Skip to content

Commit 78c1e90

Browse files
committed
refactor(scripts): 优化跨订阅切换节点流程并修复控制接口状态检测漏洞
- 核心优化:在 `service.sh` 的启动、停止、重启指令中新增 `core` 标志,允许通过指定参数跳过 `tproxy.sh` 代理防火墙规则的加载和清理,从而仅对 `sing-box` 进程执行轻量重启。 - 逻辑退化:修改 `switch.sh` 中的切换退化逻辑,在控制接口热切换失效时,使用 `restart core` 代替原有的完整重启,避免了因防火墙规则重建导致的断网与切换延迟,使切换耗时缩短至毫秒级。 - 漏洞修复:修正 `api.sh` 中 `nc` 管道请求的退出码被 `sed` 覆盖以及 `nc` 无法识别 HTTP 4xx/5xx 错误的缺陷。通过捕获响应头行验证 HTTP 状态码是否为 2xx,确保请求失败时能正确返回非零状态码,以协助切换逻辑正确退化。
1 parent cef7f6b commit 78c1e90

3 files changed

Lines changed: 63 additions & 16 deletions

File tree

src/module/scripts/core/service.sh

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,15 @@ cleanup_runtime_files() {
5252
# 启动服务
5353
#######################################
5454
do_start() {
55+
local skip_tproxy="${1:-0}"
5556
local pid runtime_outbounds new_pid
5657
local node_path
5758

58-
log "INFO" "========== 开始启动 sing-box 服务 =========="
59+
if [ "$skip_tproxy" = "1" ]; then
60+
log "INFO" "========== 开始启动 sing-box 核心服务 (跳过 tproxy) =========="
61+
else
62+
log "INFO" "========== 开始启动 sing-box 服务 =========="
63+
fi
5964
verify_environment
6065

6166
pid="$(get_pid "$SING_BOX_BIN")"
@@ -105,8 +110,10 @@ EOF
105110
LOG_STDERR=0 SWITCH_ALLOW_RESTART=0 sh "$SWITCH_SCRIPT" config "$CUR_OUTBOUND_CONFIG" || die "节点配置同步失败,启动中止"
106111
fi
107112

108-
log "INFO" "正在加载透明代理规则..."
109-
"$TPROXY_SCRIPT" start -d "$TPROXY_CONF_DIR" >> "$LOG_FILE" 2>&1 || die "透明代理规则加载失败"
113+
if [ "$skip_tproxy" != "1" ]; then
114+
log "INFO" "正在加载透明代理规则..."
115+
"$TPROXY_SCRIPT" start -d "$TPROXY_CONF_DIR" >> "$LOG_FILE" 2>&1 || die "透明代理规则加载失败"
116+
fi
110117

111118
log "INFO" "========== sing-box 服务启动完成 =========="
112119
}
@@ -115,13 +122,20 @@ EOF
115122
# 停止服务
116123
#######################################
117124
do_stop() {
125+
local skip_tproxy="${1:-0}"
118126
local pid count
119127

120-
log "INFO" "========== 开始停止 sing-box 服务 =========="
128+
if [ "$skip_tproxy" = "1" ]; then
129+
log "INFO" "========== 开始停止 sing-box 核心服务 (跳过 tproxy) =========="
130+
else
131+
log "INFO" "========== 开始停止 sing-box 服务 =========="
132+
fi
121133
verify_environment
122134

123-
log "INFO" "正在清理透明代理规则..."
124-
"$TPROXY_SCRIPT" stop -d "$TPROXY_CONF_DIR" >> "$LOG_FILE" 2>&1 || true
135+
if [ "$skip_tproxy" != "1" ]; then
136+
log "INFO" "正在清理透明代理规则..."
137+
"$TPROXY_SCRIPT" stop -d "$TPROXY_CONF_DIR" >> "$LOG_FILE" 2>&1 || true
138+
fi
125139

126140
pid="$(get_pid "$SING_BOX_BIN")"
127141
if [ -z "$pid" ]; then
@@ -155,10 +169,19 @@ do_stop() {
155169
# 重启服务
156170
#######################################
157171
do_restart() {
158-
log "INFO" "========== 开始重启 sing-box 服务 =========="
159-
do_stop
172+
local target="${1:-}"
173+
local skip_tproxy=0
174+
175+
if [ "$target" = "core" ]; then
176+
skip_tproxy=1
177+
log "INFO" "========== 开始重启 sing-box 核心服务 (跳过 tproxy) =========="
178+
else
179+
log "INFO" "========== 开始重启 sing-box 服务 =========="
180+
fi
181+
182+
do_stop "$skip_tproxy"
160183
sleep 1
161-
do_start
184+
do_start "$skip_tproxy"
162185
}
163186

164187
#######################################
@@ -202,13 +225,19 @@ EOF
202225
main() {
203226
case "${1:-}" in
204227
start)
205-
do_start
228+
local target="${2:-}"
229+
local skip=0
230+
[ "$target" = "core" ] && skip=1
231+
do_start "$skip"
206232
;;
207233
stop)
208-
do_stop
234+
local target="${2:-}"
235+
local skip=0
236+
[ "$target" = "core" ] && skip=1
237+
do_stop "$skip"
209238
;;
210239
restart)
211-
do_restart
240+
do_restart "${2:-}"
212241
;;
213242
status)
214243
do_status

src/module/scripts/core/switch.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ is_service_running() {
2828
#######################################
2929
restart_service_if_allowed() {
3030
if [ "$SWITCH_ALLOW_RESTART" = "1" ]; then
31-
log "INFO" "正在重启 sing-box 服务以应用配置..."
32-
LOG_STDERR=0 sh "$SERVICE_SCRIPT" restart || die "重启 sing-box 服务失败"
31+
log "INFO" "正在重启 sing-box 核心服务以应用配置..."
32+
LOG_STDERR=0 sh "$SERVICE_SCRIPT" restart core || die "重启 sing-box 服务失败"
3333
else
3434
log "WARN" "当前阶段不允许通过重启应用配置"
3535
return 1

src/module/scripts/utils/api.sh

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ api_request() {
6060
host="${controller%%:*}"
6161
port="${controller##*:}"
6262

63-
{
63+
local response status_line status
64+
response=$( {
6465
printf "%s %s HTTP/1.1\r\n" "$method" "$path"
6566
printf "Host: %s\r\n" "$controller"
6667
printf "Authorization: Bearer %s\r\n" "$secret"
@@ -71,7 +72,24 @@ api_request() {
7172
printf "Connection: close\r\n"
7273
printf "\r\n"
7374
[ -n "$data" ] && printf "%s" "$data"
74-
} | "$(detect_busybox)" nc "$host" "$port" 2>/dev/null | sed '1,/^\r$/d'
75+
} | "$(detect_busybox)" nc "$host" "$port" 2>/dev/null )
76+
status=$?
77+
78+
status_line=$(printf "%s" "$response" | head -n 1)
79+
80+
if [ "$method" = "GET" ]; then
81+
printf "%s" "$response" | sed '1,/^\r$/d'
82+
if [ $status -ne 0 ] || ! printf "%s" "$status_line" | grep -q -E '^HTTP/[0-9.]+ 2[0-9][0-9]'; then
83+
return 1
84+
fi
85+
return 0
86+
else
87+
if [ $status -ne 0 ] || ! printf "%s" "$status_line" | grep -q -E '^HTTP/[0-9.]+ 2[0-9][0-9]'; then
88+
log "ERROR" "[控制接口错误] 请求失败: $method $path,状态行: $status_line"
89+
return 1
90+
fi
91+
return 0
92+
fi
7593
}
7694

7795
#######################################

0 commit comments

Comments
 (0)