From 712b77a43a488750e2887b689666954fb21810e3 Mon Sep 17 00:00:00 2001 From: Arvin <62139570+wnlen@users.noreply.github.com> Date: Sun, 16 Aug 2026 17:07:06 +0800 Subject: [PATCH] Fix TUN proxy-off shell restore state tun on-proxy-off cleared the system proxy block but left the shell restore flag enabled, so new login shells re-injected proxy variables. Disable both persistence layers and retain cleanup errors.\n\nFixes #308 --- scripts/core/clashctl.sh | 27 +++++-- .../dev/check-tun-proxy-off-shell-restore.sh | 81 +++++++++++++++++++ 2 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 scripts/dev/check-tun-proxy-off-shell-restore.sh diff --git a/scripts/core/clashctl.sh b/scripts/core/clashctl.sh index cad2087..9d5b06b 100644 --- a/scripts/core/clashctl.sh +++ b/scripts/core/clashctl.sh @@ -5518,26 +5518,39 @@ cmd_tun_off() { } cmd_tun_on_proxy_off() { - local system_proxy_rc + local system_proxy_rc shell_proxy_rc=0 cmd_tun_on || return $? + set_shell_proxy_persist_enabled "false" || shell_proxy_rc=$? + if boot_proxy_keep_disable; then + system_proxy_rc=0 + else + system_proxy_rc=$? + fi + + if [ "$shell_proxy_rc" -eq 0 ] && [ "$system_proxy_rc" -eq 0 ]; then ui_blank ui_ok "系统代理已关闭,当前使用 Tun 模式接管" ui_blank return 0 fi - system_proxy_rc=$? - if [ "$system_proxy_rc" -eq 2 ]; then - ui_warn "当前环境不支持清理系统代理持久块,Tun 已按前序结果处理" - else - ui_warn "系统代理持久块清理失败,Tun 已按前序结果处理" + if [ "$shell_proxy_rc" -ne 0 ]; then + ui_warn "Shell 代理自动恢复关闭失败,Tun 已按前序结果处理" + fi + if [ "$system_proxy_rc" -ne 0 ]; then + if [ "$system_proxy_rc" -eq 2 ]; then + ui_warn "当前环境不支持清理系统代理持久块,Tun 已按前序结果处理" + else + ui_warn "系统代理持久块清理失败,Tun 已按前序结果处理" + fi fi ui_next "clash doctor" ui_blank - return "$system_proxy_rc" + [ "$system_proxy_rc" -ne 0 ] && return "$system_proxy_rc" + return "$shell_proxy_rc" } cmd_tun_off_proxy_on() { diff --git a/scripts/dev/check-tun-proxy-off-shell-restore.sh b/scripts/dev/check-tun-proxy-off-shell-restore.sh new file mode 100644 index 0000000..8eff788 --- /dev/null +++ b/scripts/dev/check-tun-proxy-off-shell-restore.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" + +source_clashctl_for_tests() { + set -- "" + # Source the real command functions; suppress the no-arg usage output. + source "$PROJECT_DIR/scripts/core/clashctl.sh" >/dev/null +} + +source_clashctl_for_tests + +tmp_dir="$(mktemp -d)" +trap 'rm -rf "$tmp_dir"' EXIT + +test_project="$tmp_dir/project" +RUNTIME_DIR="$test_project/runtime" +mkdir -p "$test_project/scripts/core" "$RUNTIME_DIR" +cp "$PROJECT_DIR/scripts/core/alias.sh" "$test_project/scripts/core/alias.sh" + +cat > "$RUNTIME_DIR/config.yaml" <<'YAML' +mixed-port: 7890 +YAML + +set_shell_proxy_persist_enabled "true" + +cmd_tun_on() { :; } +boot_proxy_keep_disable() { :; } +ui_blank() { :; } +ui_ok() { :; } +ui_warn() { :; } +ui_next() { :; } + +cmd_tun_on_proxy_off + +if shell_proxy_persist_enabled; then + echo "not ok - tun on-proxy-off keeps shell proxy auto-restore enabled" >&2 + exit 1 +fi + +actual="$( + env -i \ + HOME="$tmp_dir/home" \ + PATH="$PATH" \ + bash --noprofile --norc -c ' + unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY + source "'"$test_project"'/scripts/core/alias.sh" + printf "%s\n" "${http_proxy:-}" + ' +)" + +if [ -n "$actual" ]; then + echo "not ok - a new shell restored proxy after tun on-proxy-off: $actual" >&2 + exit 1 +fi + +echo "ok - tun on-proxy-off disables shell proxy auto-restore" + +set_shell_proxy_persist_enabled "true" +boot_proxy_keep_disable() { return 2; } + +if cmd_tun_on_proxy_off; then + echo "not ok - tun on-proxy-off ignored system proxy cleanup failure" >&2 + exit 1 +else + actual_rc=$? +fi + +if [ "$actual_rc" -ne 2 ]; then + echo "not ok - tun on-proxy-off returned $actual_rc, expected 2" >&2 + exit 1 +fi + +if shell_proxy_persist_enabled; then + echo "not ok - system proxy cleanup failure left shell auto-restore enabled" >&2 + exit 1 +fi + +echo "ok - shell auto-restore stays off when system proxy cleanup fails"