• iptables nat&conntrack


    规则的顺序很重要,一旦有一个规则匹配成功了,后面的规则将会被忽略

    - -I: 指定一个链,表示要加入一条规则在链中,放在所有规则的首部

    - -A:指定一个链,追加一条规则,放在所有规则尾部

    10.10.28.18的网关是10.10.28.1

    root@ubuntu:/home/devuser# ping 8.8.8.8
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=251 time=2.84 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=251 time=2.67 ms
    ^C
    --- 8.8.8.8 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 2.677/2.759/2.842/0.097 ms
    root@ubuntu:/home/devuser# 
    root@ubuntu:/home/devuser# tcpdump -i enp1s0  icmp and  host 10.10.28.18 
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on enp1s0, link-type EN10MB (Ethernet), capture size 262144 bytes
    16:55:13.696084 IP 10.10.28.18 > dns.google: ICMP echo request, id 2943, seq 1, length 64
    16:55:13.698672 IP dns.google > 10.10.28.18: ICMP echo reply, id 2943, seq 1, length 64
    16:55:14.697137 IP 10.10.28.18 > dns.google: ICMP echo request, id 2943, seq 2, length 64
    16:55:14.699610 IP dns.google > 10.10.28.18: ICMP echo reply, id 2943, seq 2, length 64
    16:55:15.699053 IP 10.10.28.18 > dns.google: ICMP echo request, id 2943, seq 3, length 64
    16:55:15.701513 IP dns.google > 10.10.28.18: ICMP echo reply, id 2943, seq 3, length 64
    16:55:16.700986 IP 10.10.28.18 > dns.google: ICMP echo request, id 2943, seq 4, length 64
    16:55:16.703475 IP dns.google > 10.10.28.18: ICMP echo reply, id 2943, seq 4, length 64

    10.10.28.18 经过10.10.18.1时 下述规则生效

    19       3   252 MASQUERADE  all  --  *      *       10.10.28.18         !10.10.28.0/24 

    8.8.8-->10.10.18.1 回包时

    3189  167K MASQUERADE  all  --  *      *      !10.10.28.1           10.10.28.0/24

    抓包应该看不到dns.google ,实际上看到了

    root@PORT:~# conntrack -L | grep 10.10.28.18
    tcp      6 115 SYN_SENT src=10.10.28.18 dst=8.8.8.8 sport=48352 dport=22 [UNREPLIED] src=8.8.8.8 dst=210.xx.xx.151 sport=22 dport=48352 mark=0 use=1
    icmp     1 15 src=10.10.28.18 dst=8.8.8.8 type=8 code=0 id=2958 src=8.8.8.8 dst=210.xx.xx.151 type=0 code=0 id=2958 mark=0 use=1
    conntrack v1.4.3 (conntrack-tools): 113 flow entries have been shown.
    tcp      6 431996 ESTABLISHED src=10.10.28.1 dst=10.10.28.18 sport=35230 dport=22 src=10.10.28.18 dst=10.10.28.1 sport=22 dport=35230 [ASSURED] mark=0 use=1
    root@PORT:~# 
    root@ubuntu:/home/devuser# ping 10.10.16.82
    PING 10.10.16.82 (10.10.16.82) 56(84) bytes of data.
    64 bytes from 10.10.16.82: icmp_seq=1 ttl=63 time=0.236 ms
    64 bytes from 10.10.16.82: icmp_seq=2 ttl=63 time=0.122 ms
    64 bytes from 10.10.16.82: icmp_seq=3 ttl=63 time=0.123 ms
    ^C
    --- 10.10.16.82 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2055ms
    rtt min/avg/max/mdev = 0.122/0.160/0.236/0.054 ms
    root@ubuntu:/home/devuser#
    root@PORT:~# conntrack -L | grep 10.10.28.18
    icmp     1 24 src=10.10.28.18 dst=10.10.16.82 type=8 code=0 id=2965 src=10.10.16.82 dst=10.10.16.1 type=0 code=0 id=2965 mark=0 use=1
    conntrack v1.4.3 (conntrack-tools): 115 flow entries have been shown.
    tcp      6 431994 ESTABLISHED src=10.10.28.1 dst=10.10.28.18 sport=35230 dport=22 src=10.10.28.18 dst=10.10.28.1 sport=22 dport=35230 [ASSURED] mark=0 use=1

    iptables nat&conntrack的特殊之处

    问题与解释

    我在PREROUTING上做了一个REDIRECT端口改写,相应的服务处理请求后会返回应答。

    按照我以往的认识,认为回包的流量应该先后经过OUTPUT和POSTROUTING,所以我利用iptables -t nat -nvL去查看NAT表在OUTPUT链和POSTROUTING链上的packge计数器,结果发现没有上涨,这让我陷入了沉思。

    经过谷歌后找到了完美的解释:linux-netfilter-how-does-connection-tracking-track-connections-changed-by-nat

    实际上我是知道OUTPUT链会先过conntrack表恢复原始IP关系的,但是超出我理解的是NAT表压根就不会再执行。

    上述URL中给出了解释:NAT表只在连接状态是NEW的时候(也就是TCP的第一个握手包)才会执行计算,一旦改写关系存入了conntrack,那么这条连接后续的通讯就不会再过POSTROUTING和OUTPUT上面的NAT表了,而是直接换成了匹配conntrack来复原连接之前的改写状态。

    因此,如果我们想看到回包的package计数器增长,就应该去看OUTPUT或者POSTROUTING上面的filter表计数,一定会看到上涨。

    再次梳理流程

    如果我们是服务端,那么SYN包到达的时候,在POSTROUTING链的NAT表执行过之后(可能做DNAT或者REDIRECT),路由表将决定是FORWARD还是INPUT:

    • 如果INPUT,那么conntrack记录就此生成,当回包的时候会首先根据conntrack作地址复原,并且是不会经过OUTPUT/POSTROUTING链NAT表(但是会经过filter表)的。
    • 如果FORWARD,那么conntrack记录不会立即生成,需要经过POSTROUTING之后才知道是否做了SNAT/MASQUERADE,此时才会生成conntrack记录。当收到上游回包的时候,不会过PREROUTING的NAT表,而是直接根据conntrack复原为原始IP地址,然后直接FORWARD->POSTROUTING(不会过NAT表)送回原始客户端。
  • 相关阅读:
    那些年搞不懂的多线程、同步异步及阻塞和非阻塞(一)---多线程简介
    java中IO流详细解释
    Java IO流学习总结
    MySQL数据库中索引的数据结构是什么?(B树和B+树的区别)
    使用Redis存储Nginx+Tomcat负载均衡集群的Session
    Redis 3.2.4集群搭建
    JDK1.8源码分析之HashMap
    java HashMap和LinkedHashMap区别
    Java中原子类的实现
    多线程-传统定时任务
  • 原文地址:https://www.cnblogs.com/dream397/p/13268064.html
Copyright © 2020-2023  润新知