要精准追踪非法协议包数量,需先定义内核可识别的非法特征(如ct state invalid、异常tcp标志等),再用nftables命名计数器原子记录匹配次数。

要精准追踪通过防火墙的特定非法协议包数量,关键不是“识别非法协议”本身(nftables 不解析应用层),而是定义什么是你认为需监控的“非法”行为,再用 stateful counter 做无干扰、可复用、原子更新的计数。
核心思路是:先用 nftables 规则精确匹配目标流量特征(如异常 TCP 标志、INVALID 状态、未授权端口、非 ESTABLISHED 的 UDP 回包等),再在该规则中显式挂载命名计数器。计数器不改变包走向,只忠实记录匹配次数。
✅ 明确“非法协议包”的常见可匹配特征
nftables 无法判断 HTTP 请求是否恶意,但能可靠识别以下内核可判定的异常:
-
ct state invalid:连接跟踪失败,极可能为伪造源、分片攻击、TCP 状态混乱包 -
tcp flags & (fin|syn|rst|psh|ack|urg) != syn且ct state new:非 SYN 的新连接发起(如 SYN+FIN 扫描) -
ip protocol icmp icmp type { destination-unreachable, time-exceeded }但来源非已知出口网关(需配合 ip saddr 过滤) -
udp dport 137-139或5355等非预期端口上的入向 UDP 包(无对应 established 连接) -
ip frag-off != 0:非首片 IP 分片(常用于规避检测)
这些都可在规则中直接表达,无需外部模块。
✅ 创建并绑定命名计数器(Stateful Counter)
命名计数器必须先创建,再引用,才能跨规则复用、单独查看、长期跟踪:
# 创建一个专用于统计 INVALID 包的计数器 nft add counter inet filter invalid-count # 创建一个专用于统计 TCP 异常标志组合的计数器 nft add counter inet filter tcp-flag-scan # 创建一个专用于统计非法 DNS 端口 UDP 包的计数器 nft add counter inet filter udp-dns-scan
⚠️ 注意:
inet是地址簇(兼容 IPv4/IPv6),filter是表名,invalid-count是你在整张表内唯一可用的名字。
✅ 在 INPUT 链中添加带计数器的匹配规则
把计数器作为规则的一部分,放在 accept / drop / log 之前或之后均可(顺序不影响计数):
# 统计所有 INVALID 包(建议放在规则链靠前位置)
nft add rule inet filter input ct state invalid counter name invalid-count
# 统计 SYN+FIN 或 NULL 扫描包(TCP 标志非法组合)
nft add rule inet filter input tcp flags & (fin|syn|rst|psh|ack|urg) != 0 \
tcp flags & (fin|syn) == (fin|syn) \
counter name tcp-flag-scan
# 统计发往本地 5355(LLMNR)端口的 UDP 包(非 established)
nft add rule inet filter input udp dport 5355 ct state != established \
counter name udp-dns-scan
? 提示:
ct state != established比ct state new更宽泛,涵盖 untracked 和 invalid 场景,适合广义“非法回包”。
✅ 实时查看与持续监控计数结果
-
查看某条规则及其当前计数:
nft list chain inet filter input
输出中会显示类似:
ct state invalid counter name invalid-count packets 127 bytes 9834
-
只看计数器本身(不含规则):
nft list counter inet filter invalid-count
-
每秒刷新观察增长(适合调试):
watch -n1 'nft list counter inet filter invalid-count'
✅ 所有计数字段(packets / bytes)都是原子更新,不会因并发漏记或重复计。
✅ 进阶:结合 drop 或 log 构成闭环响应
计数器可与其他动作共存,形成“先记录、再处置”流程:
# 记录 + 丢弃 INVALID 包(推荐兜底策略)
nft add rule inet filter input ct state invalid counter name invalid-count drop
# 记录 + 打日志 + 丢弃 TCP 扫描包(便于审计)
nft add rule inet filter input tcp flags & (fin|syn) == (fin|syn) \
counter name tcp-flag-scan log prefix "TCP-SCAN: " drop
⚠️ 注意:
drop和accept是 verdict 动作,一旦执行即终止该包在当前链的处理;counter和log是 non-verdict 动作,可自由组合。
不复杂但容易忽略











