mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 21:50:44 +00:00
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞 - 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀? 鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException - 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴? 鏈嶅姟鍣ㄧ - 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級 - 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯 - 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺? 鏂囨。 - 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
144 lines
5.8 KiB
Python
144 lines
5.8 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""三个修复:
|
||
|
||
1. 【关键】被控端发请求要带 User-Agent
|
||
Cloudflare 的 Browser Integrity Check 把 Python 默认 UA
|
||
(Python-urllib/3.11)当成可疑客户端,返回 403 + error code 1010。
|
||
实测 LanRemote/1.4.0 能过。
|
||
不修的话:固定域名上线后,被控端根本连不上。
|
||
(手表端 Java 已经带了 LanRemote-Watch/1.4,没问题)
|
||
|
||
2. setup_named_tunnel.sh 写的 public_url.txt 少了 https://
|
||
导致 /url 接口和 status 显示"还没有地址"。
|
||
|
||
3. install.sh 里钉的 Cloudflare API IP 是错的
|
||
我之前猜的 104.16.132.229 返回的是错误页(error code 1034),
|
||
不是 API。真实地址要用公共 DNS 查(104.19.192.174 等)。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
|
||
RELAY = ROOT / "windows" / "lanremote" / "relay.py"
|
||
SETUP = ROOT / "_build" / "setup_named_tunnel.sh"
|
||
INSTALL = ROOT / "relay" / "install.sh"
|
||
|
||
# ---------------- 1. relay.py 加 UA ----------------
|
||
|
||
UA_CONST_ANCHOR = '''# 私有网段 + 回环 + mDNS 名字'''
|
||
|
||
UA_CONST = '''# 请求头。**必须带 User-Agent**:
|
||
# Cloudflare 的 Browser Integrity Check 会把 Python 默认 UA
|
||
# (Python-urllib/3.11)判为可疑客户端,返回 403 + error code 1010。
|
||
# 实测 LanRemote/1.4.0 能过,用自家标识比伪装浏览器合适。
|
||
USER_AGENT = "LanRemote/1.4.0"
|
||
|
||
|
||
# 私有网段 + 回环 + mDNS 名字'''
|
||
|
||
UA_PROBE_OLD = ''' request = urllib.request.Request(base + "/v1/health")'''
|
||
UA_PROBE_NEW = ''' request = urllib.request.Request(
|
||
base + "/v1/health", headers={"User-Agent": USER_AGENT})'''
|
||
|
||
# ---------------- 2. setup_named_tunnel.sh 补 https:// ----------------
|
||
|
||
SETUP_OLD = '''echo "$HOSTNAME_FULL" > "$RELAY_DIR/public_url.txt"'''
|
||
SETUP_NEW = '''# 一定要带 https:// —— public_url() 只认以 http 开头的,
|
||
# 少了协议头 /url 接口会显示"还没有地址"。
|
||
echo "https://$HOSTNAME_FULL" > "$RELAY_DIR/public_url.txt"'''
|
||
|
||
# ---------------- 3. install.sh 换真实 IP ----------------
|
||
|
||
INSTALL_OLD = ''' echo "104.16.132.229 api.cloudflare.com"
|
||
echo "104.16.133.229 api.cloudflare.com"'''
|
||
INSTALL_NEW = ''' # 这几个是用公共 DNS(1.1.1.1 / 8.8.8.8 / 223.5.5.5)查出来的
|
||
# 真实地址。之前随手挑的 104.16.132.229 是错的 ——
|
||
# 它返回 Cloudflare 错误页(error code: 1034)而不是 API,
|
||
# 会导致 cloudflared tunnel create 报 unauthorized。
|
||
echo "104.19.192.174 api.cloudflare.com"
|
||
echo "104.19.192.175 api.cloudflare.com"
|
||
echo "104.19.192.176 api.cloudflare.com"
|
||
echo "104.19.192.177 api.cloudflare.com"
|
||
echo "104.17.0.1 api.cloudflare.com"
|
||
echo "104.18.0.1 api.cloudflare.com"'''
|
||
|
||
# 检查逻辑也要跟着改:现在该看响应是不是 API JSON,不是只看状态码
|
||
INSTALL_CHECK_OLD = '''if is_real_cf "$CF_IP" && { [ "$CF_CODE" = "403" ] || [ "$CF_CODE" = "200" ]; }; then
|
||
echo " ✓ 正常(没被劫持)"'''
|
||
INSTALL_CHECK_NEW = '''CF_BODY=$(timeout 12 curl -4 -s https://api.cloudflare.com/client/v4/user 2>/dev/null | head -c 200)
|
||
if is_real_cf "$CF_IP" && echo "$CF_BODY" | grep -q '"success"'; then
|
||
echo " ✓ 正常(返回的是真正的 API JSON)"'''
|
||
INSTALL_CHECK2_OLD = ''' if [ "$CF_CODE2" = "403" ] || [ "$CF_CODE2" = "200" ]; then
|
||
echo " ✓ 修好了"'''
|
||
INSTALL_CHECK2_NEW = ''' CF_BODY2=$(timeout 12 curl -4 -s https://api.cloudflare.com/client/v4/user 2>/dev/null | head -c 200)
|
||
if echo "$CF_BODY2" | grep -q '"success"'; then
|
||
echo " ✓ 修好了(返回的是真正的 API JSON)"'''
|
||
|
||
|
||
def patch(path: Path, pairs, label: str) -> bool:
|
||
text = path.read_text(encoding="utf-8")
|
||
ok = True
|
||
for old, new, tag in pairs:
|
||
if old not in text:
|
||
print(f" [{label}] [跳过] {tag} —— 锚点没找到")
|
||
ok = False
|
||
continue
|
||
text = text.replace(old, new, 1)
|
||
print(f" [{label}] {tag}")
|
||
path.write_text(text, encoding="utf-8", newline="\n")
|
||
raw = path.read_bytes()
|
||
if b"\r\n" in raw and path.suffix == ".sh":
|
||
path.write_bytes(raw.replace(b"\r\n", b"\n"))
|
||
print(f" [{label}] 顺手修了 CRLF")
|
||
return ok
|
||
|
||
|
||
def main() -> int:
|
||
ok = True
|
||
|
||
ok &= patch(RELAY, [
|
||
(UA_CONST_ANCHOR, UA_CONST, "加 USER_AGENT 常量"),
|
||
(UA_PROBE_OLD, UA_PROBE_NEW, "_probe 带 UA"),
|
||
], "relay.py")
|
||
|
||
# _post 那处:把 headers 里补上 UA
|
||
text = RELAY.read_text(encoding="utf-8")
|
||
post_old = ''' request = urllib.request.Request(self.url + path, data=body,'''
|
||
if post_old in text:
|
||
# 找 _post 里构造 headers 的地方,统一并入 UA
|
||
text = text.replace(
|
||
post_old,
|
||
''' headers = dict(headers or {})
|
||
headers.setdefault("User-Agent", USER_AGENT)
|
||
request = urllib.request.Request(self.url + path, data=body,''',
|
||
1)
|
||
RELAY.write_text(text, encoding="utf-8", newline="\n")
|
||
print(" [relay.py] _post 带 UA")
|
||
else:
|
||
print(" [relay.py] [跳过] _post 锚点没找到")
|
||
|
||
ok &= patch(SETUP, [(SETUP_OLD, SETUP_NEW, "public_url.txt 补 https://")],
|
||
"setup_named_tunnel.sh")
|
||
|
||
ok &= patch(INSTALL, [
|
||
(INSTALL_OLD, INSTALL_NEW, "换成真实 IP"),
|
||
(INSTALL_CHECK_OLD, INSTALL_CHECK_NEW, "判断改成看 JSON"),
|
||
(INSTALL_CHECK2_OLD, INSTALL_CHECK2_NEW, "第二处判断"),
|
||
], "install.sh")
|
||
|
||
import ast
|
||
try:
|
||
ast.parse(RELAY.read_text(encoding="utf-8"))
|
||
print(" relay.py 语法 OK")
|
||
except SyntaxError as exc:
|
||
print(f" relay.py 语法错误: {exc}")
|
||
ok = False
|
||
|
||
return 0 if ok else 1
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|