iptables的state模块通过识别非法ACK包状态实现精准拦截:仅放行ESTABLISHED/RELATED状态的ACK,拒绝INVALID或无状态的孤立ACK,并可叠加tcp-flags、length和recent模块提升准确性。

iptables 的 state 模块本身不直接“深度拦截 ACK 扫描”,但它能精准识别并阻断那些绕过三次握手、伪造或滥用 ACK 标志位的非法连接尝试——这类行为常见于 ACK 扫描(如 nmap -sA)、会话劫持探测或 TCP 状态混淆攻击。关键在于:合法 ACK 包必然属于已建立(ESTABLISHED)或关联(RELATED)连接;而扫描器发出的孤立 ACK(无对应 SYN/ACK 会话)在内核 conntrack 表中查不到状态,会被标记为 INVALID 或 UNTRACKED。
识别并拦截孤立/伪造的 ACK 包
ACK 扫描的核心是向目标端口发送纯 ACK 包(仅 ACK 位为 1),观察 RST 响应来判断端口是否“过滤”或“开放”。这类包从不触发三次握手,因此不会进入 ESTABLISHED 状态。用 state 模块可高效筛出:
-
拒绝所有非 ESTABLISHED/RELATED 的 ACK 包(最常用且有效):
iptables -A INPUT -p tcp --tcp-flags ALL ACK -m state ! --state ESTABLISHED,RELATED -j DROP -
专门拦截 INVALID 状态的 ACK(常伴随半开连接残留或畸形包):
iptables -A INPUT -p tcp --tcp-flags ALL ACK -m state --state INVALID -j DROP -
排除已知管理端口白名单(避免误伤 SSH、HTTPS 健康检查等):
如需放行对 22 或 443 端口的特定 ACK 探测(例如 LB 心跳),应在上述规则前加显式 ACCEPT:iptables -A INPUT -p tcp --dport 22 --tcp-flags ALL ACK -m state --state ESTABLISHED,RELATED -j ACCEPT
配合 tcp-flags 与 length 提升准确性
单靠 state 可能漏掉未被 conntrack 跟踪的包(如 conntrack 表满、nf_conntrack_tcp_be_liberal 关闭)。建议叠加底层特征过滤:
-
只允许 ACK+PSH 或 ACK+FIN 的组合(真实数据传输或优雅关闭):
iptables -A INPUT -p tcp --tcp-flags ALL ACK,PSH -m state --state ESTABLISHED -j ACCEPTiptables -A INPUT -p tcp --tcp-flags ALL ACK,FIN -m state --state ESTABLISHED -j ACCEPT -
拦截长度异常的小 ACK 包(如仅含 TCP 头无载荷,长度=40 字节):
iptables -A INPUT -p tcp --tcp-flags ALL ACK -m length --length 40 -m state ! --state ESTABLISHED -j DROP
处理未被跟踪的 ACK(UNTRACKED 场景)
若启用了 -j NOTRACK 规则(如对某些高吞吐端口跳过 conntrack),或系统禁用 connection tracking,ACK 包可能标记为 UNTRACKED。此时需回退到更基础的匹配逻辑:
- 先用
--tcp-flags确保只含 ACK:iptables -A INPUT -p tcp --tcp-flags ALL ACK --tcp-flags ACK ACK - 再结合 recent 模块做轻量级连接上下文还原:
记录最近 5 秒内对该 IP 发起过 SYN 的源地址,仅允许其后续 ACK:iptables -A INPUT -p tcp --syn -m recent --name ack-whitelist --setiptables -A INPUT -p tcp --tcp-flags ALL ACK -m recent --name ack-whitelist --rcheck --seconds 5 -j ACCEPT
验证与日志辅助分析
启用日志可快速定位误拦或漏拦场景:
- 记录被丢弃的非法 ACK:
iptables -A INPUT -p tcp --tcp-flags ALL ACK -m state ! --state ESTABLISHED,RELATED -j LOG --log-prefix "ILLEGAL-ACK: "
配合journalctl -k | grep "ILLEGAL-ACK"实时查看 - 确认 conntrack 状态跟踪是否启用:
sysctl net.netfilter.nf_conntrack_tcp_be_liberal应为 1(默认),确保宽松模式下仍能识别部分边缘 ACK 流量

















