我有一个在 vanilla 设置上运行的 Docker 容器,它监听端口 9999:
docker run --rm -it -p 9999:9999 busybox nc -vvl -p 9999 0.0.0.0
我向 NAT 上的 POSTROUTING 表添加了一条 LOG 规则,以便捕获服务器数据包。但是,当我从外部机器连接到此容器时,系统日志中什么也看不到。
不过,当我登录 mangle 的 POSTROUTING 链的末尾时,我可以看到连接数据包。根据The Diagram(TM),NAT-POSTROUTING 应该是下一个要传输的链。
这是 NAT 表:
# iptables -nL -tnat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER 0 -- 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 0 -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
LOG 0 -- 172.16.0.0/12 0.0.0.0/0 LOG flags 0 level 4 prefix "Packet:"
MASQUERADE 0 -- 172.17.0.0/16 0.0.0.0/0
MASQUERADE 6 -- 172.17.0.2 172.17.0.2 tcp dpt:9999
Chain DOCKER (2 references)
target prot opt source destination
RETURN 0 -- 0.0.0.0/0 0.0.0.0/0
DNAT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9999 to:172.17.0.2:9999
观察后journalctl -f | grep Packet:
没有发现任何异常。TRACE 指示 NAT 表被全部跳过,即服务器传出的数据包的所有链都被跳过。
设置如下:
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
为什么会出现这种情况?或者更一般地说,为什么有些数据包会完全跳过 NAT 表?