linux防火墙中基于状态的包过滤是默认启用的核心机制,内核通过conntrack子系统维护连接跟踪表,自动识别new/established/related等状态,使firewalld等工具能智能放行合法响应流量,无需手动开放高端口,天然抵御syn flood等会话层攻击。

Linux 防火墙中基于状态的包过滤(Stateful Inspection)不是“额外功能”,而是现代内核防火墙(如 iptables/nftables)和上层管理工具(如 firewalld)默认启用的核心机制。它让防火墙不再只看单个数据包的五元组,而是理解整个连接生命周期——这才是真正区分“合法响应”和“可疑入站”的关键。
状态跟踪如何工作
内核通过 conntrack 子系统维护一张动态连接跟踪表(connection tracking table),记录每个活跃连接的状态信息,包括:
- 源/目的 IP 地址与端口
- 协议类型(TCP/UDP/ICMP 等)
- TCP 连接状态(NEW、ESTABLISHED、RELATED、INVALID)
- 连接超时时间(如 ESTABLISHED 默认 5 天)
- UDP 流的会话标识(基于 IP+端口+超时窗口)
当一个新包到达时,防火墙先查 conntrack 表:若匹配已有连接且状态合法(如响应包属于 ESTABLISHED 连接),则直接放行;否则才进入规则链(如 INPUT)做策略判断。
firewalld 如何体现状态检测
firewalld 本身不直接操作 conntrack,但它所有区域(zone)的默认行为都依赖内核的状态机制。例如:
- public 区域默认拒绝入站新连接,但自动允许已建立连接的返回流量(无需手动开高端口)
- 添加服务(如 http)时,firewalld 实际下发的是对 NEW 状态的放行规则,后续 ESTABLISHED/RELATED 流量由 conntrack 自动处理
- 启用 masquerade 或端口转发时,conntrack 会同步维护 NAT 映射关系,确保回程包能正确反向转换
验证和调试状态行为
你可以用以下命令观察实际效果:
- sudo conntrack -L 查看当前所有跟踪连接
- sudo firewall-cmd --list-all 确认当前区域是否启用 default-drop 策略
-
sudo tcpdump -i any port 22 and host
结合 conntrack 输出,对比 SYN(NEW)与后续 ACK(ESTABLISHED)的处理路径 - 临时禁用状态跟踪测试:echo 0 | sudo tee /proc/sys/net/netfilter/nf_conntrack_enable(仅用于调试,勿在生产环境使用)
为什么不能只靠静态规则
假设你用纯包过滤方式开放 Web 服务:
- 必须显式允许目标端口 80 的入站 + 源端口 1024–65535 的出站响应 → 极易被滥用
- UDP DNS 查询响应可能来自任意高端口,无法预判 → 规则要么太松,要么阻断业务
- TCP 半开连接(SYN Flood)、伪造 FIN/RST 包等攻击无法识别 → 缺乏上下文判断力
而状态检测自动解决这些问题:只允许属于已协商连接的响应包,丢弃无主孤包,天然抵御多数反射型和会话劫持类攻击。











