nftables 原生无法识别畸形 tcp 标志,因其 ct state 不校验 tcp 标志合法性,需结合 ebpf 深度解析并标记异常包,再通过 meta mark 在 nftables 中静默丢弃。

要让 nftables 在检测到畸形 TCP 标志位(如 SYN+FIN、ALL-flags-on、NULL 扫描等)时静默丢弃,不能单靠 nftables 原生命令完成——因为标准 conntrack 不校验 TCP 标志组合合法性。必须结合 eBPF 程序做深度解析,并通过包标记驱动 nftables 决策。
为什么原生 nftables 无法直接识别畸形 TCP 标志
nftables 的 ct state 只跟踪连接生命周期,不验证 TCP 头部标志位是否符合 RFC 规范。例如:
- SYN 和 FIN 同时为 1:合法握手?还是端口扫描?nftables 默认放行
- URG+PSH+RST+SYN+FIN+ACK 全置位(“Xmas 扫描”):conntrack 视为 untracked,可能落入默认规则漏放
- 仅 ACK 但无对应 SYN-ACK:属于状态机异常迁移,原生无匹配能力
用 eBPF 实现 TCP 标志校验并标记异常包
在 socket 或 sk_skb hook 点加载 eBPF 程序,解析 TCP 头、检查标志位组合与序列号逻辑:
- 识别非法组合:如 (SYN & FIN) == 1、(SYN | FIN | RST) == 0(纯 ACK 无上下文)、所有 6 位全 1
- 对确认异常的包,写入 skb mark(如 0x200)或 per-CPU map 记录
- 推荐使用 libbpf + C 编写,hook 点选 sk_skb(早于 conntrack,避免被跳过)
在 nftables 中匹配标记并静默丢弃
eBPF 标记后,nftables 用 meta mark 快速决策,确保无响应:
nft add rule inet filter input meta mark & 0x200 == 0x200 drop- 务必放在链开头,避免被其他 accept 规则提前匹配
- 不使用
reject,不发 RST/ICMP,扫描器收不到任何反馈
补充建议:配合基础连接状态过滤
即使启用 eBPF 检测,仍需保留 conntrack 层防护作为兜底:
nft add rule inet filter input ct state invalid drop-
nft add rule inet filter input ct state { new, untracked } tcp flags & (fin | syn | rst | ack) != syn drop(拦截非 SYN 的新连接请求) - 这两条可筛掉部分明显异常流量,降低 eBPF 负载











