下面这份可以直接作为你的部署文档使用。
1. 场景说明
当前部署结构:
宿主机 Linux
├── mihomo
│ └── SOCKS5 端口:11008
│
└── Docker
└── sub2api 容器
└── 需要通过 mihomo 代理访问外部网络
由于 sub2api 运行在 Docker 容器中,容器内的:
127.0.0.1
指的是 sub2api 容器自己,不是宿主机。
所以不能在 sub2api 中配置:
socks5h://127.0.0.1:11008
需要使用 Docker 容器访问宿主机的网关 IP。
2. 确认 mihomo 端口在宿主机可用
在宿主机执行:
curl --max-time 20 -x socks5h://127.0.0.1:11008 https://ipinfo.io/json
如果能返回出口 IP,说明 mihomo 本机代理正常。
3. 修改 mihomo 监听配置
mihomo 需要允许 Docker 容器访问,所以不能只监听 127.0.0.1。
检查监听状态:
ss -lntp | grep 11008
理想结果类似:
LISTEN 0 4096 *:11008 *:* users:(("mihomo",pid=xxx,fd=xx))
如果看到的是:
127.0.0.1:11008
说明只允许宿主机本机访问,Docker 容器访问不到。
mihomo 配置中建议设置:
allow-lan: true
bind-address: "*"
如果使用的是 listeners 多端口配置,11008 监听建议类似:
listeners:
- name: socks-11008
type: socks
port: 11008
listen: 0.0.0.0
修改后重启 mihomo:
sudo systemctl restart mihomo
再次检查:
ss -lntp | grep 11008
4. 查看 sub2api 容器的宿主机网关 IP
进入 sub2api 所在服务器,执行:
docker exec -it sub2api sh -c "ip route"
示例结果:
default via 172.18.0.1 dev eth0
172.18.0.0/16 dev eth0 scope link src 172.18.0.4
其中:
172.18.0.1
就是当前 sub2api 容器访问宿主机的网关 IP。
也可以直接提取:
docker exec -it sub2api sh -c "ip route | awk '/default/ {print \$3}'"
5. 在 sub2api 容器内测试 mihomo
根据上一步拿到的网关 IP 测试:
docker exec -it sub2api curl -v --max-time 20 \
-x socks5h://172.18.0.1:11008 \
https://ipinfo.io/json
如果能返回出口 IP,说明:
sub2api 容器 -> 宿主机 mihomo -> 外部网络
链路已经打通。
6. 如果容器访问超时,放行 Docker 网段
如果宿主机本地测试正常,但容器里访问超时,可以放行 Docker 自定义网络访问 mihomo 端口。
当前 sub2api 网段是:
172.18.0.0/16
临时放行:
sudo iptables -I INPUT 1 -s 172.18.0.0/16 -p tcp --dport 11008 -j ACCEPT
再次测试:
docker exec -it sub2api curl -v --max-time 20 \
-x socks5h://172.18.0.1:11008 \
https://ipinfo.io/json
如果服务器使用 UFW,可以持久化放行:
sudo ufw allow from 172.18.0.0/16 to any port 11008 proto tcp
查看规则:
sudo ufw status verbose
7. sub2api 中配置代理地址
在 sub2api 后台或环境变量中,将代理地址设置为:
socks5h://172.18.0.1:11008
不要使用:
socks5h://127.0.0.1:11008
也不建议继续使用:
socks5h://host.docker.internal:11008
因为当前 sub2api 在 Docker 自定义网络中,实际可用的宿主机网关是:
172.18.0.1
8. 如果通过 docker-compose 配置
进入部署目录:
cd /opt/sub2api-deploy
如果代理地址写在 .env 中,可配置为:
PROXY_URL=socks5h://172.18.0.1:11008
如果写在 docker-compose.yml 中,可配置为:
services:
sub2api:
environment:
PROXY_URL: socks5h://172.18.0.1:11008
修改后重启 sub2api:
docker compose restart sub2api
查看日志:
docker logs -f sub2api
9. 最终验证命令
宿主机测试 mihomo:
curl --max-time 20 -x socks5h://127.0.0.1:11008 https://ipinfo.io/json
容器内测试 mihomo:
docker exec -it sub2api curl --max-time 20 \
-x socks5h://172.18.0.1:11008 \
https://ipinfo.io/json
sub2api 中最终使用的代理地址:
socks5h://172.18.0.1:11008
10. 常见错误说明
错误一:connection refused
dial tcp 127.0.0.1:11008: connect: connection refused
原因:在 Docker 容器中使用了 127.0.0.1,它指向容器自己,不是宿主机。
解决:
改为 socks5h://172.18.0.1:11008
错误二:no such host
lookup host.docker.internal: no such host
原因:Linux Docker 默认不一定支持 host.docker.internal。
解决:不用这个域名,直接使用容器网关 IP:
socks5h://172.18.0.1:11008
错误三:connection timed out
Connection timed out
原因通常是 mihomo 没有监听 0.0.0.0,或者宿主机防火墙拦截了 Docker 网段访问。
解决:
sudo iptables -I INPUT 1 -s 172.18.0.0/16 -p tcp --dport 11008 -j ACCEPT
并确保 mihomo 监听:
*:11008
结论
在当前部署环境中,sub2api 走 mihomo 的最终可用配置是:
socks5h://172.18.0.1:11008
核心原因是:
sub2api 在 Docker 自定义网络中
宿主机 mihomo 在容器外运行
容器需要通过 Docker 网关 IP 访问宿主机代理端口