82426b1941
新增侧栏「宝塔面板」菜单、代理 API 与连接配置页;通过 SSH 读写子机 api.json 自动写入凭据,5 分钟后台重试,含审计修复、检测缓存与并发锁。 Co-authored-by: Cursor <cursoragent@cursor.com>
59 lines
1.5 KiB
Python
59 lines
1.5 KiB
Python
"""Resolve Nexus center IP for Baota API whitelist."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ipaddress
|
|
import logging
|
|
import socket
|
|
from urllib.parse import urlparse
|
|
|
|
from server.config import settings
|
|
|
|
logger = logging.getLogger("nexus.btpanel.source_ip")
|
|
|
|
|
|
def _is_ip(value: str) -> bool:
|
|
try:
|
|
ipaddress.ip_address(value.strip())
|
|
return True
|
|
except ValueError:
|
|
return False
|
|
|
|
|
|
def _host_from_url(url: str) -> str | None:
|
|
parsed = urlparse(url.strip())
|
|
host = (parsed.hostname or "").strip()
|
|
return host or None
|
|
|
|
|
|
def resolve_center_ip_from_dns(host: str) -> str | None:
|
|
if not host:
|
|
return None
|
|
if _is_ip(host):
|
|
return host
|
|
try:
|
|
infos = socket.getaddrinfo(host, None, type=socket.SOCK_STREAM)
|
|
for info in infos:
|
|
addr = info[4][0]
|
|
if _is_ip(addr):
|
|
return addr
|
|
except OSError as exc:
|
|
logger.warning("bt panel source ip dns failed host=%s: %s", host, exc)
|
|
return None
|
|
|
|
|
|
def get_bt_panel_source_ip() -> str | None:
|
|
"""Center outbound IP for Baota ``limit_addr`` (settings → API_BASE_URL DNS)."""
|
|
explicit = (getattr(settings, "BT_PANEL_SOURCE_IP", None) or "").strip()
|
|
if explicit and _is_ip(explicit):
|
|
return explicit
|
|
|
|
base = (settings.API_BASE_URL or "").strip()
|
|
host = _host_from_url(base) if base else None
|
|
if host:
|
|
resolved = resolve_center_ip_from_dns(host)
|
|
if resolved:
|
|
return resolved
|
|
|
|
return None
|