浏览器能打开内网页面,只能说明代理对浏览器有效,并不代表 npm 或 Maven 也能用。每个客户端读取各自的配置,而只能经 VPN 访问的网络还带来第二个问题:客户端能否到达代理。先看状态码,再顺着失败工具自身的配置链排查。这也是同一网段里一个客户端能用、隔壁却失败的原因。

407 到底说明了什么

407 Proxy Authentication Required 来自代理,而不是注册表或仓库。客户端已经到达代理,代理拒绝了请求,通常是因为凭据缺失、格式错误,或对该目标不被接受。

超时讲的是另一件事:代理地址错误、隧道建立前没有到代理的路由,或缺少内网主机的绕过项。先读错误文本,再改凭据。

确认代理主机、端口、认证方式,以及用户名是否需要域前缀。然后看失败的工具有没有从文件、环境变量或两者读取该值。带域的用户名是 407 的常见原因,用错误编码保存的密码也一样。

npm 读取自己的配置链

npm 在用户或项目的 .npmrc 中接受 proxy 与 https-proxy 键。值本身是 URL,所以必须写协议;密码里的保留字符要做 URL 编码,否则 at 符号会把值截断。

proxy=http://proxy.example.com:8080
https-proxy=http://proxy.example.com:8080
strict-ssl=true

用 npm config list 可以看出每个生效值来自哪个文件。像 npm_config_proxy 这样的 shell 导出可能覆盖文件,而带个人密码的项目级 .npmrc 绝不应提交。打印值时一并打印来源路径。

让 strict-ssl 保持开启。检查 TLS 的代理可能要求把 企业 CA 放进信任库;为了绕开报错而关掉校验,只会掩盖真正的信任问题。

Maven 把代理和镜像分开

Maven 从用户 settings 文件读取代理与镜像,而不是项目 pom。网络相关的代理和内部仓库镜像放在 ~/.m2/settings.xml,公开仓库声明留在项目里。

代理块需要 id、启用标志、协议、主机和端口,以及给内部仓库的 nonProxyHosts 条目。这些字段放在用户文件而不是 pom,网络变化才不会改写整个团队的构建。

把内部仓库加入 nonProxyHosts,让 Maven 直连。没有这条,代理就成了多余的跳点,故障看起来像仓库中断。镜像条目指向内部仓库,并不替代代理设置。

经常换网络的人可以为每个网络各留一份 settings,在 shell 启动时选择正确副本。每次搬迁都手改同一个文件,只会把能用的笔记本变成支持工单。

VS Code 与 dev 容器的命名空间不同

VS Code 从用户或工作区设置读取 http.proxy,包括协议和端口。这只覆盖编辑器自身对扩展与市场的请求,并不会自动配置终端或从编辑器启动的容器。既要看取值,也要看设置作用域。工作区设置可以覆盖某个项目的用户设置。

dev 容器有自己的网络命名空间,不继承宿主机的代理变量与 VPN 路由,所以 容器内的 marketplace 调用可能失败,而同样的调用在宿主机上正常。

把变量交给容器,或给它独立的解析器与路由。如果容器内能解析名称但代理始终不响应,缺的通常是路由而不是地址。

绕过列表与环境优先级

把 VPN 网关、内部仓库和私有 DNS 后缀加入绕过列表。如果在隧道建立前就经代理访问网关,连接会失败得像代理宕机。请在没有隧道时测试这一项。

环境变量与文件可能互相矛盾。要跑工具自己的配置导出,而不是 shell 的,并比较它报告的取值。小写重复变量、父 shell 中的旧值或项目文件,都可能压过刚改过的设置。

在 CI 里把代理作为密钥变量传入,并在同一个镜像里测一次装包。容器内的 407 往往说明该变量根本没传进去,而宿主机 shell 里是有的。

为每个工具记下代理主机、端口、绕过后缀,以及提供它们的文件或变量。当一个客户端返回 407 而另一个正常时,这份记录能把四份不同配置的对比变成一次短检查。

相关文章