|
Linux 上配全局代理,局代很多人第一反应是局代改 /etc/environment,或者往 ~/.bashrc 里塞几行 export http_proxy=...。局代这招对终端里的局代 curl、wget 管用,局代但你一打开 Chrome、局代一跑 Docker、局代一执行 apt,局代该卡还是局代卡。问题出在:环境变量只影响那些主动读取它的局代程序,而 Linux 世界里不读环境变量的局代程序太多了。 我去年在一台 Ubuntu 22.04 的局代机器上折腾了半天,export all_proxy=socks5://127.0.0.1:1080 写进 /etc/profile,局代终端里 curl google.com 秒通,局代结果 apt update 照样转圈转到超时。局代查了半天才想起来,apt 走的是自己的配置文件,根本不看 all_proxy。这就是环境变量方案的第一个坑:覆盖面取决于程序作者的心情。 真正意义上的“全局”,得从几个层面分别处理。 终端和命令行工具 环境变量仍然是最省事的办法,但别只写 http_proxy。大小写都要写,all_proxy 也要写,因为不同工具认的变量名不一样。curl 认小写 http_proxy,有些 Go 写的工具认 HTTPS_PROXY,还有的只认 all_proxy。全写上,不亏。 export http_proxy=http://127.0.0.1:7890 export https_proxy=http://127.0.0.1:7890 export all_proxy=socks5://127.0.0.1:7890 export HTTP_PROXY=$http_proxy export HTTPS_PROXY=$https_proxy export ALL_PROXY=$all_proxy export no_proxy=localhost,127.0.0.1,192.168.0.0/16 写到 /etc/profile.d/proxy.sh 里比塞 ~/.bashrc 好,因为前者对所有用户、所有登录 shell 生效,而且不会在你每次开终端时重复追加。 apt 和包管理器 apt 有自己的代理配置。新建 /etc/apt/apt.conf.d/95proxy: Acquire::http::Proxy "http://127.0.0.1:7890"; Acquire::https::Proxy "http://127.0.0.1:7890"; snap 更麻烦,它走 systemd 服务,得用 sudo snap set system proxy.http=...。pip 认环境变量但也认 ~/.pip/pip.conf。npm 要 npm config set proxy。每个包管理器都是一套自己的逻辑,没有银弹。 图形界面程序 GNOME 桌面环境下,gsettings set org.gnome.system.proxy mode 'manual' 加上对应的 host/port 设置,能让大部分 GTK 程序走代理。但 Chrome 和 Electron 系应用不一定买账,它们更倾向于读环境变量或者自己的启动参数。最稳的办法是给 Chrome 加启动参数 --proxy-server=socks5://127.0.0.1:1080,改 .desktop 文件里的 Exec 行。 透明代理才是终局 上面这些方法本质上都是“让程序主动配合”。真要一劳永逸,得用 iptables 或 nftables 做透明代理,把流量在网卡层面重定向到本地代理端口。配合 v2ray/xray 的 tproxy 模式,或者 clash 的 tun 模式,整个系统的 TCP/UDP 流量都会被接管,程序完全无感知。 我现在的方案是 clash 开 tun 模式,创建一张虚拟网卡,路由表里加默认路由指向它。好处是不用管任何程序怎么想,坏处是需要 root 权限,而且跟 Docker 的网络会有冲突——Docker 自己也会创建网卡和路由规则,两者偶尔打架。解决办法是在 clash 配置里把 Docker 的网段加进 bypass。 说到底,Linux 全局代理没有“一个配置搞定所有”的捷径。环境变量覆盖命令行,apt/snap/pip 各自配置,桌面环境走 gsettings,浏览器加启动参数,最后用 tun 模式兜底。按需组合,别指望一招通吃。 |