no_proxy 是 Linux 环境中用于控制代理例外规则的重要环境变量。当系统配置了 http_proxy、https_proxy 等代理后,并不是所有网络请求都应该经过代理服务器,例如访问本机服务、内网地址、企业内部域名或特定 IP 时,通常需要绕过代理。此时就需要合理配置 no_proxy。
一、no_proxy环境变量的作用
Linux 中常见的代理环境变量包括:
Bashhttp_proxy=http://192.168.1.100:8080 https_proxy=http://192.168.1.100:8080 ftp_proxy=http://192.168.1.100:8080 no_proxy=localhost,127.0.0.1
其中,http_proxy 和 https_proxy 用于指定网络请求使用的代理服务器,而 no_proxy 用来声明不经过代理的地址。
例如:
Bashexport http_proxy=http://192.168.1.100:8080 export https_proxy=http://192.168.1.100:8080 export no_proxy=localhost,127.0.0.1
配置完成后,访问 localhost 或 127.0.0.1 的请求通常会直接连接目标地址,而不会通过代理服务器。
需要注意的是,no_proxy 并不是 Linux 内核提供的统一网络功能,而是一种被大量命令行工具、网络库和应用程序采用的约定。不同软件对其格式和匹配规则的支持可能存在差异。
二、临时配置no_proxy
如果只希望当前终端会话使用代理例外规则,可以直接执行:
Bashexport no_proxy=localhost,127.0.0.1
也可以同时配置常见的本地主机地址:
Bashexport no_proxy=localhost,127.0.0.1,::1
这里的 ::1 是 IPv6 环回地址。
查看当前配置:
Bashecho $no_proxy
或者:
Bashprintenv no_proxy
如果输出:
localhost,127.0.0.1,::1
说明当前 Shell 中已经设置了该变量。
三、配置多个域名和IP地址
实际服务器环境中,no_proxy 往往需要配置多个地址。例如某台服务器既需要访问本地服务,也需要访问企业内部网络:
Bashexport no_proxy=localhost,127.0.0.1,::1,192.168.1.0/24,.example.com
这里需要特别注意:CIDR 网段是否有效取决于具体应用程序的实现。虽然部分程序支持 192.168.1.0/24 这样的写法,但并不能认为所有 Linux 网络工具都会按照 CIDR 规则处理。
因此,如果需要最大程度提高兼容性,可以明确列出需要绕过代理的主机名或 IP。
例如:
Bashexport no_proxy=localhost,127.0.0.1,192.168.1.10,192.168.1.20
对于内部域名,也可以写成:
Bashexport no_proxy=localhost,127.0.0.1,.example.com
前面的点通常用于表示该域及其子域,例如:
api.example.com git.example.com registry.example.com
是否能够按照预期匹配,同样取决于具体程序的实现。
四、同时设置大写和小写变量
Linux 环境中的代理变量经常出现大小写并存的情况,例如:
BashHTTP_PROXY HTTPS_PROXY NO_PROXY
以及:
Bashhttp_proxy https_proxy no_proxy
不同程序对变量名称的支持并不完全一致,因此在服务器环境中,为了减少兼容性问题,可以同时设置大小写形式:
Bashexport http_proxy=http://192.168.1.100:8080 export https_proxy=http://192.168.1.100:8080 export HTTP_PROXY=http://192.168.1.100:8080 export HTTPS_PROXY=http://192.168.1.100:8080 export no_proxy=localhost,127.0.0.1,::1 export NO_PROXY=localhost,127.0.0.1,::1
不过,大写和小写变量同时存在时,如果两者内容不同,就可能导致不同程序出现不同的代理行为。因此建议保持两套变量的值一致。
五、让no_proxy永久生效
直接使用 export 设置的变量只对当前 Shell 会话有效,关闭终端后配置通常就会消失。
如果希望登录后自动生效,可以根据使用的 Shell 修改对应配置文件。
Bash 用户通常可以编辑:
Bash~/.bashrc
添加:
Bashexport no_proxy=localhost,127.0.0.1,::1,.example.com export NO_PROXY=localhost,127.0.0.1,::1,.example.com
保存后执行:
Bashsource ~/.bashrc
也可以重新打开终端。
如果配置用于登录环境,则可以根据系统和 Shell 情况考虑:
Bash~/.profile
或者系统级配置:
Bash/etc/profile
企业服务器上修改 /etc/profile 前需要谨慎,因为它会影响多个用户。
六、验证no_proxy是否配置成功
仅仅执行 echo $no_proxy,只能证明环境变量存在,并不能证明应用程序真的按照预期绕过代理。
更可靠的验证方式是结合实际网络请求进行测试。
首先查看环境变量:
Bashenv | grep -i proxy
例如:
http_proxy=http://192.168.1.100:8080 https_proxy=http://192.168.1.100:8080 no_proxy=localhost,127.0.0.1,::1
然后使用 curl 测试:
Bashcurl -v http://localhost:8080
观察输出中的连接过程。
也可以直接指定一个临时代理环境进行验证:
Bashhttp_proxy=http://192.168.1.100:8080 https_proxy=http://192.168.1.100:8080 no_proxy=localhost curl -v http://localhost:8080
如果 curl 根据 no_proxy 规则直接连接 localhost,通常可以从详细输出中看到相关信息。
七、使用curl检查代理是否被绕过
curl 是排查代理环境非常实用的工具。
例如:
Bashcurl -v http://example.com
如果请求经过 HTTP 代理,通常可以在详细输出中看到类似:
Uses proxy env variable http_proxy
而配置:
Bashexport no_proxy=example.com
之后再次执行:
Bashcurl -v http://example.com
如果 curl 不再使用之前配置的代理,说明当前 curl 已识别对应的 no_proxy 规则。
也可以通过 --noproxy 临时指定绕过规则:
Bashcurl --noproxy example.com https://example.com
这种方式适合排查问题,因为它不会修改当前 Shell 的环境变量。
如果希望让 curl 完全忽略代理环境变量,可以使用:
Bashcurl --noproxy '*' https://example.com
这对于判断“问题来自代理还是目标服务器”非常有帮助。
八、no_proxy中常见的配置内容
实际工作中,下面这些地址经常需要加入 no_proxy:
Bashlocalhost 127.0.0.1 ::1
例如:
Bashexport no_proxy=localhost,127.0.0.1,::1
如果服务器存在内部服务,还可以加入:
Bashexport no_proxy=localhost,127.0.0.1,::1,192.168.1.10,192.168.1.20
对于企业内部域名,可以根据应用支持情况配置:
Bashexport no_proxy=localhost,127.0.0.1,.corp.example.com
如果同时存在 Kubernetes、Docker 或其他内部服务,则可能还需要针对实际访问地址进行配置。例如:
Bashexport no_proxy=localhost,127.0.0.1,::1,.svc,.cluster.local
不过,这类配置不能直接套用到所有环境,应根据实际 DNS、服务发现机制以及客户端实现进行调整。
九、no_proxy配置不生效的常见原因
1. 环境变量名称不兼容
某些程序只读取大写:
BashNO_PROXY
另一些程序可能读取:
Bashno_proxy
遇到程序行为异常时,可以检查:
Bashenv | grep -i proxy
必要时同时配置大小写版本。
2. no_proxy格式不符合程序要求
例如:
Bashno_proxy=.example.com
和:
Bashno_proxy=example.com
在不同软件中的匹配行为可能不同。
因此,如果某个域名始终无法绕过代理,建议先直接写完整主机名进行测试:
Bashexport no_proxy=api.example.com
确认成功后,再逐步缩减规则。
3. 代理变量与no_proxy内容冲突
检查:
Bashenv | grep -i proxy
如果发现:
HTTP_PROXY=... http_proxy=... NO_PROXY=... no_proxy=...
但大小写变量的内容并不一致,就可能产生难以定位的问题。
建议统一配置:
Bashexport HTTP_PROXY=http://192.168.1.100:8080 export HTTPS_PROXY=http://192.168.1.100:8080 export NO_PROXY=localhost,127.0.0.1,::1
同时根据具体软件需要补充小写形式。
4. 应用程序根本不读取no_proxy
no_proxy 是通用约定,并非所有程序都会实现。
例如某个应用可能使用自己的代理配置文件、命令行参数或配置项,即使 Shell 中存在:
Bashno_proxy=localhost
它也不一定会自动遵守。
因此,排查问题时不能只检查环境变量,还要确认具体应用的代理机制。
十、如何清除no_proxy配置
临时取消当前 Shell 中的 no_proxy:
Bashunset no_proxy
如果同时设置了大写变量:
Bashunset NO_PROXY
检查:
Bashecho "$no_proxy" echo "$NO_PROXY"
如果没有输出,说明对应变量已经被取消。
如果重新打开终端后变量又出现,则需要检查:
Bash~/.bashrc ~/.profile /etc/profile /etc/environment
以及其他 Shell 初始化文件,找到相关配置并删除或修改。
十一、Docker和容器环境中的no_proxy
容器环境是 no_proxy 使用频率较高的场景。
例如启动容器时可以通过:
Bashdocker run -e HTTP_PROXY=http://192.168.1.100:8080 -e HTTPS_PROXY=http://192.168.1.100:8080 -e NO_PROXY=localhost,127.0.0.1,::1 my-image
进入容器后检查:
Bashenv | grep -i proxy
需要注意,容器中的 localhost 指向的是容器自身,并不是宿主机。因此:
BashNO_PROXY=localhost
并不能自动表示“访问宿主机时绕过代理”。
如果容器需要访问宿主机服务,应根据实际网络模式和宿主机访问地址配置对应规则。
十二、Git、wget等工具中的代理验证
Git 可能同时存在环境变量代理和 Git 自身配置。
查看 Git 代理配置:
Bashgit config --global --get http.proxy git config --global --get https.proxy
如果 Git 自己设置了代理,即使调整了 no_proxy,也可能仍然出现与预期不同的行为。因此排查 Git 网络问题时,需要同时检查环境变量和 Git 配置。
wget 同样可能读取代理环境变量。可以先检查:
Bashenv | grep -i proxy
然后结合实际 URL 测试。
对于复杂环境,最好分别测试:
Bashcurl wget git
因为不同客户端使用的网络库和代理实现并不完全相同。
十三、推荐的no_proxy配置思路
生产服务器上不建议简单地配置一个非常宽泛的规则,例如:
Bashno_proxy=*
虽然这种方式可以让大量请求绕过代理,但也可能绕过企业统一出口、访问控制、审计或安全策略。
更合理的方式是只添加确实需要绕过代理的地址:
Bashexport no_proxy=localhost,127.0.0.1,::1,internal.example.com
如果需要添加多个内部服务,可以根据实际访问情况逐步扩展:
Bashexport no_proxy=localhost,127.0.0.1,::1,api.internal.example.com,registry.internal.example.com
配置完成后,再使用实际客户端验证。
十四、排查no_proxy问题的完整流程
遇到“配置了 no_proxy 但请求仍然走代理”的问题,可以按照以下顺序排查:
首先查看代理环境变量:
Bashenv | grep -i proxy
然后确认目标地址:
Bashecho $no_proxy
检查大小写变量:
Bashecho "$no_proxy" echo "$NO_PROXY"
接着使用 curl -v 进行实际测试:
Bashcurl -v http://目标地址
如果仍然使用代理,可以暂时绕过代理:
Bashcurl --noproxy '*' -v http://目标地址
如果 --noproxy '*' 可以正常访问,而普通请求无法访问,那么问题很可能集中在代理配置或 no_proxy 匹配规则上。
随后可以进一步检查目标域名解析:
Bashgetent hosts example.com
确认访问的到底是哪个地址,并将实际需要绕过代理的主机名或 IP 加入 no_proxy。
最后,再确认具体应用是否支持 no_proxy,以及它是否存在自己的代理配置。
十五、配置no_proxy时的注意事项
no_proxy 看似只是一个简单的逗号分隔字符串,但在实际服务器环境中,它涉及 Shell、应用程序、网络库和代理服务器多个层面。
配置时建议注意以下几点:
-
使用逗号分隔多个目标,不要随意使用空格。
-
同时检查
no_proxy和NO_PROXY是否存在。 -
不要默认认为所有程序都支持 CIDR。
-
不要默认认为所有程序对
.example.com的匹配方式完全一致。 -
修改永久配置后,需要重新加载 Shell 环境。
-
容器中的
localhost与宿主机的localhost含义不同。 -
排查问题时优先使用
curl -v查看实际连接行为。 -
不要为了省事使用
no_proxy=*,除非明确知道这样做的影响。 -
Git 等软件可能拥有独立的代理配置,需要单独检查。
-
生产环境修改代理规则前,应确认是否会影响安全审计和网络访问策略。
合理配置 no_proxy 的关键并不是简单地把一批地址写进去,而是明确哪些请求应该经过代理、哪些请求必须直接连接,再结合具体客户端的匹配规则进行验证。对于 Linux 服务器而言,env | grep -i proxy 可以用于快速检查环境,curl -v 则适合进一步确认请求是否真正绕过代理。通过“检查环境变量—确认匹配规则—实际网络测试—检查应用独立配置”的方式排查,通常能够较快定位 no_proxy 不生效的问题。