将传入的外部 DNS 数据包转发到嵌入式 docker DNS

将传入的外部 DNS 数据包转发到嵌入式 docker DNS

我在 docker 容器中运行 openvpn 服务。链接到此容器的是一些其他容器,包括一个 gitlab 容器。我希望能够使用其容器名称作为主机从 VPN 客户端访问此 gitlab 容器。我喜欢使用 docker 网络来管理哪些容器可以通过 VPN 访问的想法。

由于 docker 具有其嵌入式 DNS 功能,我认为这应该可以通过将 DNS 数据包转发给它(127.0.0.11:53)来实现,这样我就可以使用 VPN 服务器的地址作为客户端上的名称服务器。

至少,在 OVPN 容器中本地执行时,似乎有一个有效的 DNS 服务:

bash-4.3# nslookup gitlab 127.0.0.11             
Server:    127.0.0.11
Address 1: 127.0.0.11

Name:      gitlab
Address 1: 172.19.0.2 gitlab_gitlab_1.gitlab_default

但是,我的 iptables 路由不起作用:

iptables -t nat -I PREROUTING 1 -p udp -s 192.168.255.0/24 --dport 53 -j DNAT --to-destination 127.0.0.11:53
iptables -t nat -I PREROUTING 1 -p tcp -s 192.168.255.0/24 --dport 53 -j DNAT --to-destination 127.0.0.11:53

其中 192.168.255.0/24 是我的 VPN 网络。

这是完整的 iptables 列表:

bash-4.3# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  192.168.255.0/24     anywhere             tcp dpt:domain to:127.0.0.11:53
DNAT       udp  --  192.168.255.0/24     anywhere             udp dpt:domain to:127.0.0.11:53

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER_OUTPUT  all  --  anywhere             127.0.0.11          

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER_POSTROUTING  all  --  anywhere             127.0.0.11          
MASQUERADE  all  --  192.168.255.0/24     anywhere            

Chain DOCKER_OUTPUT (1 references)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             127.0.0.11           tcp dpt:domain to:127.0.0.11:36429
DNAT       udp  --  anywhere             127.0.0.11           udp dpt:domain to:127.0.0.11:33172

Chain DOCKER_POSTROUTING (1 references)
target     prot opt source               destination         
SNAT       tcp  --  127.0.0.11           anywhere             tcp spt:36429 to::53
SNAT       udp  --  127.0.0.11           anywhere             udp  spt:33172 to::53

除上述两个规则外,所有规则均由 docker 自动创建。我做错了什么?

答案1

docker 内嵌 DNS 的目标端口每次启动时都会改变(to:127.0.0.11:36429)。尝试将传入流量分派到DOCKER_OUTPUT规则:

iptables -t nat -A PREROUTING -p udp --dport 53 -j DOCKER_OUTPUT
iptables -t nat -A PREROUTING -p tcp --dport 53 -j DOCKER_OUTPUT

要将响应转发给原始请求者,请将伪装规则添加到任何源自您之外的包localhost

iptables -t nat -A POSTROUTING ! -s 127.0.0.1 -p udp --dport 53 -j MASQUERADE
iptables -t nat -A POSTROUTING ! -s 127.0.0.1 -p tcp --dport 53 -j MASQUERADE

相关内容