最近有点着迷iptables,各种用法都想试试
虚拟机里一个内网IP,一个float IP
root@iptables:~# ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: mtu 1400 qdisc pfifo_fast state UP qlen 1000 link/ether fa:16:3e:a8:79:61 brd ff:ff:ff:ff:ff:ff inet 10.10.38.115/21 brd 10.10.39.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fea8:7961/64 scope link valid_lft forever preferred_lft forever 3: eth1: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether fa:17:00:13:01:14 brd ff:ff:ff:ff:ff:ff inet 115.115.115.187/21 brd 115.115.119.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::f817:ff:fe13:114/64 scope link valid_lft forever preferred_lft forever
路由规则
root@iptables:~# ip r 0.0.0.0/1 via 115.115.112.1 dev eth1 default via 10.10.32.1 dev eth0 ......
添加一条源地址转换规则
root@iptables:~# iptables -t nat -A POSTROUTING -s 10.10.38.115/21 -j SNAT --to-source 115.115.115.187 root@iptables:~# iptables -t nat -vnL POSTROUTING --line-number Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 SNAT all -- * * 10.10.32.0/21 0.0.0.0/0 to:115.115.115.187
这里内网网关只有内网才能通,外网却是没法通的,此时已经将源IP地址为该内网IP的包,源IP snat成了外网IP,而没有这条路由规则,虚拟机内部应该是没法通内网网关的,但是
root@iptables:~# ping 10.10.32.1 PING 10.10.32.1 (10.10.32.1) 56(84) bytes of data. 64 bytes from 10.10.32.1: icmp_req=1 ttl=62 time=0.371 ms 64 bytes from 10.10.32.1: icmp_req=2 ttl=62 time=0.172 ms 64 bytes from 10.10.32.1: icmp_req=3 ttl=62 time=0.172 ms 64 bytes from 10.10.32.1: icmp_req=4 ttl=62 time=0.146 ms 64 bytes from 10.10.32.1: icmp_req=5 ttl=62 time=0.114 ms
看到大吃一惊,先抓内网网卡的包
root@iptables:~# tcpdump -i eth0 icmp -en tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 21:32:54.943565 fa:16:3e:a8:79:61 > fa:16:3e:92:36:49, ethertype IPv4 (0x0800), length 98: 115.115.115.187 > 10.10.32.1: ICMP echo request, id 21802, seq 1, length 64 21:32:55.942572 fa:16:3e:a8:79:61 > fa:16:3e:92:36:49, ethertype IPv4 (0x0800), length 98: 115.115.115.187 > 10.10.32.1: ICMP echo request, id 21802, seq 2, length 64 21:32:56.941563 fa:16:3e:a8:79:61 > fa:16:3e:92:36:49, ethertype IPv4 (0x0800), length 98: 115.115.115.187 > 10.10.32.1: ICMP echo request, id 21802, seq 3, length 64 21:32:57.940958 fa:16:3e:a8:79:61 > fa:16:3e:92:36:49, ethertype IPv4 (0x0800), length 98: 115.115.115.187 > 10.10.32.1: ICMP echo request, id 21802, seq 4, length 64 21:32:58.940950 fa:16:3e:a8:79:61 > fa:16:3e:92:36:49, ethertype IPv4 (0x0800), length 98: 115.115.115.187 > 10.10.32.1: ICMP echo request, id 21802, seq 5, length 64
可以看到只有request,没有reply,继续再抓外网网卡的包
root@iptables:~# tcpdump -i eth1 icmp -en tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes 21:32:42.263175 3c:8c:40:08:37:39 > fa:17:00:13:01:14, ethertype IPv4 (0x0800), length 98: 10.10.32.1 > 115.115.115.187: ICMP echo reply, id 21800, seq 1, length 64 21:32:43.261973 3c:8c:40:08:37:39 > fa:17:00:13:01:14, ethertype IPv4 (0x0800), length 98: 10.10.32.1 > 115.115.115.187: ICMP echo reply, id 21800, seq 2, length 64 21:32:44.261128 3c:8c:40:08:37:39 > fa:17:00:13:01:14, ethertype IPv4 (0x0800), length 98: 10.10.32.1 > 115.115.115.187: ICMP echo reply, id 21800, seq 3, length 64 21:32:45.261134 3c:8c:40:08:37:39 > fa:17:00:13:01:14, ethertype IPv4 (0x0800), length 98: 10.10.32.1 > 115.115.115.187: ICMP echo reply, id 21800, seq 4, length 64 21:32:46.261066 3c:8c:40:08:37:39 > fa:17:00:13:01:14, ethertype IPv4 (0x0800), length 98: 10.10.32.1 > 115.115.115.187: ICMP echo reply, id 21800, seq 5, length 64
看到这里,reply都在这里,原来是eth0=>gw=>eth1的节奏,仔细想想也是对的,eth0上的包通过snat源地址变成了外网地址,而namespace里网关本身也是通过snat能够访问外网的因此能够回ping包,所以表面上看好像还能够到网关,实际上reply和request走的是不同的路线
也许你要问,我的根据是什么,答案就是MAC地址
eth0网卡上源MAC地址其实是内网网卡的,可以对比ip a的结果;eth1网卡上目的MAC地址是外网网卡的,这样就肯定了上面的说法,除此之外,两个10.10.32.1的MAC地址不一致,原因就是request里对应的目的MAC地址是namespace里ha的,而reply里的源MAC地址就属于ha经过SNAT之后的qg所有