From fa202a0405acd72ea778c659bfc7ac317298b696 Mon Sep 17 00:00:00 2001 From: hotyue <52734432+hotyue@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:24:50 +0000 Subject: [PATCH] =?UTF-8?q?fix(core):=20[v3.5.2]=20=E9=87=87=E7=94=A8=20Ba?= =?UTF-8?q?se64=20=E7=BC=96=E7=A0=81=E5=BD=BB=E5=BA=95=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=88=AB=E5=90=8D=E5=90=8C=E6=AD=A5=E9=93=BE=E8=B7=AF=EF=BC=8C?= =?UTF-8?q?=E5=85=8D=E7=96=AB=20WAF=20=E6=8B=A6=E6=88=AA=E4=B8=8E=E4=B8=AD?= =?UTF-8?q?=E8=8B=B1=E6=96=87=E7=AC=A6=E5=8F=B7=E8=A7=A3=E6=9E=90=E5=B4=A9?= =?UTF-8?q?=E6=BA=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/agent_daemon.sh | 120 ++++++++++++++++++++++++------------------- master/tg_master.sh | 11 ++-- 2 files changed, 72 insertions(+), 59 deletions(-) diff --git a/core/agent_daemon.sh b/core/agent_daemon.sh index 7f6a934..d096ad6 100755 --- a/core/agent_daemon.sh +++ b/core/agent_daemon.sh @@ -232,69 +232,81 @@ class AgentHandler(http.server.BaseHTTPRequestHandler): except Exception as e: print(f"Log transmission failed: {e}") - # 路由 5: 节点重命名展示别名同步接口 (v3.5.2 核心 - 综合防雷加固版) + # 路由 5: 节点重命名展示别名同步接口 (Base64 终极防御版) elif req_path == '/trigger_rename': - raw_alias = query.get('alias', [''])[0] - if raw_alias: - import re - # 🛡️ 综合避雷防御机制: - # 1. 自动将下划线(_)替换为中划线(-),防止 TG Markdown 渲染崩溃 - decoded_alias = urllib.parse.unquote(raw_alias).replace('_', '-') - # 2. 剔除 \w 中的下划线,严格限制仅允许中英文、数字、中划线,最大20字符 + b64_alias = query.get('b64', [''])[0] + if not b64_alias: + self.send_response(400) + self.end_headers() + self.wfile.write(b"400 Bad Request: Alias is empty\n") + return + + import re + import base64 + try: + # 1. 还原 URL 安全的 Base64 字符并解码 (杜绝乱码与 WAF 拦截) + pad = len(b64_alias) % 4 + if pad > 0: + b64_alias += '=' * (4 - pad) + b64_alias = b64_alias.replace('-', '+').replace('_', '/') + raw_alias = base64.b64decode(b64_alias).decode('utf-8', errors='ignore') + + # 2. 强清洗:杜绝 TG Markdown 崩溃,严格限制中英数,最大20字符 + decoded_alias = raw_alias.replace('_', '-') safe_alias = re.sub(r'[^a-zA-Z0-9\-\u4e00-\u9fa5]', '', decoded_alias)[:20] if safe_alias: - try: - # 3. 强制指定 UTF-8 纯文件流修改,彻底阻断中文编码崩溃与 Shell 注入 - config_path = '/opt/ip_sentinel/config.conf' - with open(config_path, 'r', encoding='utf-8') as f: - lines = f.readlines() + # 3. 强容错读写 config.conf + config_path = '/opt/ip_sentinel/config.conf' + with open(config_path, 'r', encoding='utf-8', errors='ignore') as f: + lines = f.readlines() + + alias_found = False + config_dict = {} + for i, line in enumerate(lines): + if line.startswith('NODE_ALIAS='): + lines[i] = f'NODE_ALIAS="{safe_alias}"\n' + alias_found = True + elif '=' in line and not line.startswith('#'): + key, val = line.strip().split('=', 1) + config_dict[key] = val.strip('"\'') + + if not alias_found: + lines.append(f'NODE_ALIAS="{safe_alias}"\n') - alias_found = False - config_dict = {} - for i, line in enumerate(lines): - if line.startswith('NODE_ALIAS='): - lines[i] = f'NODE_ALIAS="{safe_alias}"\n' - alias_found = True - elif '=' in line and not line.startswith('#'): - key, val = line.strip().split('=', 1) - config_dict[key] = val.strip('"\'') + with open(config_path, 'w', encoding='utf-8') as f: + f.writelines(lines) - if not alias_found: - lines.append(f'NODE_ALIAS="{safe_alias}"\n') - - with open(config_path, 'w', encoding='utf-8') as f: - f.writelines(lines) - - # 4. 数据闭环: 弃用脆弱的 urllib,通过系统 curl 异步发包绕过 WAF 拦截 - region = config_dict.get('REGION_CODE', 'UNKNOWN') - node_name = config_dict.get('NODE_NAME', 'UNKNOWN') - agent_ip = config_dict.get('PUBLIC_IP', '127.0.0.1') - agent_port = config_dict.get('AGENT_PORT', '9527') - chat_id = config_dict.get('CHAT_ID', '') - tg_url = config_dict.get('TG_API_URL', '') - - if tg_url and chat_id: - reg_msg = f"#REGISTER#|{region}|{node_name}|{agent_ip}|{agent_port}|{safe_alias}" - subprocess.Popen([ - 'curl', '-s', '-m', '10', '-X', 'POST', tg_url, - '-d', f'chat_id={chat_id}', - '-d', f'text={reg_msg}' - ]) - - # 立刻响应主控,防止网络阻塞导致 Master 等待超时 - self.send_response(200) - self.send_header("Content-type", "text/plain") - self.end_headers() - self.wfile.write(b"Action Accepted: trigger_rename\n") - return - except Exception as e: - print(f"Rename failed: {e}") + # 4. 绕过 WAF:交由系统底层 curl 异步发包 + region = config_dict.get('REGION_CODE', 'UNKNOWN') + node_name = config_dict.get('NODE_NAME', 'UNKNOWN') + agent_ip = config_dict.get('PUBLIC_IP', '127.0.0.1') + agent_port = config_dict.get('AGENT_PORT', '9527') + chat_id = config_dict.get('CHAT_ID', '') + tg_url = config_dict.get('TG_API_URL', '') + + if tg_url and chat_id: + reg_msg = f"#REGISTER#|{region}|{node_name}|{agent_ip}|{agent_port}|{safe_alias}" + subprocess.Popen([ + 'curl', '-s', '-m', '10', '-X', 'POST', tg_url, + '-d', f'chat_id={chat_id}', + '-d', f'text={reg_msg}' + ]) + + self.send_response(200) + self.send_header("Content-type", "text/plain") + self.end_headers() + self.wfile.write(b"Action Accepted: trigger_rename\n") + return + except Exception as e: + self.send_response(500) + self.end_headers() + self.wfile.write(f"500 Internal Error: {str(e)}\n".encode('utf-8')) + return - # 如果触发任何异常拦截,退回 400 状态码 self.send_response(400) self.end_headers() - self.wfile.write(b"400 Bad Request: Invalid Alias\n") + self.wfile.write(b"400 Bad Request: Invalid Characters\n") else: self.send_response(404) diff --git a/master/tg_master.sh b/master/tg_master.sh index 13343e9..f8f3a3c 100755 --- a/master/tg_master.sh +++ b/master/tg_master.sh @@ -334,11 +334,11 @@ while true; do if [ -n "$AGENT_IP" ] && [ -n "$AGENT_PORT" ]; then send_msg "$CHAT_ID" "⏳ 正在向 \`$TARGET_NODE\` 下发重命名指令,正在建立加密隧道..." - # 安全 URL 编码,防止中文在 URL 传输中损坏 - ENCODED_ALIAS=$(jq -rn --arg x "$NEW_ALIAS" '$x|@uri' 2>/dev/null) - TARGET_URL=$(generate_signed_url "$AGENT_IP" "$AGENT_PORT" "/trigger_rename") - TARGET_URL="${TARGET_URL}&alias=${ENCODED_ALIAS}" + + # [绝密防线: Base64 编码绕过一切传输限制与 WAF 拦截] + ALIAS_B64=$(echo -n "$NEW_ALIAS" | base64 | tr -d '\n' | tr '+/' '-_') + TARGET_URL="${TARGET_URL}&b64=${ALIAS_B64}" RESPONSE=$(curl -s -m 5 "$TARGET_URL" || echo "FAILED") @@ -347,7 +347,8 @@ while true; do elif [[ "$RESPONSE" == *"Action Accepted"* ]]; then send_msg "$CHAT_ID" "✅ 通讯成功!节点别名已下发: \`$NEW_ALIAS\`\n*(注: 节点随后将自动向中枢报备刷新面板)*" else - send_msg "$CHAT_ID" "⚠️ 节点拒绝了请求,请确保该节点的 Agent 已经更新至 v3.5.2" + # 增加输出 RESPONSE 调试信息,排查任何拦截死因 + send_msg "$CHAT_ID" "⚠️ 节点拒绝了请求,请确保 Agent 已更新至 v3.5.2\n(回传信息: \`${RESPONSE}\`)" fi else send_msg "$CHAT_ID" "❌ 数据库中未找到该节点的通讯地址。"