如何阻止Docker在Synology NAS上进行源NAT流量访问

时间:2020-05-05 23:51:10

标签: docker iptables synology

在Synology NAS上,似乎docker / iptables的默认设置是将去往容器的NAT流量源到网关IP。当容器需要查看正确/真实的客户端IP时,这从根本上引起了问题。例如,在ubuntu系统上运行时,我看不到此问题。

让我按照您所看到的走。在Synology NAS上,我将运行一个简单的nginx容器:

docker run --rm -ti -p 80:80 nginx

(我有disabled the Synology NAS from using port 80

我将在笔记本电脑上卷曲,然后看到以下日志行:

172.17.0.1 - - [05/May/2020:17:02:44 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"

嗯...客户端IP(172.17.0.1)是NAS上的docker0接口。

user@synology:~$ ifconfig docker0
docker0   Link encap:Ethernet  HWaddr 02:42:B5:BE:C5:51
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          <snip> 

当我第一次看到这一点时,我感到非常困惑,因为我不记得Docker网络以这种方式工作。因此,我启动了我的ubuntu VM并尝试了相同的测试(与之前的docker run命令相同)。

我的卷曲测试关闭框的日志行:

172.16.207.1 - - [05/May/2020:17:12:04 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"

在这种情况下,docker0 IP不是容器所看到的通信源。

user@ubuntu-vm:~# ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        <snip> 

因此,与更标准的ubuntu部署相比,Synolgy NAS的docker网络设置似乎有所不同。好的,整洁。那么如何解决这个问题呢?

这就是我在努力的地方。显然,iptables正在发生某些事情。在两个系统上运行相同的iptables -t nat -L -n命令会显示出截然不同的结果。

user@synology:~$ iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
DEFAULT_OUTPUT  all  --  0.0.0.0/0            0.0.0.0/0

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
DEFAULT_POSTROUTING  all  --  0.0.0.0/0            0.0.0.0/0

Chain DEFAULT_OUTPUT (1 references)
target     prot opt source               destination
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain DEFAULT_POSTROUTING (1 references)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:80

Chain DOCKER (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:80
user@ubuntu-vm:~# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           
MASQUERADE  all  --  172.18.0.0/16        0.0.0.0/0           
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:80

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
RETURN     all  --  0.0.0.0/0            0.0.0.0/0           
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:80

我真的不了解这些链如何工作,或者为什么它们对于不同的系统是不同的。在这两个系统上,我都没有更改任何docker级别的设置,这些是默认配置。

以前有人遇到过这个吗?有没有一种快速的方法来切换呢?

1 个答案:

答案 0 :(得分:1)

我自己在使用Pi-hole(描述为here时遇到了这个问题,而此iptables规则似乎可以解决此问题:

sudo iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER

请注意,这不是永久性的,因此,如果重新启动NAS,则必须再次应用它。


更新:这是一个更“永久”的修复程序:https://gist.github.com/PedroLamas/db809a2b9112166da4a2dbf8e3a72ae9