Linux 没有一个统一的“系统代理”开关:浏览器读取桌面环境设置,终端看环境变量,apt、Docker 和 systemd 服务则各有各的配置文件。本文逐层梳理这些设置,并说明不识别代理的程序该怎么处理。
Windows 和 macOS 都有一个大多数程序会读取的系统代理,Linux 没有这样的中心。代理在三个层面设置,每个程序只看它认识的那一层。
第一层是桌面环境设置。GNOME 把代理保存在 gsettings 中(schema 为 org.gnome.system.proxy),KDE Plasma 保存在 ~/.config/kioslaverc 文件中。Chromium 系浏览器和使用 libproxy 库构建的程序会读取这一层。
第二层是环境变量 http_proxy、https_proxy、ftp_proxy、all_proxy 和 no_proxy。这是终端中的主要方式:curl、wget、git、pip、npm、apt 以及大量其他工具都会读取。
第三层是程序自己的配置文件:apt、dnf、snapd、Docker、git 和 npm 都可以在各自的设置中直接写入代理。这对 systemd 服务和通过 sudo 执行的命令尤其重要,因为它们拿不到你当前会话的变量。
由此得出最重要的一条原则:设置完成后,逐一检查每个你关心的程序的出口 IP。浏览器走了代理,并不代表 apt、Docker 或你的脚本也走了代理。
其他系统的同类指南: Windows 代理客户端、 Mac 代理设置、 路由器代理设置。
在 GNOME 中(Ubuntu 和 Fedora Workstation 的默认桌面,也用于安装了 GNOME 的 Debian),代理从“设置”的“网络”面板进入。Ubuntu 26.04 帮助文档列出了三种模式:“无”(直接连接)、“手动”(分别填写 HTTP、HTTPS、FTP 和 SOCKS 的地址和端口)和“自动”(填写 PAC 文件的 URL)。在新版 GNOME 中,HTTP、HTTPS、FTP 和 SOCKS 字段、例外列表以及配置地址都集中在同一个代理设置页面上。
需要注意:GNOME 窗口中只有主机和端口。界面里无法填写用户名和密码,尽管 gsettings 的 HTTP 配置中有 authentication-user 和 authentication-password 两个键。所有设置都可以在终端用 gsettings 命令修改,便于写脚本和远程配置。
在 KDE Plasma 中(Kubuntu、Fedora 以及其他发行版的 KDE 版本),代理位于“系统设置”→“网络”→“代理”(System Settings → Network → Proxy)。可选模式包括:不使用代理、自动检测、PAC 文件地址、使用系统代理配置(从环境变量读取),以及手动配置(HTTP、SSL、FTP 和 SOCKS 字段)。设置保存在 ~/.config/kioslaverc 中,KDE 应用通过 KIO 读取,基于 libproxy 的程序也会读取。这个窗口同样没有用户名和密码字段。
根据 Chromium 项目文档,Linux 上的 Chromium 会自动识别自己运行在 GNOME 还是 KDE 中,并读取对应的代理设置。在其他桌面环境中,它使用命令行参数和环境变量。Firefox 有自己的设置,也可以选择使用系统设置。注意 Chromium 的限制:它对 SOCKS5 不支持任何认证方式,所以给 Chrome 使用带密码的代理,最好填成 HTTP 代理。
# 与 GNOME 设置窗口的作用相同
gsettings set org.gnome.system.proxy mode 'manual'
gsettings set org.gnome.system.proxy.http host 'host'
gsettings set org.gnome.system.proxy.http port 8080
gsettings set org.gnome.system.proxy.https host 'host'
gsettings set org.gnome.system.proxy.https port 8080
gsettings set org.gnome.system.proxy.socks host 'host'
gsettings set org.gnome.system.proxy.socks port 1080
# 关闭代理
gsettings set org.gnome.system.proxy mode 'none'请将 host 和端口替换为你自己的信息。这些命令修改的是当前用户的设置,不需要 sudo。
Chrome 与带密码的 SOCKS5 不兼容。在 Chromium 和 Chrome 中使用带用户名密码的代理时,请使用 HTTP 代理或代理客户端。浏览器的详细设置见 浏览器代理设置指南。
Astra Linux 是一款基于 Debian 的俄罗斯发行版,使用自己的 Fly 桌面和工具,所以 Ubuntu 的操作说明不能直接照搬。根据 Astra Linux 帮助中心的《使用 PROXY》一文,系统级代理通过 /etc/environment 中的环境变量设置(需要重启),图形程序则通过 fly-kcmshell5 proxy 读取这些值;通过 fly-kcmshell5 设置的带用户名密码的代理无法使用。如果你使用的是 Astra,请以其帮助中心中对应版本的说明为准。
在命令行中,主要方式是设置 http_proxy、https_proxy、ftp_proxy、all_proxy 和 no_proxy 变量。值写成 URL:协议头、用户名和密码(如有)、主机和端口。当某个协议没有单独的变量时,会使用 all_proxy;no_proxy 是用逗号分隔的主机和域名列表,这些地址直接连接。
大小写有区别。根据 curl 手册,变量可以用小写或大写,小写优先,但 http_proxy 只在小写时有效。Docker daemon 则两种都会检查,还有一些程序只读取大写。所以实际使用中,通常把两组变量都设置成相同的值。
变量保存在哪里。export 命令只对当前终端会话有效。对单个用户,把它追加到 ~/.bashrc(或 ~/.zshrc)。对所有用户,可以使用 /etc/environment:这个文件在登录时由 pam_env 模块读取,它不是脚本,而是 KEY=value 形式的行,不能写 export,也不会展开其他变量。另一个选择是 /etc/profile.d/ 下的脚本,它在登录 shell 启动和图形会话启动时执行。Ubuntu 不建议直接编辑 /etc/profile,因为它属于 base-files 软件包。
两个常见陷阱。第一是 sudo:它默认会重置环境变量,代理随之丢失。可以用 sudo -E(前提是 sudo 策略允许保留环境变量),或者在 /etc/sudoers.d/ 下的文件中添加 Defaults env_keep += "*_proxy *_PROXY"。第二是 systemd 服务:服务管理器启动的进程不会继承你的会话变量,需要在 unit 中通过 Environment= 为它们设置代理。
使用 SOCKS5 时请写 socks5h://,而不是 socks5://。在 curl 中,socks5h 表示由代理解析网站域名,而不是本机解析。否则 DNS 请求会发往你的运营商或主机商的 DNS。
# 当前终端会话的代理
export http_proxy="http://login:pass@host:8080"
export https_proxy="http://login:pass@host:8080"
export all_proxy="socks5h://login:pass@host:1080"
export no_proxy="localhost,127.0.0.1,.local"
# 部分程序只读取大写变量
export HTTP_PROXY="$http_proxy" HTTPS_PROXY="$https_proxy" NO_PROXY="$no_proxy"
# 查看当前设置
env | grep -i _proxy
# 取消代理
unset http_proxy https_proxy all_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY
# 使用 sudo 时保留代理变量(只能通过 visudo 编辑)
sudo visudo -f /etc/sudoers.d/05_proxy
# Defaults env_keep += "*_proxy *_PROXY"请将 host、端口、login 和 pass 替换为你自己的信息。密码中的特殊字符需要进行百分号编码,例如 @ 写作 %40。以 # 开头并缩进的行,写入打开的文件时要去掉 # 符号。
apt(Debian、Ubuntu、Mint)会读取 http_proxy 变量,但更可靠的方式是在 /etc/apt/apt.conf.d/ 下的文件中写入 Acquire::http::Proxy "http://login:pass@host:8080/",Acquire::https::Proxy 同理。根据 apt-transport-http 手册,支持 http、https 和 socks5h 协议头,即由代理端解析 DNS 的 SOCKS5。用户名和密码可以放到 apt_auth.conf,个别主机可以设置为 DIRECT。
dnf(Fedora、RHEL 及其衍生版)从 /etc/dnf/dnf.conf 或仓库文件中的 proxy= 参数读取代理,用户名和密码分别通过 proxy_username 和 proxy_password 设置。根据 dnf 文档,未设置 proxy 时使用 curl 的环境变量,例如 http_proxy。在仓库描述中把 proxy 设为空值,可以取消从主配置段继承的代理。
curl 通过 -x(--proxy)参数接受代理,支持 http、https、socks4、socks4a、socks5 和 socks5h 协议头,不带参数时读取环境变量。-x 参数优先于环境变量。wget 读取 http_proxy、https_proxy、ftp_proxy 和 no_proxy,也读取 /etc/wgetrc(Debian 和 Ubuntu)和 ~/.wgetrc 中的同名参数,用户名和密码通过 proxy_user 和 proxy_password 设置。wget 手册中没有提到 SOCKS,需要 SOCKS 时请用 curl 或 proxychains。
git 在没有额外配置时读取 http_proxy、https_proxy 和 all_proxy,http.proxy 参数会覆盖它们,语法与 curl 相同,包括 socks5h://。也可以通过 remote.<名称>.proxy 为单个远程仓库设置代理。pip 通过 --proxy 参数、pip.conf 中的 proxy 参数,或 http_proxy、https_proxy 和 no_proxy 变量获取代理。npm 使用 proxy 和 https-proxy 参数,未设置时读取 HTTP_PROXY、HTTPS_PROXY 及其小写形式。
snapd 作为系统服务运行,看不到你终端中的变量。需要用 snap set system proxy.http=... 和 proxy.https=... 为它设置代理。根据 snapd 源码,这些值用于它自身的请求;如果没有设置,snapd 会从自己的环境中读取代理。
# APT(Debian、Ubuntu、Mint):文件 /etc/apt/apt.conf.d/95proxy
Acquire::http::Proxy "http://login:pass@host:8080/";
Acquire::https::Proxy "http://login:pass@host:8080/";
# 通过 SOCKS5 并由代理解析 DNS 的写法:
# Acquire::http::Proxy "socks5h://login:pass@host:1080/";
# DNF(Fedora、RHEL):/etc/dnf/dnf.conf 的 [main] 段
proxy=http://host:8080
proxy_username=login
proxy_password=pass
# curl 和 git
curl -x socks5h://login:pass@host:1080 https://example.com
git config --global http.proxy http://login:pass@host:8080
# pip 和 npm
pip install --proxy http://login:pass@host:8080 requests
npm config set proxy http://login:pass@host:8080
npm config set https-proxy http://login:pass@host:8080
# snapd(系统服务,看不到终端中的变量)
sudo snap set system proxy.http="http://login:pass@host:8080"
sudo snap set system proxy.https="http://login:pass@host:8080"
# wget:/etc/wgetrc 或 ~/.wgetrc
use_proxy = on
http_proxy = http://host:8080/
https_proxy = http://host:8080/
proxy_user = login
proxy_password = pass修改 /etc 下的配置文件需要 root 权限。配置文件中的明文密码对所有能访问该文件的用户可见,请谨慎设置文件权限。
Docker 有两个互相独立的代理设置位置。第一个是守护进程 dockerd,它从 Docker Hub 和其他镜像仓库拉取镜像。根据 Docker 文档,推荐方式是在 /etc/docker/daemon.json 中使用 proxies 键,填写 http-proxy、https-proxy 和 no-proxy,然后重启守护进程。也可以在 systemd 的 drop-in 文件 /etc/systemd/system/docker.service.d/http-proxy.conf 中用环境变量设置代理,但守护进程配置的优先级高于环境变量。Docker Desktop 会忽略 daemon.json 中的代理,它有自己的设置。
第二个是容器和构建过程。~/.docker/config.json 中的 proxies 段不影响客户端和守护进程本身:Docker 据此在容器中设置 HTTP_PROXY 和 http_proxy 变量,并作为构建参数传入。常见错误是只配置了守护进程,然后发现容器里的应用仍然直接联网,或者反过来。
任何 systemd 服务都是如此,无论是数据采集程序、机器人还是监控代理。服务管理器启动的进程不会继承你的会话变量,也不会读取 ~/.bashrc。需要在 unit 中用 Environment= 指令,或通过 EnvironmentFile= 引用文件来设置代理。最方便的方式是使用 systemctl edit,让修改保存在单独的 drop-in 文件中,软件包更新时不会丢失。
# Docker daemon(拉取镜像):/etc/docker/daemon.json
{
"proxies": {
"http-proxy": "http://login:pass@host:8080",
"https-proxy": "http://login:pass@host:8080",
"no-proxy": "localhost,127.0.0.0/8"
}
}
sudo systemctl restart docker
# 其他任意 systemd 服务
sudo systemctl edit myservice.service
# [Service]
# Environment="HTTPS_PROXY=http://login:pass@host:8080"
# Environment="NO_PROXY=localhost,127.0.0.1"
sudo systemctl restart myservice.servicedaemon.json 只影响守护进程(拉取和推送镜像)。容器的代理在 ~/.docker/config.json 中设置。以 # 开头并缩进的行,写入打开的文件时要去掉 # 符号。
很多程序完全不支持代理,或者只支持 HTTP。对于这些程序,可以使用拦截网络连接的封装工具。
proxychains-ng(Debian 和 Ubuntu 中的软件包为 proxychains4,配置文件为 /etc/proxychains4.conf)通过 LD_PRELOAD 替换网络函数。根据项目说明,它只对动态链接的程序有效,且只支持 TCP,不支持 UDP 和 ICMP。支持 http、socks4 和 socks5 代理,其中 http 和 socks5 支持用户名密码,还支持代理链和通过代理解析 DNS(proxy_dns)。默认的 /etc/proxychains4.conf 启用了 strict_chain,并包含一行用于 Tor 的 socks4 127.0.0.1 9050:需要把它注释掉并添加自己的代理,而且 [ProxyList] 中只接受 IPv4 地址,不接受主机名。最新版本 4.17 发布于 2024 年 1 月,但主分支在 2026 年 8 月仍有更新。
graftcp 解决了 proxychains 的主要缺点:它通过 ptrace 拦截系统调用,不依赖 LD_PRELOAD,因此也能处理静态编译的程序,包括大多数 Go 程序。它可以把 TCP 转发到 SOCKS5 或 HTTP 代理,支持代理 DNS,显式开启后还能转发 UDP。仅支持 Linux。Ubuntu 22.04 和 24.04 中有 graftcp 软件包,但版本是较旧的 0.3.1。项目在 GitHub Releases 中发布最新的 .deb、.rpm 包和压缩包,最近一次发布在 2026 年 7 月,主分支在 2026 年 8 月有更新。
如果要让整台机器的流量都走代理,可以使用 TUN,即虚拟网络接口。tun2socks 支持带认证的 HTTP、SOCKS、Shadowsocks 和 SSH 代理,2026 年 9 月有更新。sing-box 支持 tun 入站和带用户名密码的 socks 出站。Linux 上的图形客户端有基于 mihomo 内核的 Clash Verge Rev:它为 x64、arm64 和 armhf 提供 .deb 和 .rpm 包,支持系统代理和 TUN 模式,2026 年 9 月有更新。各系统上这类软件的详细对比,见 Proxifier 替代软件一文。
# Debian 和 Ubuntu
sudo apt install proxychains4
# 在 /etc/proxychains4.conf 的 [ProxyList] 段:注释掉 socks4 127.0.0.1 9050 这一行
# 然后添加自己的代理(只能填 IPv4 地址,不接受主机名)
# socks4 127.0.0.1 9050
socks5 203.0.113.10 1080 login pass
# 让任意程序通过代理运行
proxychains4 curl https://example.com203.0.113.10 是文档专用地址段中的地址,请替换为你的代理的 IPv4 地址。
延伸阅读: Proxifier 替代软件、 SOCKS5 代理原理与配置。
搜索“Linux 代理服务器”的人,很多时候要的不是客户端,而是自己的服务器。下面简要介绍三种最常见的选择,不展开分步教程。
Squid 是带缓存的 Web 代理,支持 HTTP、HTTPS、FTP 等协议。Debian(包括 Debian 13)以及 Ubuntu 24.04 和 26.04 的标准仓库中都有,适合办公网络、缓存和过滤。如果需要不带缓存的轻量 HTTP 代理,同一仓库中还有 tinyproxy。
Dante 是 SOCKS 服务器,软件包名为 dante-server。它在 Ubuntu 24.04、26.04、Debian 12 和 Debian 测试分支中提供,但在核查时稳定版 Debian 13 中没有。3proxy 是一个紧凑的服务器,一个程序同时支持 HTTP 和 SOCKS。Debian 和 Ubuntu 仓库中没有它,但项目自己发布 .deb 和 .rpm 包,并维护签名的 apt 和 dnf 仓库。1.0.0 版本于 2026 年 8 月发布。
请记住,自建服务器的出口 IP 是你的 VPS 或家庭宽带的 IP。在平台会检查 IP 类型的场景中,机房 IP 的效果通常不如移动运营商的 IP。如果目标就是移动 IP,就不需要自己搭建服务器。
| 程序 | 设置位置 | SOCKS | 说明 |
|---|---|---|---|
| GNOME (Ubuntu, Fedora) | “设置”→“网络”→“网络代理”,gsettings 键 org.gnome.system.proxy | 支持,SOCKS 字段 | 界面中只有主机和端口。Chromium 和基于 libproxy 的程序会读取。 |
| KDE Plasma | “系统设置”→“网络”→“代理”,文件 ~/.config/kioslaverc | 支持,SOCKS 字段 | 可选择从环境变量读取系统代理配置。没有用户名和密码字段。 |
| Astra Linux (Fly) | fly-kcmshell5 proxy,/etc/environment | socks_proxy 变量 | 根据 Astra 帮助中心,通过 fly-kcmshell5 设置的带认证代理无法使用。 |
| apt | /etc/apt/apt.conf.d/,Acquire::http::Proxy | 支持,socks5h:// | 也会读取 http_proxy,但通过 sudo 运行时该变量通常会丢失。 |
| dnf | /etc/dnf/dnf.conf,proxy= 和 proxy_username= | 文档未说明 | 未设置 proxy 时,使用 curl 的环境变量,例如 http_proxy。 |
| curl | -x 参数或环境变量 | socks4、socks4a、socks5、socks5h | http_proxy 只能小写。 |
| wget | /etc/wgetrc、~/.wgetrc、环境变量 | 手册未说明 | 用户名和密码通过 proxy_user 和 proxy_password 设置。 |
| git | git config http.proxy | 支持,curl 语法 | 未配置时读取 http_proxy、https_proxy 和 all_proxy。 |
| pip, npm | --proxy、pip.conf;npm config proxy 和 https-proxy | 面向 HTTP 代理 | 两者都识别 HTTP(S)_PROXY 变量。 |
| snapd | snap set system proxy.http 和 proxy.https | 文档未说明 | snapd 以服务方式运行,看不到终端里 export 的变量。 |
| Docker daemon | /etc/docker/daemon.json,proxies 键 | HTTP/HTTPS 代理 | 与客户端分开:容器的代理由 ~/.docker/config.json 设置。 |
2026 年 9 月 25 日根据官方文档和项目源码核对。“未说明”表示手册中没有提到 SOCKS 支持,并不代表所有版本都一定不支持。
适用于 Ubuntu、Debian 和 Fedora 的 GNOME 桌面。需要准备代理地址、端口,以及终端要用的用户名和密码(如有)。
打开“设置”并进入“网络”面板。最快的方式是打开“活动”概览后直接输入“网络”。
打开“网络代理”。根据 GNOME 版本不同,它在左侧列表中,或者从“网络”面板中以单独窗口打开。
选择“手动”模式。“自动”模式用于 PAC 文件:在其中填写配置文件的 URL。
如果是 HTTP 代理,把主机和端口填入“HTTP 代理”和“HTTPS 代理”(HTTP Proxy、HTTPS Proxy)字段;如果是 SOCKS5,填入 SOCKS 字段(SOCKS Proxy)。界面中没有用户名和密码字段,所以带认证的代理更适合通过环境变量、程序配置文件或代理客户端接入。
检查“忽略的主机”列表(Ignored Hosts)。GNOME 的默认配置中包含 localhost、127.0.0.0/8 和 ::1。如有需要,添加本地地址和公司内部域名。
保存更改:新版 GNOME 的代理窗口中有“保存”(Save)按钮,旧版修改后立即生效。启动 Chromium 或 Chrome,在任意 IP 查询网站上检查出口 IP。
为终端设置 http_proxy 和 https_proxy 变量(示例见环境变量一节):curl、git 和 apt 读取的是这些变量或各自的配置文件,而不是 gsettings。
在终端中用 curl 访问 IP 查询网站进行检查。如果浏览器显示代理 IP,终端显示的却是真实 IP,说明当前会话没有设置环境变量。
环境变量、apt.conf 或 proxychains 只负责转发流量。网站如何看待你,取决于出口处的代理。 Linux 上跑的通常是数据采集程序、机器人和自动化任务,而它们最常因为机房 IP 被封而受阻。