我使用 nftables 作为我的规则。
我的问题:如何记录 tcp 标志?
这是我的规则:
nft add rule filter input tcp dport 22 ct state new tcp flags \& \(fin\|syn\) ==\( fin \| syn\) accept
我总是得到的结果:
Dec 6 13:40:19 my_host my_FIN IN=eth0 OUT=eth1 MAC= SRC=x.1.1.1 DST=x.2.2.2 LEN=40 TOS=00 PREC=0x00 TTL=127 ID=17695 DF PROTO=TCP SPT=54049 DPT=422SEQ=2558094232 ACK=0 WINDOW=8192 SYN URGP=0 MARK=0
编辑 我的规则:
chain FORWARD {
ip saddr 1.1.1.1 ip daddr . tcp dport @myset tcp flags & (fin | syn) == fin | syn counter packets 0 bytes 0 log prefix " myprefix " group 1 accept
}
对于 TCP 情况,Netfilter 的 conntrack 在其内部状态和等效 TCP 状态之间进行了额外的一致性检查。这个netdev 2.1 PDF文档(对不起,我找不到它的 netdev url,这是来自作者的网站)讲述了它:
conntrack NEW状态匹配 TCP SYN_SENT或 TCP SYN_RECEIVED状态。如果您在规则中选择NEW状态条件,使用
ct state new
,它将永远不会匹配任何FIN数据包,因为在建立新的 TCP 连接时永远不会涉及FIN数据包。删除后重试
ct state new
。更新:我最初没有看到第二个问题。这个表达式:
将永远不会与 FIN 标志匹配,因为永远不会同时找到 FIN+SYN(除了一些随机的无效尝试)。正确的表达应该是:
无论何时设置 FIN或SYN都会匹配。实际上nftables简化了它,只有这个被显示或需要:
因此,考虑到这两种调整(
ct state new
必须仍然被删除),规则变为:或在完整的链组中:
一旦您可以使用上述规则实际检测到 FIN 数据包,如果您的意图是过滤一些 TCP 攻击(您真的需要吗?),请注意 netfilter 可能会考虑首先在 TCP 连接的第一个数据包中将 TCP FIN 视为INVALID状态:您可能有兴趣记录这些状态 (
ct state invalid
)。有 netfilter sysctl 切换可以改变关于INVALID状态的结果:启用 不会将其归类为无效的 nf_conntrack_tcp_be_liberal 和禁用nf_conntrack_tcp_loose这将停止恢复已建立的 TCP 连接,即停止拥有没有 SYN 的状态 NEW。只有在丢失连接跟踪后才能进行此恢复:在路由器重启防火墙或使用 刷新 conntrack 状态conntrack -F
之后,但谁知道呢,这里可能会选择偏执狂。