0.1 启动容器
0.2 打开iptables调试功能
通过调试可以看 iptables 几个表 (raw mangle nat filter ) 的顺序,谁先谁后, 可以自己测试一下.
0.3 查看 NAT 表
查看执行结果
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 12 packets, 883 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 12 packets, 883 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
2 0 0 MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:80
Chain DOCKER (2 references)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
2 0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:800.4 查看 filter 表
查看执行结果
Chain INPUT (policy ACCEPT 523 packets, 31567 bytes)
num pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 40 7071 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0
2 40 7071 DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0
3 15 833 ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
4 3 156 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0
5 22 6082 ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
6 0 0 ACCEPT all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 274 packets, 92208 bytes)
num pkts bytes target prot opt in out source destination
Chain DOCKER (1 references)
num pkts bytes target prot opt in out source destination
1 3 156 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:80
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
num pkts bytes target prot opt in out source destination
1 22 6082 DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
2 40 7071 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-2 (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 DROP all -- * docker0 0.0.0.0/0 0.0.0.0/0
2 22 6082 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-USER (1 references)
num pkts bytes target prot opt in out source destination
1 40 7071 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0.5 watch 日志
0.6 外部浏览器访问 nginx
上面我的操作我是在虚拟机里的.
0.7 观察日志
流量进来先走 nat:PREROUTING -> 如果有转发就走filter:FORWARD->nat:POSTROUTING
查看执行结果
TRACE: raw:PREROUTING:policy:2 IN=eth0 OUT=
# nat:PREROUTING:rule:1 找 nat:PREROUTING 第一条规则, target 是 DOCKER
TRACE: nat:PREROUTING:rule:1 IN=eth0 OUT=
# nat:DOCKER: 的第一条规则 in 不匹配, 所以 继续下一条规则. 第2条匹配了.
TRACE: nat:DOCKER:rule:2 IN=eth0 OUT=
# 走filter 的 forward(因为前面的规则里nat:DOCKER:rule:2 再根据路由)
# 跳转到 DOCKER-USER
TRACE: filter:FORWARD:rule:1 IN=eth0 OUT=docker0
# 跳这DOCKER-USER 第一条. 是个return (return的意思是,结束子chains,返回到原来的chains 继续它的下一条)
# 可以理解为 main函数里 调用了 A 函数, A函数里面return了. 你到了main ,执行 A函数后面的语句.
TRACE: filter:DOCKER-USER:return:1 IN=eth0 OUT=docker0
# 回到forward的第二条 发现是跳 DOCKER-ISOLATION-STAGE-1
TRACE: filter:FORWARD:rule:2 IN=eth0 OUT=docker0
# DOCKER-ISOLATION-STAGE-1的第一条 没有符合规则, 继续第二条看是否匹配, 匹配了.
# 第二条是个return
TRACE: filter:DOCKER-ISOLATION-STAGE-1:return:2 IN=eth0 OUT=docker0
# 继续回到forward. (看第3条规则没匹配,因为是还没有建立连接)
TRACE: filter:FORWARD:rule:4 IN=eth0 OUT=docker0
# accept 了..
TRACE: filter:DOCKER:rule:1 IN=eth0 OUT=docker0
TRACE: nat:POSTROUTING:policy:3 IN= OUT=docker0
# 后续
TRACE: filter:FORWARD:rule:1 IN=eth0 OUT=docker0
TRACE: filter:DOCKER-USER:return:1 IN=eth0 OUT=docker0
TRACE: filter:FORWARD:rule:2 IN=eth0 OUT=docker0
TRACE: filter:DOCKER-ISOLATION-STAGE-1:return:2 IN=eth0 OUT=docker0
# 看 这个时候匹配上了. 因为已经建立连接了.
TRACE: filter:FORWARD:rule:3 IN=eth0 OUT=docker0