用 Docker 隔离 EasyConnect 并配置内网流量转发
公司内网一般都会用到 EasyConnect,比如访问代码仓库、测试环境、数据库、内部管理后台之类的。
但我不太喜欢直接把 EasyConnect 装在宿主机上。原因很简单:这类 VPN 客户端经常会接管系统网络环境,路由、代理、DNS 都可能被它影响。尤其是 macOS 上,本来就已经有 Clash / Mihomo / Surge 这类代理工具了,再叠一个 EasyConnect,网络问题排查起来会很麻烦,并且 EasyConnect 安装到电脑很难卸载干净,会残留很多内容。
所以我的思路是:把 EasyConnect 丢到 Docker 里隔离起来,只把它提供出来的 SOCKS5 / HTTP 代理暴露给宿主机使用。
这样处理之后,整体会清爽很多:
- EasyConnect 只运行在容器里,不直接污染宿主机网络;
- 宿主机按需走代理,不需要所有流量都进 VPN;
- 浏览器、Git、SSH 可以分别配置,哪里需要内网就配置哪里;
- 容器目录挂出来之后,登录状态和配置可以持久化;
- 还可以继续配合 Clash / Mihomo 这类代理客户端做规则分流。
启动 EasyConnect 容器
先给一个 docker run 版本,适合临时测试。跑通之后,后面再改成 Docker Compose,日常使用会更方便。
使用 hagb/docker-easyconnect 镜像启动容器:
bashdocker run \ --name app-easyconnect \ --device /dev/net/tun \ --cap-add NET_ADMIN \ --privileged \ -ti \ -e PASSWORD=xxxx \ -e URLWIN=1 \ -e DISABLE_PKG_VERSION_XML=1 \ -v /Users/wangwenpeng/docker/app/easy-connect:/root \ -p 127.0.0.1:5901:5901 \ -p 127.0.0.1:1080:1080 \ -p 127.0.0.1:8888:8888 \ hagb/docker-easyconnect:7.6.7
关键参数说明如下:
| 参数 | 作用 |
|---|---|
--name app-easyconnect |
指定容器名称,便于后续管理 |
--device /dev/net/tun |
挂载 TUN 设备,VPN 隧道需要使用 |
--cap-add NET_ADMIN |
允许容器修改网络配置 |
--privileged |
启用特权模式,减少 VPN 客户端的权限问题 |
-e PASSWORD=xxxx |
设置 VNC 连接密码 |
-e URLWIN=1 |
启用窗口模式,方便操作图形界面 |
-e DISABLE_PKG_VERSION_XML=1 |
禁用包版本检查,部分 ARM64 环境需要 |
-v /path:/root |
持久化 EasyConnect 配置和登录数据 |
-p 127.0.0.1:5901:5901 |
暴露 VNC 端口 |
-p 127.0.0.1:1080:1080 |
暴露 SOCKS5 代理端口 |
-p 127.0.0.1:8888:8888 |
暴露 HTTP 代理端口 |
这里的端口都绑定到了 127.0.0.1,也就是只允许本机访问。除非你明确想让局域网里的其他设备也用这个代理,否则不建议绑定到 0.0.0.0。
注意,Docker 的特权模式参数是:
bash--privileged
不要写成:
bash-privileged
容器启动后,可以用 VNC 客户端连接:
text127.0.0.1:5901
密码就是启动容器时的 PASSWORD。登录 EasyConnect 成功后,宿主机可以通过以下代理端口访问内网:
textSOCKS5: 127.0.0.1:1080 HTTP: 127.0.0.1:8888
使用 Docker Compose 管理
如果只是验证一下,docker run 没问题。但这个容器后面大概率会反复启动、停止,甚至需要换机器复用配置,所以我更推荐把它写成 docker-compose.yml。
可以新建一个目录,例如:
bashmkdir -p ~/docker/app/easy-connect
cd ~/docker/app/easy-connect然后创建 docker-compose.yml:
yamlservices:
easyconnect:
image: hagb/docker-easyconnect:7.6.7
container_name: app-easyconnect
privileged: true
tty: true
stdin_open: true
devices:
- /dev/net/tun:/dev/net/tun
cap_add:
- NET_ADMIN
environment:
PASSWORD: xxxx
URLWIN: "1"
DISABLE_PKG_VERSION_XML: "1"
volumes:
- ./data:/root
ports:
- "127.0.0.1:5901:5901"
- "127.0.0.1:1080:1080"
- "127.0.0.1:8888:8888"
restart: unless-stopped启动:
bashdocker compose up -d
查看日志:
bashdocker compose logs -f
停止:
bashdocker compose down
如果只是想停止容器但保留状态,也可以用:
bashdocker compose stop
再次启动:
bashdocker compose start
这里有几个点需要注意。
数据持久化目录
yamlvolumes:
- ./data:/root这个目录用来保存 EasyConnect 的配置和登录状态。后面只要 ./data 不删,重新创建容器一般也不用从零开始配置。
端口只绑定本机
yamlports:
- "127.0.0.1:5901:5901"
- "127.0.0.1:1080:1080"
- "127.0.0.1:8888:8888"这样做是为了避免把 VNC、SOCKS5、HTTP 代理暴露到局域网。尤其是 VNC 端口,不建议开放给其他机器访问。
环境变量最好加引号
yamlURLWIN: "1"
DISABLE_PKG_VERSION_XML: "1"YAML 对数字、布尔值有自己的解析规则。虽然这里不加引号大概率也能跑,但我习惯把这类环境变量写成字符串,避免不必要的问题。
restart 策略
yamlrestart: unless-stopped这个配置表示 Docker 重启后自动拉起容器,但如果你手动 docker compose stop 了,它就不会强行再启动。
日常用起来基本就是:
bash# 第一次启动 / 修改配置后启动
docker compose up -d
# 临时停用
docker compose stop
# 再次使用
docker compose start配置代理客户端规则
容器只是把 EasyConnect 的代理端口暴露出来了,至于哪些流量要走它,最好还是交给代理客户端做规则分流。
如果本机使用 Clash、Clash Verge、Mihomo Party 等代理客户端,可以通过全局扩展脚本添加一个 EasyConnect 代理节点,然后只让指定内网网段走这个节点。
示例脚本:
jsfunction main(config, profileName) {
// 添加 EasyConnect 代理
config.proxies.push({
name: 'ec',
type: 'socks5',
server: '127.0.0.1',
port: 1080,
udp: true
});
// 添加内网规则
config.rules.unshift(
"IP-CIDR,10.193.108.0/24,ec"
);
return config;
}这里新增了一个名为 ec 的 SOCKS5 节点:
js{
name: 'ec',
type: 'socks5',
server: '127.0.0.1',
port: 1080,
udp: true
}其中:
name:代理节点名称,可以自定义;type:代理类型,这里是socks5;server:代理地址,本机访问 Docker 暴露端口,所以是127.0.0.1;port:EasyConnect 容器暴露的 SOCKS5 端口;udp:是否允许 UDP 转发。
内网规则如下:
jsconfig.rules.unshift(
"IP-CIDR,10.193.108.0/24,ec"
);含义是:访问 10.193.108.0/24 网段时,走名为 ec 的代理节点。
这里使用 unshift 是为了把规则插入到最前面。代理规则通常是从上到下匹配的,如果内网规则放得太靠后,可能会被前面的 DIRECT、REJECT 或其他规则提前命中。
这个地方一定要按自己的内网网段改,不要直接照抄。比如你的 GitLab、测试环境、数据库服务器都在不同网段,就需要把这些网段都加进去。
如果你的公司内网网段不同,按实际情况修改即可,例如:
jsconfig.rules.unshift(
"IP-CIDR,10.100.0.0/16,ec",
"IP-CIDR,172.16.0.0/12,ec"
);配置系统代理
如果只是浏览器访问内网后台,配置浏览器代理就够了。如果希望系统中的大部分应用都能通过代理访问内网,可以在 macOS 中配置 SOCKS 代理。
路径如下:
text系统设置 -> 网络 -> 当前网络 -> 详细信息 -> 代理
开启 SOCKS 代理,并填写地址和端口。
如果系统直接走 EasyConnect 容器:
text服务器:127.0.0.1 端口:1080
流量链路是:
text系统应用 -> 127.0.0.1:1080 -> EasyConnect Docker -> 公司内网
如果系统先走代理客户端,再由规则转发到 EasyConnect:
text服务器:127.0.0.1 端口:7897
流量链路是:
text系统应用 -> 127.0.0.1:7897 -> Clash / Mihomo -> ec 节点 -> EasyConnect Docker -> 公司内网
我更推荐第二种方式,因为它能通过规则控制哪些流量走 EasyConnect,哪些流量直连,哪些流量走其他代理,不容易把整个系统网络搞乱。
需要注意的是,macOS 代理设置中通常有一个“绕过代理设置”的列表。如果你希望某个内网地址走代理,需要确认这个地址或网段没有出现在绕过列表中。
例如,如果绕过列表里包含:
text10.0.0.0/8 192.168.0.0/16 *.local
访问 10.x.x.x 的请求可能会直接绕过代理,导致 EasyConnect 代理不生效。
SOCKS5 和 HTTP 代理的区别
EasyConnect Docker 同时暴露了 SOCKS5 和 HTTP 代理端口。一般情况下,我会优先使用 SOCKS5。
SOCKS5 是传输层代理:
- 不关心上层协议内容;
- 可以转发 TCP 流量;
- 部分场景支持 UDP;
- HTTP、HTTPS、FTP、SSH 等协议都可以通过 SOCKS5 转发。
HTTP 代理是应用层代理:
- 理解 HTTP 协议;
- 主要用于 HTTP / HTTPS 流量;
- HTTPS 通常通过
CONNECT方法建立隧道; - 不适合直接代理 SSH 等非 HTTP 协议。
所以对于 Git、SSH、数据库客户端等场景,SOCKS5 通常更合适。
配置 Git 走代理
系统代理不一定能覆盖到所有命令行工具,所以 Git 这里最好单独确认一下。
如果公司 Git 仓库使用 HTTP 协议,例如:
texthttp://10.100.108.110:8600/project/your-project.git
可以让 Git 通过 SOCKS5 代理访问。
先查看当前远程地址:
bashgit remote -v
如果当前是 SSH 地址,并且你不想折腾 SSH 代理,也可以直接改成 HTTP 地址:
bashgit remote set-url origin http://10.100.108.110:8600/project/your-project.git
再次验证:
bashgit remote -v
然后配置 Git 全局代理:
bashgit config --global http.proxy socks5://127.0.0.1:7897 git config --global https.proxy socks5://127.0.0.1:7897
这里的 7897 是本机代理客户端端口。如果你本机代理客户端不是这个端口,就改成自己的端口。
如果直接使用 EasyConnect 容器暴露的 SOCKS5 端口,可以改成:
bashgit config --global http.proxy socks5://127.0.0.1:1080 git config --global https.proxy socks5://127.0.0.1:1080
测试是否可用:
bashgit ls-remote origin
如果配置正确,会看到类似输出:
text92d4dd02b3698daef0054b450ae8cd6268d5723e HEAD c922d1de1a7fa6f6786505b11328a45eb0db7d23 refs/heads/dev 92d4dd02b3698daef0054b450ae8cd6268d5723e refs/heads/main
配置 SSH 走代理
如果你还是更习惯使用 SSH 格式的 Git 地址,例如:
textgit@10.193.100.100:gysk/project.git
那只配置系统代理通常是不够的。macOS 系统代理主要影响浏览器、curl 等 HTTP / HTTPS 流量,而 SSH 客户端通常不会自动使用系统代理。
所以这里需要单独配置 SSH 的 ProxyCommand。
编辑 SSH 配置文件:
bashtouch ~/.ssh/config
chmod 600 ~/.ssh/config添加配置:
sshconfigHost 10.193.108.* ProxyCommand nc -X 5 -x 127.0.0.1:7897 %h %p StrictHostKeyChecking ask SendEnv -LC_*
含义如下:
| 配置 | 作用 |
|---|---|
Host 10.193.108.* |
匹配所有 10.193.108.x 网段主机 |
ProxyCommand nc -X 5 -x 127.0.0.1:7897 %h %p |
通过 SOCKS5 代理连接目标主机 |
StrictHostKeyChecking ask |
首次连接时询问是否信任主机指纹 |
SendEnv -LC_* |
不发送 LC_ 开头的语言环境变量 |
如果直接走 EasyConnect 容器的 SOCKS5 端口,可以改成:
sshconfigProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
有些配置里会直接把主机密钥校验关掉:
sshconfigStrictHostKeyChecking no
这样确实省事,但安全性比较低。除非是明确可控的测试环境,否则我更推荐使用:
sshconfigStrictHostKeyChecking ask
可以用调试模式验证 SSH 是否走代理:
bashssh -v git@10.193.108.100
如果配置命中,会看到类似信息:
textExecuting proxy command: exec nc -X 5 -x 127.0.0.1:7897 ...
不方便配置代理的软件怎么办
有些软件本身不支持配置代理,比如部分数据库客户端、旧版本 Navicat 或内部工具。这类软件最麻烦,因为它既不看系统代理,也没有自己的代理入口。
可以考虑三种方式:
- 使用软件自带的 SSH Tunnel:适合数据库、Redis 等客户端;
- 使用系统代理:如果软件遵守 macOS 系统代理,则可以直接生效;
- 使用代理客户端的 TUN 模式:在网卡层面接管流量,兼容性更强,但也更接近全局代理,耗电和误伤正常网络的概率都会更高。
如果只是少量工具需要访问内网,优先尝试软件自带代理或 SSH Tunnel。只有在软件完全不支持代理时,再考虑 TUN 模式。
常见问题排查
Docker Compose 启动失败
先看日志:
bashdocker compose logs -f
如果是权限或网络设备相关问题,重点检查这几个配置是否还在:
yamlprivileged: true
devices:
- /dev/net/tun:/dev/net/tun
cap_add:
- NET_ADMIN如果是端口占用,换掉左边的宿主机端口即可,例如:
yamlports:
- "127.0.0.1:15901:5901"
- "127.0.0.1:11080:1080"
- "127.0.0.1:18888:8888"此时宿主机访问端口也要跟着改成 15901、11080、18888。
容器启动失败
检查 Docker 参数是否写错,尤其是:
bash--privileged
同时确认 Docker Desktop 是否正常运行。
VNC 连不上
检查容器是否运行:
bashdocker ps
检查端口映射:
bashdocker port app-easyconnect
如果使用 Docker Compose,也可以执行:
bashdocker compose ps
确认连接地址是:
text127.0.0.1:5901
代理连不上内网
先确认 EasyConnect 已经在容器中登录成功。
然后测试 SOCKS5 代理:
bashcurl --socks5 127.0.0.1:1080 http://10.193.108.10
如果通过代理客户端中转,则测试代理客户端端口:
bashcurl --socks5 127.0.0.1:7897 http://10.193.108.10
Git 仍然无法访问
检查 Git 代理配置:
bashgit config --global --get http.proxy git config --global --get https.proxy
检查远程地址:
bashgit remote -v
如果是 HTTP 地址,确认 Git 代理端口是否正确。如果是 SSH 地址,则检查 ~/.ssh/config 中的 ProxyCommand 是否匹配目标主机。
总结
通过 Docker / Docker Compose 运行 EasyConnect,可以把 VPN 客户端隔离在容器中,避免它直接影响宿主机网络环境。
整体流量链路可以设计为:
text应用程序 -> 本机 SOCKS5 / HTTP 代理 -> 代理客户端规则分流 -> EasyConnect Docker 容器 -> 公司内网
核心步骤是:
- 用
docker run快速验证 EasyConnect 容器是否能正常启动; - 跑通后改成 Docker Compose,方便后续启动、停止和迁移;
- 暴露
1080SOCKS5 代理端口和8888HTTP 代理端口; - 在代理客户端中添加 EasyConnect SOCKS5 节点;
- 使用规则让指定内网网段走 EasyConnect;
- 根据需要配置系统代理、Git 代理和 SSH 代理;
- 对不支持代理的软件,考虑 SSH Tunnel 或 TUN 模式。
这样既能访问公司内网,又能最大程度减少 EasyConnect 对本机网络环境的影响。