【发布时间】:2020-08-18 18:23:45
【问题描述】:
要构建某个图像,我需要创建一个隧道并让 docker 将此隧道用作 socks5 代理(也可以将代理用于 DNS)。
所以现在我有几个问题:
- 如何让 docker 使用主机上的代理?
- 如何让docker使用代理获取基础镜像?
- 如何让 docker 使用代理来执行 RUN 指令?
- 如何让 docker 使用代理进行 ADD 指令?
【问题讨论】:
标签: docker proxy dns socks tunnel
要构建某个图像,我需要创建一个隧道并让 docker 将此隧道用作 socks5 代理(也可以将代理用于 DNS)。
所以现在我有几个问题:
【问题讨论】:
标签: docker proxy dns socks tunnel
因为我花了一整天的时间研究这个,这里是答案。
我将在下面留下部分不完整/错误/旧的答案,因为我今天设置了一个新系统并且需要再次找出所有问题,因为旧答案的某些部分不再有意义。
使用localhost:port 不起作用。在解决this 问题之前,您需要使用 docker0 网络接口的 IP 地址(在我的情况下为172.17.0.1)。如果您的主机操作系统是 linux,您可以通过将额外的 --network=host 参数传递给 docker build 来使用 localhost:port,如其他答案中所述。
也适用于 3.。只需将这个内容(如果需要更改IP和端口)放入~/.docker/config.json(注意协议是socks5h)
{
"proxies":
{
"default":
{
"httpProxy": "socks5h://172.17.0.1:3128",
// or "httpProxy": "socks5h://localhost:3128", with --network=host
"httpsProxy": "socks5h://172.17.0.1:3128",
"noProxy": ""
}
}
}
ADD命令是用宿主机的(代理)环境变量执行的,忽略了config.json中的那些。更复杂的是,由于守护进程通常与root 用户一起运行,因此只获取root 用户的环境变量。更复杂的是,主机当然需要使用 localhost 作为代理主机。最重要的是:无论出于何种原因,在这种情况下,协议都需要为socks5(最后缺少h)。就我而言,由于我切换到 WSL2 并在 WSL2 中使用 docker(手动启动 dockerd docker 守护程序),我只需在调用 dockerd 之前导出所需的环境变量:
#!/bin/bash
DOCKER_DIR=~/sys/docker
DOCKER_SOCK="$DOCKER_DIR/docker.sock"
# unset any proxy env vars that the regular user might have set
# because we pass the environment variables with sudo -E
unset http_proxy
unset https_proxy
unset no_proxy
unset HTTP_PROXY
unset HTTPS_PROXY
unset NO_PROXY
# only this env var is needed for ADD in Dockerfile
export http_proxy=socks5://localhost:3128
export DOCKER_HOST="unix://$DOCKER_SOCK"
if [ ! -S "$DOCKER_SOCK" ]; then
mkdir -pm o=,ug=rwx "$DOCKER_DIR"
chgrp docker "$DOCKER_DIR"
sh -c "nohup sudo -E -b dockerd < /dev/null > $DOCKER_DIR/dockerd.log 2>&1"
fi
如果您在 linux 机器上进行了“常规”设置,则可以使用 4. 的旧答案,但请注意您可能还需要使用 localhost。
从这里开始的不完整/错误/旧答案
~/.docker/config.json(注意协议是socks5h) {
"proxies":
{
"default":
{
"httpProxy": "socks5h://172.17.0.1:3128",
"httpsProxy": "socks5h://172.17.0.1:3128",
"noProxy": ""
}
}
}
/etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=socks5://172.17.0.1:3128/"
然后
sudo systemctl daemon-reload
sudo systemctl restart docker
(这只是错误/不需要答案 2。)此外,对于像 yum 这样的包管理器能够在构建期间更新包,您需要像这样传递环境变量:
docker build --build-arg http_proxy=socks5://172.17.0.1:3128
【讨论】:
为了在本地连接一个容器到socks5,也就是整个互联网都去一个代理,容器必须能访问机器主机。
要在 Linux 中访问机器托管,您必须: 将 --network="host" 放入运行命令:
docker run --name test --network="host" --env http_proxy="socks5://127.0.0.1:1080" --env https_proxy="127.0.0.1:1080" nginx sh - c "curl ifconfig.io"
对于 mac 和 windows 用户,我们使用 host.local.internal:local_port:
docker run --name test --env http_proxy="socks5://host.local.internal:1080" --env https_proxy="socks5://host.local.internal:1080" nginx sh -c "curl ifconfig.io"
【讨论】:
sudo iptables -t nat -N REDSOCKS
sudo iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN
sudo iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 5000
sudo iptables -t nat -A REDSOCKS -d 172.17.0.0/12 -j RETURN
sudo iptables -t nat -A OUTPUT -p tcp -o docker0 -j REDSOCKS
sudo iptables -t nat -A PREROUTING -p tcp -i docker0 -j REDSOCKS
【讨论】:
使用 localhost:port 通过在“docker build ...”命令中添加“--network=host”选项来工作。
【讨论】: