概述
linux conntrack (connection tracking)
conntrack本质
conntrack本质是一个内核里的hash表,每个node上的conntrack在跟踪流过它的每一条连接
conntrack含义
conntrack俗称流表,或者连接跟踪表,它属于netfilters框架,在PREROUTING mangle之前以及OUTPUT mangle之前都会经过一个connection tracking的表。
conntrack作用
conntrack是实现nat地址转换的灵魂,一个连接仅在首次经过netfilters链条时会计算nat表,一旦conntrack记录下这次的改写关系,后续无论是去程包还是回程包都是依据conntrack表进行改写关系的处理,不会再重复执行nat表中的DNAT/SNAT规则。
conntrack内容
在node的conntrack表中记录了大量的记录,每条记录包含2部分:
改写前的源IP和目标IP
改写后的源IP和目标IP
conntrack条目解析,以三次握手为例
1、syn send
SYN_SENT状态被设置了,这说明连接已经发出一个SYN包,但应答还没发送过 来,这可从[UNREPLIED]标志看出。
tcp 6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031
dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23
dport=1031 use=1
2、syn/ack receive
现在我们已经收到了相应的SYN/ACK包,状态也变为SYN_RECV,这说明最初发出的SYN包已正确传输,
并 且SYN/ACK包也到达了防火墙。 这就意味着在连接的两方都有数据传输,因此可以认为两个方向都有相应的回应。
tcp 6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031
dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031
use=1
3、ack receive
现在我们发出了三步握手的最后一个包,即ACK包,连接也就进入ESTABLISHED状态了。再传输几个数据 包,连接就是[ASSURED]的了。
tcp 6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35
sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5
sport=23 dport=1031 use=1
字段解析:
第一个是协议名称
第二个是协议号
第三个是此状态的生存时间
接下来是包的源、目地址和端口,还有期待之中回应包的源、目地址和端口。
[UNREPLIED]标 记说明还未收到回应
conntrack命令使用
连接跟踪子系统会跟踪它看到的所有报文流。运行 sudo conntrack -L 可查看其内容:
tcp 6 43184 ESTABLISHED src=192.168.2.5 dst=10.25.39.80 sport=5646 dport=443 src=10.25.39.80 dst=192.168.2.5 sport=443 dport=5646 [ASSURED] mark=0 use=1
tcp 6 26 SYN_SENT src=192.168.2.5 dst=192.168.2.10 sport=35684 dport=443 [UNREPLIED] src=192.168.2.10 dst=192.168.2.5 sport=443 dport=35684 mark=0 use=1
udp 17 29 src=192.168.8.1 dst=239.255.255.250 sport=48169 dport=1900 [UNREPLIED] src=239.255.255.250 dst=192.168.8.1 sport=1900 dport=48169 mark=0 use=1
上述显示结果中,每行表示一个连接跟踪项。你可能会注意到,每行相同的地址和端口号会出现两次,而且第二次出现的源地址/端口对和目标地址/端口对会与第一次正好相反!这是因为每个连接跟踪项会先后两次被插入连接状态表。第一个四元组(源地址、目标地址、源端口、目标端口)记录的是原始方向的连接信息,即发送者发送报文的方向。而第二个四元组则记录的是连接跟踪子系统期望收到的对端回复报文的连接信息。
这解决了两个问题:
1、如果报文匹配到一个 NAT 规则,例如 IP 地址伪装,相应的映射信息会记录在链接跟踪项的
回复方向部分,并自动应用于同一条流的所有后续报文。
2、即使一条流经过了地址或端口的转换,也可以成功在连接状态表中查找到回复报文的四元组信息。
原始方向的(第一个显示的)四元组信息永远不会改变:它就是发送者发送的连接信息。
NAT 操作只会修改回复方向(第二个)四元组,因为这是接受者看到的连接信息。
修改第一个四元组没有意义:netfilter 无法控制发起者的连接状态,它只能在收到/转发报文时对其施加影响。当一个报文未映射到现有连接表项时,连接跟踪可以为其新建一个表项。
对于 UDP 报文,该操作会自动进行。对于 TCP 报文,连接跟踪可以配置为只有 TCP 报文设置了 SYN 标志位 才新建表项。
默认情况下,连接跟踪会允许从流的中间报文开始创建,这是为了避免对启用连接跟踪之前就存在的流处理出现问题。
回复方向的四元组包含 NAT 信息。你可以通过命令过滤输出经过源地址 NAT 或目标地址 NAT 的连接跟踪项。通过这种方式可以看到一个指定的流经过了哪种类型的 NAT 转换。
例如,运行 sudo conntrack -L -p tcp –src-nat 可显示经过源 NAT 的连接跟踪项,输出结果类似于以下内容:
tcp 6 114 TIME_WAIT src=10.0.0.10 dst=10.8.2.12 sport=5536 dport=80 src=10.8.2.12 dst=192.168.1.2 sport=80 dport=5536 [ASSURED]
这个连接跟踪项表示一条从 10.0.0.10:5536 到 10.8.2.12:80 的连接。与前面示例不同的是,回复方向的四元组不是原始方向四元组的简单翻转:源地址已修改。目标主机(10.8.2.12)将回复数据包发送到 192.168.1.2,而不是 10.0.0.10。
每当 10.0.0.10 发送新的报文时,具有此连接跟踪项的路由器会将源地址替换为 192.168.1.2。当 10.8.2.12 发送回复报文时,该路由器将目的地址修改回 10.0.0.10。
注意点:
调试nat流量的时候,iptables -t nat -nvL去查看NAT表在OUTPUT链和POSTROUTING链上的packge计数器,结果可能是没有上涨,即使此时仍有正常的nat流量。
NAT表除了第一次做NAT时有应用外,后续都靠conntrack的映射表来NAT,后续的包不会再执行NAT表的规则来。
即:NAT表只在连接状态是NEW的时候(也就是TCP的第一个握手包)才会执行计算,一旦改写关系存入了conntrack,那么这条连接后续的通讯就不会再过POSTROUTING和OUTPUT上面的NAT表了,而是直接换成了匹配conntrack来复原连接之前的改写状态。
因此,如果我们想看到回包的package计数器增长,就应该去看OUTPUT或者POSTROUTING上面的filter表计数,一定会看到上涨。
最后
以上就是乐观菠萝为你收集整理的【博客521】linux conntrack (connection tracking)linux conntrack (connection tracking)的全部内容,希望文章能够帮你解决【博客521】linux conntrack (connection tracking)linux conntrack (connection tracking)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复