auth: HTTPS с self-signed сертификатами + расширенный дефолт ROUTER_HOST

- urllib теперь идёт на HTTPS с unverified context (Keenetic админка
  обычно с самоподписанным сертификатом)
- .env по умолчанию содержит и HTTP, и HTTPS, и :81 для LAN-IP, плюс
  my.keenetic.net и loopback — пробуется всё подряд
This commit is contained in:
Андрей Бобырев
2026-04-26 10:47:55 +03:00
parent d8ee078ef5
commit 7c2adf95b9
3 changed files with 14 additions and 4 deletions

View File

@@ -3,7 +3,7 @@
# Можно перечислить через запятую — будет пробовать по порядку, пока кто-то не примет. # Можно перечислить через запятую — будет пробовать по порядку, пока кто-то не примет.
# Установщик сам подставит LAN-IP роутера, если запущен на нём. # Установщик сам подставит LAN-IP роутера, если запущен на нём.
# Часто loopback закрыт админкой Keenetic — основной кандидат это LAN-IP. # Часто loopback закрыт админкой Keenetic — основной кандидат это LAN-IP.
ROUTER_HOST=http://192.168.1.1,http://my.keenetic.net,http://127.0.0.1 ROUTER_HOST=http://192.168.1.1,https://192.168.1.1,http://192.168.1.1:81,http://my.keenetic.net,https://my.keenetic.net,http://127.0.0.1
# Логин по умолчанию в форме входа (можно изменить руками при логине) # Логин по умолчанию в форме входа (можно изменить руками при логине)
ROUTER_LOGIN=admin ROUTER_LOGIN=admin

11
auth.py
View File

@@ -14,6 +14,7 @@ import http.cookiejar
import json import json
import logging import logging
import secrets import secrets
import ssl
import threading import threading
import time import time
import urllib.error import urllib.error
@@ -21,6 +22,11 @@ import urllib.request
log = logging.getLogger("kssh.auth") log = logging.getLogger("kssh.auth")
# У Keenetic админка на HTTPS обычно с самоподписанным сертификатом — отключаем проверку.
_SSL_CTX = ssl.create_default_context()
_SSL_CTX.check_hostname = False
_SSL_CTX.verify_mode = ssl.CERT_NONE
def _normalize_host(host: str) -> str: def _normalize_host(host: str) -> str:
h = (host or "").strip().rstrip("/") h = (host or "").strip().rstrip("/")
@@ -41,7 +47,10 @@ def keenetic_validate(host: str, login: str, password: str, timeout: float = 5.0
if not base or not login or password is None: if not base or not login or password is None:
return False return False
cj = http.cookiejar.CookieJar() cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) opener = urllib.request.build_opener(
urllib.request.HTTPCookieProcessor(cj),
urllib.request.HTTPSHandler(context=_SSL_CTX),
)
realm = "" realm = ""
challenge = "" challenge = ""
try: try:

View File

@@ -27,8 +27,9 @@ if [ ! -f "$INST/.env" ]; then
| awk '$4 ~ /^(192\.168|10|172\.(1[6-9]|2[0-9]|3[01]))\..*\.1\// {sub("/.*","",$4); print $4; exit}' | awk '$4 ~ /^(192\.168|10|172\.(1[6-9]|2[0-9]|3[01]))\..*\.1\// {sub("/.*","",$4); print $4; exit}'
)" )"
if [ -n "$LAN_IP_GUESS" ]; then if [ -n "$LAN_IP_GUESS" ]; then
sed -i "s|^ROUTER_HOST=.*|ROUTER_HOST=http://${LAN_IP_GUESS},http://my.keenetic.net,http://127.0.0.1|" "$INST/.env" 2>/dev/null || true DEFAULT_HOSTS="http://${LAN_IP_GUESS},https://${LAN_IP_GUESS},http://${LAN_IP_GUESS}:81,http://my.keenetic.net,https://my.keenetic.net,http://127.0.0.1"
echo "==> .env: ROUTER_HOST подставлен LAN-IP $LAN_IP_GUESS (можно изменить в $INST/.env)" sed -i "s|^ROUTER_HOST=.*|ROUTER_HOST=${DEFAULT_HOSTS}|" "$INST/.env" 2>/dev/null || true
echo "==> .env: ROUTER_HOST подставлен LAN-IP $LAN_IP_GUESS (HTTP/HTTPS, можно изменить в $INST/.env)"
fi fi
echo "!!! Создан $INST/.env — при необходимости задайте WEB_PASSWORD/ALLOWED_IPS" echo "!!! Создан $INST/.env — при необходимости задайте WEB_PASSWORD/ALLOWED_IPS"
fi fi