mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 18:20:43 +00:00
阶段1 网络加速 - 发现隧道在跑 QUIC(ExecStart 丢了 --protocol http2), 实测 QUIC 可用率 48% vs HTTP/2 80%+,是重大性能回退。 恢复后公网延迟从 4141ms 降到 690ms(快 6 倍),可用率 92%。 - 优选 IP 结论:无效。hosts 覆盖确实生效了(日志里连的就是指定 IP), 但落点仍是 lax —— 运营商把所有 Cloudflare anycast 都路由到美西。 已清掉这段无效配置。 - BBR 不可用:设备是自定义内核 6.4.0-rc4-jsbsbxjxh66, 没编 tcp_bbr 模块也没配置项。改用 cubic + 调优: TCP 缓冲 4MB、tcp_fastopen=3、tcp_slow_start_after_idle=0 (长轮询场景关键)、tcp_tw_reuse=1。 阶段2 官网重做 - 拆出独立模块 relay/landing.py(relay.py 已两千多行, 再塞 HTML 没法看) - 信息结构参考成熟产品站:吸顶导航 / Hero / 九宫格功能 / 三步上手 / 下载 / FAQ / 页脚 - 保持白色简洁:底白、浅灰面板、细边框、大量留白 - logo 用内联 SVG(ICO 放 img 里实测是破图) - 管理入口从官网移除(管理不对外开放) 过程中被自己的测试抓到两个 bug: - 模块叫 site.py 会和 Python 标准库重名,import site 拿到的是标准库 - _logo() 里把 % 格式化和字符串拼接混用,直接抛 TypeError
112 lines
3.5 KiB
Python
112 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
||
r'''在设备上测 Cloudflare 隧道边缘 IP 的 TCP 握手延迟,挑优选 IP。
|
||
|
||
为什么要这么干:
|
||
cloudflared 连 region1.v2.argotunnel.com,这个域名由 GeoDNS 决定 ——
|
||
国内 4G 常被解析到美西(实测 lax13),单程 200ms+,
|
||
往返加丢包重传能到 4 秒(用户实测 4141ms)。
|
||
|
||
Cloudflare 是 anycast,同一批 IP 从不同网络过去落点不同。
|
||
做法:测各候选 IP 的 7844(隧道端口)握手延迟,
|
||
把最快的写进 /etc/hosts 覆盖 GeoDNS。
|
||
|
||
⚠ 关键教训:
|
||
7844 **只对 Cloudflare 的隧道专用段开放**,不是所有 anycast IP 都行。
|
||
专用段是 198.41.192.0/24 和 198.41.200.0/24(实测 198.41.192.107 通)。
|
||
我第一次拿 104.16.x.x 测,56 个全不通,就是选错段了。
|
||
'''
|
||
from __future__ import annotations
|
||
|
||
import socket
|
||
import sys
|
||
import time
|
||
|
||
PORT = 7844 # cloudflared 的 HTTP/2 隧道端口
|
||
|
||
# 已知能用的几个放前面:先确认能通,再放大范围扫
|
||
KNOWN = [
|
||
"198.41.192.107", "198.41.192.7", "198.41.192.167",
|
||
"198.41.200.13", "198.41.200.33", "198.41.200.53", "198.41.200.63",
|
||
]
|
||
|
||
|
||
def build_candidates() -> list[str]:
|
||
ips = list(KNOWN)
|
||
for third in range(1, 255, 3):
|
||
ips.append("198.41.192." + str(third))
|
||
for third in range(1, 255, 3):
|
||
ips.append("198.41.200." + str(third))
|
||
seen = set()
|
||
out = []
|
||
for ip in ips:
|
||
if ip not in seen:
|
||
seen.add(ip)
|
||
out.append(ip)
|
||
return out
|
||
|
||
|
||
def probe(ip: str, timeout: float = 2.5):
|
||
"""返回 TCP 握手耗时(毫秒),不通返回 None。"""
|
||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
sock.settimeout(timeout)
|
||
start = time.perf_counter()
|
||
try:
|
||
sock.connect((ip, PORT))
|
||
return (time.perf_counter() - start) * 1000
|
||
except OSError:
|
||
return None
|
||
finally:
|
||
sock.close()
|
||
|
||
|
||
def main() -> int:
|
||
candidates = build_candidates()
|
||
print(" 候选 %d 个(Cloudflare 隧道专用段)" % len(candidates))
|
||
print(" 测 %d 端口,每个 2 次取最快" % PORT)
|
||
print()
|
||
|
||
results = []
|
||
reachable = 0
|
||
for index, ip in enumerate(candidates, 1):
|
||
best = None
|
||
for _ in range(2):
|
||
ms = probe(ip)
|
||
if ms is not None and (best is None or ms < best):
|
||
best = ms
|
||
if best is not None:
|
||
reachable += 1
|
||
results.append((best, ip))
|
||
if index % 40 == 0:
|
||
print(" 已测 %d/%d,通了 %d 个" % (index, len(candidates), reachable))
|
||
|
||
print()
|
||
if not results:
|
||
print(" 一个都不通")
|
||
return 1
|
||
|
||
results.sort()
|
||
print(" 通了 %d 个,最快的 15 个:" % reachable)
|
||
for ms, ip in results[:15]:
|
||
print(" %7.1f ms %s" % (ms, ip))
|
||
|
||
print()
|
||
print(" 默认 GeoDNS 解析:")
|
||
for host in ("region1.v2.argotunnel.com", "region2.v2.argotunnel.com"):
|
||
try:
|
||
infos = socket.getaddrinfo(host, PORT)
|
||
v4 = sorted({i[4][0] for i in infos if i[0] == socket.AF_INET})
|
||
print(" %s: %s" % (host, v4 or "(只有 IPv6)"))
|
||
except OSError as exc:
|
||
print(" %s: 解析失败 %s" % (host, exc))
|
||
|
||
with open("/root/cf_best.txt", "w") as fh:
|
||
for ms, ip in results[:5]:
|
||
fh.write("%s %.0f\n" % (ip, ms))
|
||
print()
|
||
print(" 最快 5 个 -> /root/cf_best.txt")
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|