在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级别的设置,这些是默认配置。
以前有人遇到过这个吗?有没有一种快速的方法来切换呢?
答案 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