如何在 VS Code DevContainer 中配置 HTTP 代理

上回 我们讲了如何在跳板机背后的服务器上使用 VS Code Remote - Containers。DevContainer 中还有个棘手的问题是网络代理,本文将聊聊在 VS Code 中配置代理的问题,以及我目前的解决方案。

LOCALREMOTE SERVERHTTP://192.168.9.100:11451DOCKERVS CODE (CONTAINER)?
LOCALHTTP://127.0.0.1:1081VS CODE (LOCAL)

网络拓扑

上图描述了我目前使用 DevContainer 在远端开发时的环境,以及其与本地环境的对比。

  • 本地环境 在本地正常开发时,我会在本地启动一个代理服务,地址为 http://127.0.0.1:1081。通过在 VS Code 中设置 http.proxy 为该地址,即可让 VS Code 的所有网络请求经由该代理。
  • Remote 环境 在 Remote 使用 DevContainer 时,代理的地址变为了 http://192.168.9.100:11451 —— 这是集群内部提供的一个代理。此时该如何应对呢?

那么,在 VS Code 中能否为不同环境设置不同的代理地址呢?

尝试一:为不同环境设置不同 http.proxy 值(失败)

VS Code 的配置是层叠式的。打开设置页可以看到如下图所示的多层作用域:UserRemoteWorkspaceUser 下的设置会对所有环境生效,Remote 下的设置则只对 DevContainer 生效。作用域小的设置会覆盖作用域大的设置。Remote 中更改的某项设置会覆盖 User 中的原有项,以便用户对特定环境作更精准的配置。

如此一来,一个很自然的想法便是:保持 User 下的 http.proxy 为本地的 http://127.0.0.1:1081,再将 Remote 下的设置为 http://192.168.100:11451,以期在不同环境下使用不同的代理。

然而这样配置并没有达到预期效果。VS Code 会把所有网络请求都发往 http://192.168.100:11451,而不是根据当前环境选择代理。这其中包括了 DevContainer 内部的网络请求,也包括了本地与 DevContainer 间的通信——后者显然是不合理的。

LOCALHTTP://192.168.9.100:11451(BAD)REMOTE SERVERHTTP://192.168.9.100:11451DOCKERVS CODE (CONTAINER)?

既然如此,我们必须保持 http.proxy 始终为 http://127.0.0.1:1081,从而需要在 DevContainer 内部另架设一个转发代理,网络拓扑如下

LOCALREMOTE SERVERHTTP://192.168.9.100:11451DOCKERVS CODE(CONTAINER)HTTP://127.0.0.1:1081

尝试二:在 DevContainer 内部架设转发代理

我们选择 squid 作为 DevContainer 内部的转发代理。

安装 squid

首先在 Dockerfile 中安装 squid,并写入配置文件:

# 假设基础镜像为 ubuntu / debian
RUN apt-get install -y squid
RUN printf 'http_port 127.0.0.1:1082\ncache_peer 192.168.9.100 parent 11451 0 no-query proxy-only tls-flags=DONT_VERIFY_PEER\ncache deny all\nssl_bump peek all\nssl_bump bump all\nsslproxy_cert_error allow all\ntls_outgoing_options flags=DONT_VERIFY_PEER' >> /etc/squid/squid.conf

第二行的配置文件内容如下:

http_port 127.0.0.1:1081
cache_peer 192.168.9.100 parent 11451 0 no-query proxy-only tls-flags=DONT_VERIFY_PEER
cache deny all

ssl_bump peek all
ssl_bump bump all
sslproxy_cert_error allow all
tls_outgoing_options flags=DONT_VERIFY_PEER

其中前两行配置了 squid 的监听端口和上级代理。后面的 ssl_* 部分则开启了 SSL Bump 功能——这是必要的,否则 HTTPS 请求经由 squid 时会报 503 直接拒绝,困扰了我许久。

设置 squid 自启动

为了使 squid 服务在容器启动时自动启动,我们需要在 devcontainer.json 中添加如下配置:

{
// ...
"postStartCommand": "service squid restart"
}

如此一来,即使在 DevContainer 内也可以经由 http://127.0.0.1:1081 地址访问代理,与本地环境保持一致。Copilot 等工具也可以正常使用了。


作者:hsfzxjy
链接:
许可:CC BY-NC-ND 4.0.
著作权归作者所有。本文不允许被用作商业用途,非商业转载请注明出处。

OOPS!

A comment box should be right here...But it was gone due to network issues :-(If you want to leave comments, make sure you have access to disqus.com.