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
每行显示一个连接跟踪条目。您可能会注意到,每行两次显示地址和端口号,甚至是反向的地址和端口。这是因为每个条目两次插入到状态表中。第一个地址四元组(源地址和目标地址以及端口)是在原始方向上记录的地址,即发起方发送的地址。第二个四元组是conntrack希望在收到来自对等方的答复时看到的内容。这解决了两个问题:
如果NAT规则匹配(例如IP地址伪装),则将其记录在连接跟踪条目的答复部分中,然后可以自动将其应用于属于同一流的所有将来的数据包。
状态表中的查找将是成功的,即使它是对应用了任何形式的网络或端口地址转换的流的答复包。
原始的(第一个显示的)四元组永远不会改变:它是发起方发送的。NAT操作只会将回复(第二个)更改为四倍,因为这将是接收者看到的内容。对第一个四倍的更改将毫无意义:netfilter无法控制启动程序的状态,它只能影响数据包的接收/转发。当数据包未映射到现有条目时,conntrack可以为其添加新的状态条目。对于UDP,此操作会自动发生。对于TCP,conntrack可以配置为仅在TCP数据包设置了SYN位的情况下添加新条目。默认情况下,conntrack允许中流拾取不会对conntrack变为活动状态之前存在的流造成问题。
Conntrack状态表和NAT
如上一节所述,列出的答复元组包含NAT信息。可以过滤输出以仅显示应用了源或目标nat的条目。这样可以查看在给定流中哪种类型的NAT转换处于活动状态。“sudo conntrack -L -p tcp –src-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是由于nft假装规则所致:
inet nat postrouting meta oifname "veth0" masquerade
其他类型的NAT规则,例如“dnat to”或“redirect to”,将以类似的方式显示,其回复元组的目的地不同于原始的。
Conntrack扩展
conntrack记帐和时间戳记是两个有用的扩展。“sudo sysctl net.netfilter.nf_conntrack_acct=1”使每个流的“sudo conntrack -L”跟踪字节和数据包计数器。
“sudo sysctl net.netfilter.nf_conntrack_timestamp=1”记录每个连接的“开始时间戳”。然后,“sudo conntrack -L”显示自第一次看到流以来经过的秒数。添加“–output ktimestamp”也可以查看绝对开始日期。
插入和更改条目
您可以将条目添加到状态表。例如:
sudo conntrack -I -s 192.168.7.10 -d 10.1.1.1 --protonum 17 --timeout 120 --sport 12345 --dport 80
conntrackd将此用于状态复制。活动防火墙的条目将复制到备用系统。这样,备用系统就可以接管而不会中断连接,即使建立的流量也是如此。Conntrack还可以存储与网上发送的数据包数据无关的元数据,例如conntrack标记和连接跟踪标签。使用“update”(-U)选项更改它们:
sudo conntrack -U -m 42 -p tcp
这会将所有tcp流的connmark更改为42。
删除条目
在某些情况下,您想从状态表中删除条目。例如,对NAT规则的更改不会影响属于表中流的数据包。对于寿命长的UDP会话(例如像VXLAN这样的隧道协议),删除条目可能很有意义,这样新的NAT转换才能生效。通过“sudo conntrack -D”删除条目,然后删除地址和端口信息的可选列表。下面的示例从表中删除给定的条目:
sudo conntrack -D -p udp --src 10.0.12.4 --dst 10.0.0.1 --sport 1234 --dport 53
Conntrack错误计数器
Conntrack还可以导出统计信息:
# sudo conntrack -S
cpu=0 found=0 invalid=130 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=10
cpu=1 found=0 invalid=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
cpu=2 found=0 invalid=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=1
cpu=3 found=0 invalid=0 insert=0 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=0
大多数计数器将为0。“Found”和“insert”将始终为0,仅出于向后兼容的目的而存在。造成的其他错误包括:
invalid:数据包与现有连接不匹配,并且未创建新连接。
insert_failed:数据包开始新的连接,但是插入状态表失败。例如,当伪装时NAT引擎恰巧选择了相同的源地址和端口时,可能会发生这种情况。
drop:数据包启动一个新的连接,但是没有可用的内存为其分配新的状态条目。
early_drop:conntrack表已满。为了接受新连接,丢弃了没有双向通信的现有连接。
error:icmp(v6)收到与已知连接不匹配的icmp错误数据包
search_restart:查找由于另一个CPU的插入或删除而中断。
clash_resolve:几个CPU尝试插入相同的conntrack条目。
除非它们经常发生,否则这些错误条件是无害的。可以通过针对预期工作负载调整conntrack系统来减轻某些负担。net.netfilter.nf_conntrack_buckets和net.netfilter.nf_conntrack_max是典型的候选者。
当数据包无效时,请使用“sudo sysctl net.netfilter.nf_conntrack_log_invalid=255”来获取更多信息。例如,当conntrack遇到清除了所有tcp标志的数据包时,记录以下内容:
nf_ct_proto_6: invalid tcp flag combination SRC=10.0.2.1 DST=10.0.96.7 LEN=1040 TOS=0x00 PREC=0x00 TTL=255 ID=0 PROTO=TCP SPT=5723 DPT=443 SEQ=1 ACK=0
看完本文有收获?请转发分享更多人
因为分享是一种美德