记录 TCP 标志

记录 TCP 标志

我使用 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 

}

答案1

对于 TCP 情况,Netfilter 的 conntrack 在其内部状态和等效 TCP 状态之间进行了额外的一致性检查。这网络开发 2.1 PDF文档(抱歉我找不到它的 netdev url,这是来自作者的网站)讲述了它:

L4 跟踪器尝试保持状态,例如 tcp:跟踪状态,检查序列号。例子:

  • 新的TCP数据包?同步位设置?
  • 预期窗口中的 TCP 序列号?
  • 未确认的数据? → 调整超时时间
  • 首先?鳍? → 删除连接和/或调整超时

连线新的状态与 TCP 匹配SYN_SENT或 TCPSYN_已接收状态。如果您选择新的规则中的状态条件,使用ct state new,它永远不会匹配任何数据包,因为从来没有数据包参与建立新的 TCP 连接。

删除后重试ct state new

更新:还有第二个问题我最初没有看到。这个表达式:

tcp flags & (fin | syn) == fin | syn

永远不会与 FIN 标志匹配,因为永远不会同时找到 FIN+SYN(除了一些随机的无效尝试)。正确的表达应该是:

tcp flags & (fin | syn) != 0

每当 FIN 时都会匹配或者SYN 已设置。实际上nftables简化了它,只显示或需要这个:

tcp flags fin,syn

因此,考虑到这两项调整(ct state new仍必须删除),规则变为:

nft add rule filter FORWARD 'tcp dport 22 tcp flags fin,syn log prefix " my_FIN " group 1 accept

或在完整的链集中:

 chain FORWARD {
      type filter hook forward priority 0; policy accept;
      ip saddr 1.1.1.1 ip daddr . tcp dport @myset tcp flags fin,syn counter log prefix " myprefix " group 1 accept 

 }

一旦您可以使用上述规则实际检测到 FIN 数据包,如果您的目的是过滤某些 TCP 攻击(您真的需要吗?),请注意,netfilter 可能会考虑首先在 TCP 连接的第一个数据包中看到 TCP FIN,如下所示无效的状态:您可能有兴趣记录这些状态 ( ct state invalid)。有 netfilter sysctl 开关可以改变结果无效的状态:启用nf_conntrack_tcp_be_liberal 这不会将其归类为无效,并且禁用nf_conntrack_tcp_loose这将停止恢复已建立的 TCP 连接,即停止处于没有 SYN 的 NEW 状态。这种恢复应该仅在丢失连接跟踪后发生:在防火墙路由器重新启动后或使用 刷新 conntrack 状态后conntrack -F,但谁知道呢,这里可能会选择偏执。

相关内容