Commit 1991b84d authored by Vitaly Lipatov's avatar Vitaly Lipatov

web-api: refactor gateway checks — remove direct, add IPv6 proxies, sort sidebar

- Remove "direct" gateway, use socks5:// proxies for all checks - Add IPv6 proxy addresses for dual-stack gateway checking - beget nodes have no IPv6 (proxy_v6=None), correctly shown as NOIP - Add egw/dgw/igw to sidebar under Маршрутизаторы section - Sort all sidebar items alphabetically within sections Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 4c1b8a80
......@@ -46,15 +46,15 @@ MAX_ENTRIES = 500
UPDATE_INTERVAL = 300 # route-update.sh cycle, seconds
CHECK_GATEWAYS = [
("direct", None), # direct from igw, uses policy routing
("dgw", "socks5h://91.232.225.12:1080"),
("igw", "socks5h://91.232.225.13:1080"),
("warp", "socks5h://91.232.225.134:1080"),
("gre.hetzner", "socks5h://91.232.225.122:1080"),
("ikev2.hetzner", "socks5h://91.232.225.120:1080"),
("gre.vdska", "socks5h://91.232.225.127:1080"),
("gre.beget.ogw", "socks5h://91.232.225.124:1080"),
("ikev2.beget.ogw", "socks5h://91.232.225.130:1080"),
# (name, proxy_v4, proxy_v6)
("dgw", "socks5://91.232.225.12:1080", "socks5://[2a03:5a00:c:20::12]:1080"),
("igw", "socks5://91.232.225.13:1080", "socks5://[2a03:5a00:c:20::13]:1080"),
("warp", "socks5://91.232.225.134:1080", "socks5://[2a03:5a00:c:20::134]:1080"),
("gre.hetzner", "socks5://91.232.225.122:1080", "socks5://[2a03:5a00:c:20::122]:1080"),
("ikev2.hetzner", "socks5://91.232.225.120:1080", "socks5://[2a03:5a00:c:20::120]:1080"),
("gre.vdska", "socks5://91.232.225.127:1080", "socks5://[2a03:5a00:c:20::127]:1080"),
("gre.beget.ogw", "socks5://91.232.225.124:1080", None),
("ikev2.beget.ogw", "socks5://91.232.225.130:1080", None),
]
CHECK_TIMEOUT = 10
......@@ -291,10 +291,10 @@ def check_site(domain):
workers = len(CHECK_GATEWAYS) * 2 + 2
with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as pool:
gw_futures = []
for name, proxy in CHECK_GATEWAYS:
gw_futures.append(pool.submit(_check_one, name, proxy, url, "-4"))
if has_v6:
gw_futures.append(pool.submit(_check_one, name, proxy, url, "-6"))
for name, proxy_v4, proxy_v6 in CHECK_GATEWAYS:
gw_futures.append(pool.submit(_check_one, name, proxy_v4, url, "-4"))
if has_v6 and proxy_v6:
gw_futures.append(pool.submit(_check_one, name, proxy_v6, url, "-6"))
whois_future = pool.submit(get_whois, domain)
# Fetch HTML and parse assets via first available gateway
assets_future = pool.submit(_find_assets, CHECK_GATEWAYS[0][1], url)
......@@ -310,11 +310,11 @@ def check_site(domain):
checks[name]["status_v6"] = status
checks[name]["http_code_v6"] = code
# Fill NOIP for gateways when domain has no AAAA
if not has_v6:
for name, _proxy in CHECK_GATEWAYS:
# Fill NOIP for gateways without IPv6 result
for name, _pv4, _pv6 in CHECK_GATEWAYS:
if name not in checks:
checks[name] = {}
if "status_v6" not in checks[name]:
checks[name]["status_v6"] = "NOIP"
checks[name]["http_code_v6"] = 0
......@@ -328,7 +328,7 @@ def check_site(domain):
with concurrent.futures.ThreadPoolExecutor(max_workers=len(CHECK_GATEWAYS)) as pool:
throttle_futures = [
pool.submit(_check_throttle, name, proxy, asset_url)
for name, proxy in CHECK_GATEWAYS
for name, proxy, _pv6 in CHECK_GATEWAYS
]
for future in concurrent.futures.as_completed(throttle_futures):
gw_name, result = future.result()
......@@ -741,30 +741,36 @@ HTML_PAGE = """\
<aside class="sidebar">
<div class="sidebar-section">
<h3>egw (через VDS)</h3>
<div class="sidebar-item" title="OpenConnect VPN">openconnect.hetzner <span class="ip">.112</span></div>
<div class="sidebar-item" title="Cloak + OpenVPN">cloak.ovpn.sprintbox <span class="ip">.113</span></div>
<div class="sidebar-item" title="AmneziaWG">amneziawg.sprintbox <span class="ip">.114</span></div>
<div class="sidebar-item" title="IKEv2 IPsec">ikev2.sprintbox <span class="ip">.115</span></div>
<div class="sidebar-item" title="AmneziaWG">amneziawg.hetzner <span class="ip">.116</span></div>
<div class="sidebar-item" title="Xray/VLESS">xray.sprintbox <span class="ip">.117</span></div>
<div class="sidebar-item" title="OpenVPN">ovpn.hetzner <span class="ip">.118</span></div>
<div class="sidebar-item" title="OpenVPN">ovpn.sprintbox <span class="ip">.119</span></div>
<div class="sidebar-item" title="IKEv2 IPsec">ikev2.hetzner <span class="ip">.120</span></div>
<div class="sidebar-item" title="AmneziaWG">amneziawg.sprintbox <span class="ip">.114</span></div>
<div class="sidebar-item" title="Cloak + OpenVPN">cloak.ovpn.hetzner <span class="ip">.132</span></div>
<div class="sidebar-item" title="Cloak + OpenVPN">cloak.ovpn.sprintbox <span class="ip">.113</span></div>
<div class="sidebar-item" title="GRE tunnel">gre.hetzner <span class="ip">.122</span></div>
<div class="sidebar-item" title="GRE tunnel">gre.sprintbox <span class="ip">.123</span></div>
<div class="sidebar-item" title="Xray/VLESS">xray.hetzner <span class="ip">.125</span></div>
<div class="sidebar-item" title="GRE tunnel">gre.vdska <span class="ip">.127</span></div>
<div class="sidebar-item" title="OpenVPN">ovpn.vdska <span class="ip">.128</span></div>
<div class="sidebar-item" title="IKEv2 IPsec">ikev2.hetzner <span class="ip">.120</span></div>
<div class="sidebar-item" title="IKEv2 IPsec">ikev2.sprintbox <span class="ip">.115</span></div>
<div class="sidebar-item" title="IKEv2 IPsec">ikev2.vdska <span class="ip">.131</span></div>
<div class="sidebar-item" title="Cloak + OpenVPN">cloak.ovpn.hetzner <span class="ip">.132</span></div>
<div class="sidebar-item" title="OpenConnect VPN">openconnect.hetzner <span class="ip">.112</span></div>
<div class="sidebar-item" title="OpenVPN">ovpn.hetzner <span class="ip">.118</span></div>
<div class="sidebar-item" title="OpenVPN">ovpn.sprintbox <span class="ip">.119</span></div>
<div class="sidebar-item" title="OpenVPN">ovpn.vdska <span class="ip">.128</span></div>
<div class="sidebar-item" title="Cloudflare WARP">warp <span class="ip">.134</span></div>
<div class="sidebar-item" title="Xray/VLESS">xray.hetzner <span class="ip">.125</span></div>
<div class="sidebar-item" title="Xray/VLESS">xray.sprintbox <span class="ip">.117</span></div>
</div>
<div class="sidebar-section">
<h3>ogw (без VDS)</h3>
<div class="sidebar-item" title="GRE tunnel">gre.beget <span class="ip">.124</span></div>
<div class="sidebar-item" title="nfqws DPI bypass">nfqws <span class="ip">.126</span></div>
<div class="sidebar-item" title="ByeDPI bypass">bydpi <span class="ip">.129</span></div>
<div class="sidebar-item" title="GRE tunnel">gre.beget <span class="ip">.124</span></div>
<div class="sidebar-item" title="IKEv2 IPsec">ikev2.beget <span class="ip">.130</span></div>
<div class="sidebar-item" title="nfqws DPI bypass">nfqws <span class="ip">.126</span></div>
</div>
<div class="sidebar-section">
<h3>Маршрутизаторы</h3>
<div class="sidebar-item" title="Прямой шлюз">dgw <span class="ip">.12</span></div>
<div class="sidebar-item" title="Шлюз-распределитель">egw <span class="ip">.14</span></div>
<div class="sidebar-item" title="Основной шлюз">igw <span class="ip">.13</span></div>
</div>
<div class="sidebar-note">SOCKS5 :1080 на всех</div>
<div class="sidebar-section" id="health-section" style="display:none">
......@@ -1018,7 +1024,7 @@ function renderCheck(data) {
const gsec = mkDiv('check-section');
gsec.appendChild(mkDiv('check-section-title', '\\u0414\\u043e\\u0441\\u0442\\u0443\\u043f\\u043d\\u043e\\u0441\\u0442\\u044c \\u0447\\u0435\\u0440\\u0435\\u0437 \\u0448\\u043b\\u044e\\u0437\\u044b'));
const gwrap = document.createElement('div');
const order = ['direct', 'dgw', 'igw', 'warp', 'gre.hetzner', 'ikev2.hetzner', 'gre.vdska', 'gre.beget.ogw', 'ikev2.beget.ogw'];
const order = ['dgw', 'igw', 'warp', 'gre.hetzner', 'ikev2.hetzner', 'gre.vdska', 'gre.beget.ogw', 'ikev2.beget.ogw'];
for (const name of order) {
const info = data.checks[name];
if (!info) continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment