系统代理:流量是怎么被引导的
“为什么浏览器走代理而这个应用不走?”“为什么客户端退出后全系统断网?”——代理环境下最令人困惑的问题,根源几乎都在同一处:对"系统代理"机制的想象与它的真实工作方式不符。这一篇把机制讲透,那些怪象会自动变得合理。
系统代理是建议,不是强制
启用"系统代理"时,客户端做的事情朴素得出人意料:把自己监听的地址端口(如 127.0.0.1:7890)写进操作系统的一个约定位置(Windows 注册表的 Internet Settings、macOS 的网络服务代理设置)。仅此而已——没有任何机制强迫应用读取它。
于是一台电脑上并存着四种流量路径:
- 守规矩的应用(浏览器为代表):读取系统代理,流量交给客户端;
- 读环境变量的应用(命令行工具为代表):只认
http_proxy/https_proxy环境变量,系统代理设置对它们不存在; - 有自己配置的应用:应用内代理设置独立于一切系统机制;
- 谁都不理的应用:固定 IP 直连、UDP、私有协议——任何代理建议都约束不了它们。
“浏览器能用但应用不能"的全部谜底就在这张清单里。
TUN 模式:从建议到接管
TUN/虚拟网卡模式走的是另一条路:创建虚拟网络接口并修改路由表,让所有流量在网络层被截获——不再依赖应用的自觉。它解决了"应用不读代理"的问题,代价是需要更高权限,并引入新的故障面:客户端异常退出后路由表残留(表现为网络不可达)。
两大类系统代理故障
残留:客户端异常退出(崩溃、强杀、断电)时来不及清理系统代理设置,留下一个指向空端口的配置——全系统"断网",但不吃系统代理的应用反而正常。这是 PROXY-002 的完整故事。
错位:设置指向的端口与客户端实际监听的端口不一致——客户端换了端口而系统设置、浏览器扩展、PAC 脚本、环境变量没跟上。每一处引用都是一个潜在的过期点,对应 PROXY-001 与 PROXY-003。
排查的统一入口
connproof doctordoctor 一次给出三条关键证据:系统代理当前指向、常见本地代理端口的实际监听状态、两者的交叉判定(指向的端口无监听会被直接标注为疑似残留)。任何"全系统不正常"的场景,先跑它。
平台差异备忘
- Windows:系统代理全局一份(WinINET),但命令行工具普遍不读它;
- macOS:代理设置按网络服务分开(Wi-Fi 与以太网各一份),换接口后"代理失效"往往只是新接口没配置;
- Linux:没有统一的系统代理概念,桌面环境设置与环境变量各行其是,排查以环境变量为主。
理解了机制,最后送一条实践建议:让引用点尽量少。系统代理、浏览器扩展、环境变量、应用内设置——每多一处写着端口号的地方,就多一个未来的过期陷阱。能用客户端统一管理的,就不要手工散落各处。