mirror of
https://github.com/hotyue/IP-Sentinel.git
synced 2026-09-05 07:28:14 +08:00
fix(core): [v3.5.2] 采用 Base64 编码彻底重构别名同步链路,免疫 WAF 拦截与中英文符号解析崩溃
This commit is contained in:
+27
-15
@@ -232,22 +232,33 @@ class AgentHandler(http.server.BaseHTTPRequestHandler):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Log transmission failed: {e}")
|
print(f"Log transmission failed: {e}")
|
||||||
|
|
||||||
# 路由 5: 节点重命名展示别名同步接口 (v3.5.2 核心 - 综合防雷加固版)
|
# 路由 5: 节点重命名展示别名同步接口 (Base64 终极防御版)
|
||||||
elif req_path == '/trigger_rename':
|
elif req_path == '/trigger_rename':
|
||||||
raw_alias = query.get('alias', [''])[0]
|
b64_alias = query.get('b64', [''])[0]
|
||||||
if raw_alias:
|
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 re
|
||||||
# 🛡️ 综合避雷防御机制:
|
import base64
|
||||||
# 1. 自动将下划线(_)替换为中划线(-),防止 TG Markdown 渲染崩溃
|
try:
|
||||||
decoded_alias = urllib.parse.unquote(raw_alias).replace('_', '-')
|
# 1. 还原 URL 安全的 Base64 字符并解码 (杜绝乱码与 WAF 拦截)
|
||||||
# 2. 剔除 \w 中的下划线,严格限制仅允许中英文、数字、中划线,最大20字符
|
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]
|
safe_alias = re.sub(r'[^a-zA-Z0-9\-\u4e00-\u9fa5]', '', decoded_alias)[:20]
|
||||||
|
|
||||||
if safe_alias:
|
if safe_alias:
|
||||||
try:
|
# 3. 强容错读写 config.conf
|
||||||
# 3. 强制指定 UTF-8 纯文件流修改,彻底阻断中文编码崩溃与 Shell 注入
|
|
||||||
config_path = '/opt/ip_sentinel/config.conf'
|
config_path = '/opt/ip_sentinel/config.conf'
|
||||||
with open(config_path, 'r', encoding='utf-8') as f:
|
with open(config_path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
|
|
||||||
alias_found = False
|
alias_found = False
|
||||||
@@ -266,7 +277,7 @@ class AgentHandler(http.server.BaseHTTPRequestHandler):
|
|||||||
with open(config_path, 'w', encoding='utf-8') as f:
|
with open(config_path, 'w', encoding='utf-8') as f:
|
||||||
f.writelines(lines)
|
f.writelines(lines)
|
||||||
|
|
||||||
# 4. 数据闭环: 弃用脆弱的 urllib,通过系统 curl 异步发包绕过 WAF 拦截
|
# 4. 绕过 WAF:交由系统底层 curl 异步发包
|
||||||
region = config_dict.get('REGION_CODE', 'UNKNOWN')
|
region = config_dict.get('REGION_CODE', 'UNKNOWN')
|
||||||
node_name = config_dict.get('NODE_NAME', 'UNKNOWN')
|
node_name = config_dict.get('NODE_NAME', 'UNKNOWN')
|
||||||
agent_ip = config_dict.get('PUBLIC_IP', '127.0.0.1')
|
agent_ip = config_dict.get('PUBLIC_IP', '127.0.0.1')
|
||||||
@@ -282,19 +293,20 @@ class AgentHandler(http.server.BaseHTTPRequestHandler):
|
|||||||
'-d', f'text={reg_msg}'
|
'-d', f'text={reg_msg}'
|
||||||
])
|
])
|
||||||
|
|
||||||
# 立刻响应主控,防止网络阻塞导致 Master 等待超时
|
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-type", "text/plain")
|
self.send_header("Content-type", "text/plain")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(b"Action Accepted: trigger_rename\n")
|
self.wfile.write(b"Action Accepted: trigger_rename\n")
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Rename failed: {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.send_response(400)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(b"400 Bad Request: Invalid Alias\n")
|
self.wfile.write(b"400 Bad Request: Invalid Characters\n")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.send_response(404)
|
self.send_response(404)
|
||||||
|
|||||||
+6
-5
@@ -334,11 +334,11 @@ while true; do
|
|||||||
if [ -n "$AGENT_IP" ] && [ -n "$AGENT_PORT" ]; then
|
if [ -n "$AGENT_IP" ] && [ -n "$AGENT_PORT" ]; then
|
||||||
send_msg "$CHAT_ID" "⏳ 正在向 \`$TARGET_NODE\` 下发重命名指令,正在建立加密隧道..."
|
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=$(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")
|
RESPONSE=$(curl -s -m 5 "$TARGET_URL" || echo "FAILED")
|
||||||
|
|
||||||
@@ -347,7 +347,8 @@ while true; do
|
|||||||
elif [[ "$RESPONSE" == *"Action Accepted"* ]]; then
|
elif [[ "$RESPONSE" == *"Action Accepted"* ]]; then
|
||||||
send_msg "$CHAT_ID" "✅ 通讯成功!节点别名已下发: \`$NEW_ALIAS\`\n*(注: 节点随后将自动向中枢报备刷新面板)*"
|
send_msg "$CHAT_ID" "✅ 通讯成功!节点别名已下发: \`$NEW_ALIAS\`\n*(注: 节点随后将自动向中枢报备刷新面板)*"
|
||||||
else
|
else
|
||||||
send_msg "$CHAT_ID" "⚠️ 节点拒绝了请求,请确保该节点的 Agent 已经更新至 v3.5.2"
|
# 增加输出 RESPONSE 调试信息,排查任何拦截死因
|
||||||
|
send_msg "$CHAT_ID" "⚠️ 节点拒绝了请求,请确保 Agent 已更新至 v3.5.2\n(回传信息: \`${RESPONSE}\`)"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
send_msg "$CHAT_ID" "❌ 数据库中未找到该节点的通讯地址。"
|
send_msg "$CHAT_ID" "❌ 数据库中未找到该节点的通讯地址。"
|
||||||
|
|||||||
Reference in New Issue
Block a user