-
-
Save ancientGlider/e72cdaa2daf0af5f8d80f53fea4666be to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*- | |
""" | |
Данные с адресом, логином, паролем хранятся в конфигурационном файле следующего вида: | |
[Router] | |
ip_addr = 192.168.1.1:8080 | |
login = admin | |
passw = anyPassword | |
""" | |
CONFIG_FILE_NAME = "keenetic.conf" # имя конфигурационного файла | |
import configparser | |
import requests | |
import hashlib | |
cookies_current = None | |
session = requests.session() # заводим сессию глобально чтобы отрабатывались куки | |
def keen_auth(login, passw): # авторизация на роутере | |
response = keen_request(ip_addr, "auth") | |
if response.status_code == 401: | |
md5 = login + ":" + response.headers["X-NDM-Realm"] + ":" + passw | |
md5 = hashlib.md5(md5.encode('utf-8')) | |
sha = response.headers["X-NDM-Challenge"] + md5.hexdigest() | |
sha = hashlib.sha256(sha.encode('utf-8')) | |
response = keen_request(ip_addr, "auth", {"login": login, "password": sha.hexdigest()}) | |
if response.status_code == 200: | |
return True | |
elif response.status_code == 200: | |
return True | |
else: | |
return False | |
def keen_request(ip_addr, query, post = None): # отправка запросов на роутер | |
global session | |
# конструируем url | |
url = "http://" + ip_addr + "/" + query | |
# если есть данные для запроса POST, делаем POST, иначе GET | |
if post: | |
return session.post(url, json=post) | |
else: | |
return session.get(url) | |
config = configparser.ConfigParser() # создаём объекта парсера | |
config.read(CONFIG_FILE_NAME) # читаем конфиг | |
ip_addr = config["Router"]["ip_addr"] | |
login = config["Router"]["login"] | |
passw = config["Router"]["passw"] | |
# тестируем | |
if keen_auth(login, passw): | |
response = keen_request(ip_addr, 'rci/show/interface/WifiMaster0'); | |
print(response.text) |
Переписал тоже самое на PHP
<?php
class KeeneticAPI
{
private string $ip_addr;
private string $login;
private string $passw;
private CurlHandle $session;
private string $cookieJar;
public function __construct(string $ip_addr, string $login, string $passw)
{
$this->ip_addr = $ip_addr;
$this->login = $login;
$this->passw = $passw;
// Инициализация cURL сессии и файла для хранения cookie
$this->cookieJar = tempnam(sys_get_temp_dir(), 'cookies_');
$this->session = curl_init();
$this->auth();
}
public function __destruct()
{
// Закрытие cURL сессии и удаление файла cookie
curl_close($this->session);
if (file_exists($this->cookieJar)) {
unlink($this->cookieJar);
}
}
private function auth()
{
$response = $this->request("auth");
if ($response['status_code'] == 401) {
// Извлечение заголовков
$headers = [];
foreach (explode("\r\n", $response['headers']) as $header_line) {
$parts = explode(": ", $header_line, 2);
if (count($parts) == 2) {
$headers[$parts[0]] = $parts[1];
}
}
$ndm_realm = isset($headers['X-NDM-Realm']) ? $headers['X-NDM-Realm'] : '';
$ndm_challenge = isset($headers['X-NDM-Challenge']) ? $headers['X-NDM-Challenge'] : '';
// Вычисление хешей
$md5_input = $this->login . ':' . $ndm_realm . ':' . $this->passw;
$md5_hash = md5($md5_input);
$sha_input = $ndm_challenge . $md5_hash;
$sha_hash = hash('sha256', $sha_input);
$postData = ["login" => $this->login, "password" => $sha_hash];
$response = $this->request("auth", $postData);
if ($response['status_code'] == 200) {
return true;
}
} elseif ($response['status_code'] == 200) {
return true;
}
return false;
}
public function request($query, $post = null)
{
$url = "http://" . $this->ip_addr . "/" . $query;
curl_setopt($this->session, CURLOPT_URL, $url);
curl_setopt($this->session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->session, CURLOPT_HEADER, true);
curl_setopt($this->session, CURLOPT_COOKIEFILE, $this->cookieJar);
curl_setopt($this->session, CURLOPT_COOKIEJAR, $this->cookieJar);
if ($post !== null) {
$jsonData = json_encode($post);
curl_setopt($this->session, CURLOPT_POST, true);
curl_setopt($this->session, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($this->session, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
} else {
curl_setopt($this->session, CURLOPT_HTTPGET, true);
curl_setopt($this->session, CURLOPT_POST, false);
curl_setopt($this->session, CURLOPT_HTTPHEADER, []);
}
$response = curl_exec($this->session);
$header_size = curl_getinfo($this->session, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$status_code = curl_getinfo($this->session, CURLINFO_HTTP_CODE);
return [
'status_code' => $status_code,
'headers' => $header,
'text' => $body,
];
}
}
Использую для того чтобы через Алису выключать\включать VPN для телевизора
<?php
require('KeeneticAPI.php');
$api = new KeeneticAPI('192.168.1.1', 'admin', '12345678');
//on
$api->request('rci/ip/hotspot/host', [
'mac'=> "11:11:11:11:11:11",
'permit'=> true,
'policy'=> "Policy0",
]);
//off
$api->request('rci/ip/hotspot/host', [
'mac'=> "11:11:11:11:11:11",
'permit'=> true,
'policy'=> [
'no' => true
]
]);
Спасибо!
@gotyefrid
А я себе статические маршруты настроил, теперь у меня Youtube идёт в VPN, а остальное напрямую..
Почему бы вам также не сделать?
Маршрутизация>Загрузить из файла > Интерфейс выбираете где у вас VPN, а файлы бирёте эти: https://github.com/RockBlack-VPN/ip-address/tree/main/Global/Youtube
И всё отлично работает.
А я себе статические маршруты настроил, теперь у меня Youtube идёт в VPN, а остальное напрямую..
Увы, домены по типу rr2---sn-oan31-5a5e.googlevideo.com
периодически меняются. Потому приходится собирать велосипеды из костылей.
pc. Хмм, надо помониторить, вдруг и правда пул ip просто переименовывают...
Переписал тоже самое на PHP
<?php class KeeneticAPI { private string $ip_addr; private string $login; private string $passw; private CurlHandle $session; private string $cookieJar; public function __construct(string $ip_addr, string $login, string $passw) { $this->ip_addr = $ip_addr; $this->login = $login; $this->passw = $passw; // Инициализация cURL сессии и файла для хранения cookie $this->cookieJar = tempnam(sys_get_temp_dir(), 'cookies_'); $this->session = curl_init(); $this->aut
Привет! Скажи куда вписывать свои данные от роутера. Спасибо
Огромное спасибо!

Приобрел
Keenetic Giga
недавно, обнаружил, что для него нетdevice_tracker
компонента дляHome Assistant
. До этого былXiaomi MiR3G
наpadavan
, использовал компонентasuswrt
. Сейчас придется писать свое.И пример аутентификации был очень кстати.