feat: mihomo YAML subscription support + flow/fingerprint passthrough

- fetcher: parse mihomo/clash.meta YAML subscriptions (proxies: list),
  auto-detect format (mihomo YAML vs plain vless:// lines)
- config_builder: forward VLESS flow (xtls-rprx-vision) and per-node
  uTLS fingerprint to sing-box (required for Reality+Vision nodes)
- default DNS upstream: udp://10.35.99.172 (public UDP resolvers
  unreachable on this network; old-sub nodes are hostnames)
- Dockerfile: install PyYAML

Verified: 50-node reality+vision subscription works end-to-end
(sing-box check + live SOCKS tunnel); legacy vless:// subs unaffected.
This commit is contained in:
2026-09-09 10:56:11 +03:00
parent 1beb97e367
commit 56f28099c8
6 changed files with 143 additions and 25 deletions
+9 -3
View File
@@ -56,7 +56,7 @@ def build_singbox_config(
socks_port: int = 1080,
socks_user: str = "",
socks_pass: str = "",
dns_server: str = "udp://1.1.1.1",
dns_server: str = "udp://10.35.99.172",
log_level: str = "info",
) -> Dict[str, Any]:
"""Build a complete sing-box JSON configuration.
@@ -113,13 +113,19 @@ def _build_proxy_outbound(proxy: ProxyInfo) -> Dict[str, Any]:
"packet_encoding": "xudp",
}
# Reality/Vision flow must be forwarded for xtls-rprx-vision to work
if proxy.flow:
outbound["flow"] = proxy.flow
fingerprint = proxy.fingerprint or "chrome"
security = proxy.security or "tls"
if security == "reality":
outbound["tls"] = {
"enabled": True,
"server_name": proxy.sni,
"utls": {"enabled": True, "fingerprint": "chrome"},
"utls": {"enabled": True, "fingerprint": fingerprint},
"reality": {
"enabled": True,
"public_key": proxy.pbk,
@@ -130,7 +136,7 @@ def _build_proxy_outbound(proxy: ProxyInfo) -> Dict[str, Any]:
tls_config: Dict[str, Any] = {
"enabled": True,
"server_name": proxy.sni,
"utls": {"enabled": True, "fingerprint": "chrome"},
"utls": {"enabled": True, "fingerprint": fingerprint},
}
if proxy.alpn:
tls_config["alpn"] = [a.strip() for a in proxy.alpn.split(",") if a.strip()]