如何确认本地代理栈的出站流量是否经过本地 TUN 代理

本文由 AI 辅助整理,并由人工复核后发布。

背景

有些本地代理栈本身并不直接配置本地 TUN 代理作为上游代理,但由于 Windows 系统启用了 TUN 接管,进程的外连 TCP 连接仍可能被系统路由导入该 TUN 接口。

因此确认时要分三层看:

  1. 脚本配置层:脚本有没有显式设置本地代理程序为 HTTP/SOCKS 上游。
  2. 本机监听层:本地端口实际由哪个进程监听。
  3. 系统路由层:真正对外连接时是否走了本地 TUN 接口。

下面以一个本地代理栈为例:

Client -> http://127.0.0.1:8118 -> HTTP-to-SOCKS bridge
       -> socks5://127.0.0.1:1090 -> ssh -D tunnel
       -> remote SSH server -> target websites

1. 检查脚本是否显式使用本地代理程序

先在项目目录里搜索代理相关配置:

rg -n "HTTP_PROXY|HTTPS_PROXY|ALL_PROXY|NO_PROXY|http_proxy|https_proxy|all_proxy|no_proxy|7890|7897|socks|proxy|tun" .

重点看启动脚本里是否出现以下几类配置:

SSH_TUNNEL_TARGET="${SSH_TUNNEL_TARGET:-<ssh-user>@<ssh-server-ip>}"
SOCKS_HOST="${SOCKS_HOST:-127.0.0.1}"
SOCKS_PORT="${SOCKS_PORT:-1090}"
HTTP_HOST="${HTTP_HOST:-127.0.0.1}"
HTTP_PORT="${HTTP_PORT:-8118}"

如果脚本启动的是 SSH 动态转发:

ssh -D "$SOCKS_HOST:$SOCKS_PORT" -N "$SSH_TUNNEL_TARGET"

再用 bridge 把 HTTP 代理转到本地 SOCKS:

uv run --with pproxy python -m pproxy \
  -l "$HTTP_PROXY_URL" \
  -r "socks5://$SOCKS_HOST:$SOCKS_PORT"

那么脚本配置层的链路就是:

http://127.0.0.1:8118 -> socks5://127.0.0.1:1090 -> SSH tunnel

这不等于脚本显式使用本地代理程序。此时还需要继续确认运行时的端口和路由。

2. 检查本地端口由哪个进程监听

在 Windows 上查看相关端口:

netstat -ano | Select-String -Pattern ':1090|:8118'

期望看到类似结果:

TCP    127.0.0.1:1090    0.0.0.0:0    LISTENING    <ssh-pid>
TCP    127.0.0.1:8118    0.0.0.0:0    LISTENING    <bridge-pid>

然后确认 PID 对应的进程名:

Get-Process -Id <ssh-pid>,<bridge-pid> | Select-Object Id,ProcessName,Path

期望结果:

Id        ProcessName
--        -----------
<pid>     ssh
<pid>     python

这里的判断是:

  • 127.0.0.1:1090ssh 监听,说明 SOCKS 入口来自 ssh -D
  • 127.0.0.1:8118python 监听,通常说明 HTTP bridge 来自 pproxy
  • 如果这两个端口被其他代理程序监听,说明运行时已经偏离脚本预期。

3. 检查 SSH 外连是否经过本地 TUN

脚本没有显式使用本地代理程序,不代表出站 TCP 一定绕过本地 TUN。因为如果 TUN 接管了系统默认路由,ssh 连接远端服务器时可能被系统路由导入该 TUN 接口。

先查看 ssh 到远端服务器的连接:

netstat -ano | Select-String -Pattern '<ssh-server-ip>:22'

如果看到类似结果:

TCP    198.18.0.1:<local-port>    <ssh-server-ip>:22    ESTABLISHED    <ssh-pid>

这里的关键是本地地址 198.18.0.1。它常见于本地 TUN 代理虚拟网段,但不能只凭地址猜测,还要查接口。

查看 Windows IPv4 地址:

netsh interface ipv4 show addresses

如果输出里有类似内容:

Configuration for interface "Local TUN Proxy"
    IP Address:       198.18.0.1
    Default Gateway:  198.18.0.2

再查看路由:

netsh interface ipv4 show route

如果看到:

Prefix       Idx  Gateway/Interface Name
0.0.0.0/0    ...  198.18.0.2
198.18.0.0/30 ... Local TUN Proxy

就可以判断:当前系统默认路由存在本地 TUN 接管,且 ssh 的外连本地地址属于该 TUN 接口。

4. 如何表述最终结论

建议把结论拆开写,避免把脚本配置和系统路由混为一谈:

脚本没有显式配置本地代理程序作为 HTTP/SOCKS 上游。

脚本配置的代理链路是:
Client -> http://127.0.0.1:8118 -> pproxy -> socks5://127.0.0.1:1090 -> ssh -D -> remote SSH server。

当前运行时,ssh 到远端服务器的 TCP 连接使用了 198.18.0.1 这个本地地址,而 198.18.0.1 属于 Windows 上的本地 TUN 接口;同时系统存在经 198.18.0.2 的默认路由。

因此,应用流量先进入本地 HTTP/SOCKS/SSH 隧道;SSH 隧道本身连接远端服务器这一段,则当前经过系统层的本地 TUN。

更短的结论可以写成:

不是脚本显式使用本地代理程序,而是当前 Windows 默认路由把 ssh 隧道的出站连接导入了本地 TUN。

5. 常见误判

只看脚本,漏掉系统路由

脚本里没有本地代理程序名、78907897 等关键词,只能说明脚本没有显式配置代理上游。系统 TUN 仍可能接管普通 TCP 出站。

只看出口 IP,无法还原完整链路

出口 IP 能说明最终从哪个公网出口访问目标站点,但不能单独说明本机到 SSH 服务器这一段是否经过本地 TUN。

要确认链路,需要同时看:

  • 本地端口监听进程。
  • ssh 对远端服务器的 TCP 连接。
  • 本地地址属于哪个 Windows 网络接口。
  • 系统默认路由指向哪个网关。

把 HTTP bridge 当成最终出口

http://127.0.0.1:8118 只是本机 HTTP 代理入口。它后面还会转到 socks5://127.0.0.1:1090,再由 ssh -D 把目标连接送到远端服务器。

6. 最小确认命令清单

# 1. 看脚本是否显式出现代理变量或常见代理端口
rg -n "HTTP_PROXY|HTTPS_PROXY|ALL_PROXY|NO_PROXY|socks|proxy|tun|7890|7897" .

# 2. 看本地代理端口由谁监听
netstat -ano | Select-String -Pattern ':1090|:8118'
Get-Process -Id <ssh-pid>,<bridge-pid> | Select-Object Id,ProcessName,Path

# 3. 看 ssh 外连远端服务器时使用的本地地址
netstat -ano | Select-String -Pattern '<ssh-server-ip>:22'

# 4. 看这个本地地址属于哪个接口
netsh interface ipv4 show addresses

# 5. 看默认路由是否经过本地 TUN
netsh interface ipv4 show route

7. 判断标准

如果同时满足以下条件:

  • 127.0.0.1:1090ssh 监听。
  • 127.0.0.1:8118python / pproxy 监听。
  • ssh 到远端服务器的连接本地地址是 198.18.0.1 或其他本地 TUN 地址。
  • netsh interface ipv4 show addresses 显示该地址属于本地 TUN 接口。
  • netsh interface ipv4 show route 显示默认路由经过本地 TUN 网关。

那么可以得出:

脚本配置本身没有把本地代理程序作为代理上游;
当前运行时,ssh 隧道连接远端服务器的出站 TCP 连接经过了本地 TUN。
posted @ 2026-06-23 00:19  LexLuc  阅读(7)  评论(0)    收藏  举报