Linux 防火墙与 nftables:规则集、链、NAT 与网络安全防护

nftables 防火墙实战:与 iptables 的架构与语法对比、表/链/规则、匹配条件、conntrack 连接跟踪、SNAT/DNAT/NAT、集合与 Maps、常见防护场景、调试排错与持久化。

引言

iptables 统治 Linux 防火墙十几年,如今正被 nftables 全面替代(Debian 12、RHEL 9、Ubuntu 22.04+ 都默认 nftables 后端)。nftables 是 Netfilter 的下一代前端:统一的表/链/规则模型、集合与 Maps(告别逐条生写)、原生 conntrack 状态匹配。本文先讲清防火墙在 Netfilter 钩子里的位置与 nftables 对比 iptables 的架构差异,再系统覆盖表/链/规则语法、匹配条件、连接跟踪、NAT、集合与 Maps、典型防护场景,最后给调试与持久化方法。

前置:/linux-network-commands/(网络栈与排查)、/linux-user-permissions/(root/权限)、/linux-containers-isolation/(网络隔离)。安全体系见 /linux-security-hardening/。


目录


1. 防火墙在 Linux 网络栈中的位置

Linux 防火墙的底层是 Netfilter——内核网络栈里的一组钩子(Hook):

数据包路径:
网卡 → PREROUTING → ROUTING → FORWARD → POSTROUTING → 网卡
                        │                    ↑
                     INPUT → 本地进程      OUTPUT ← 本地进程

五个 Netfilter 钩子:

PREROUTING:进入、路由前(DNAT 在这里)
INPUT    :发给本地进程
FORWARD  :转发(非本机)
OUTPUT   :本机发出
POSTROUTING:离开前(SNAT 在这里)

nftables 的链挂到钩子上:链 = 钩子上的规则列表。

关键理解:

- 本机访问本机:走 INPUT(收)+ OUTPUT(发)
- 路由器/网关转发:走 FORWARD
- NAT 与过滤分工:过滤看钩子,NAT 改头地址

记忆:Linux 防火墙 = Netfilter 五钩子(PREROUTING/INPUT/FORWARD/OUTPUT/POSTROUTING);本机走 INPUT+OUTPUT、转发走 FORWARD、DNAT 在 PREROUTING、SNAT 在 POSTROUTING。


2. nftables vs iptables:架构与语法

为什么换 nftables:

① iptables 四表五链硬编码,nftables 自定义表/链
② nftables 集合批量管理,iptables 逐条生写
③ nftables 单二进制统一 ip/ip6/arp/bridge,iptables 有 6 个工具
④ nftables 内核态更简洁、性能更好(线性扫描优化)

语法对比:

# iptables(逐条)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# nftables(表/链/规则三段式)
nft add rule inet filter input tcp dport 22 accept

核心差异:

- iptables:-t 表 -A 链 ... -j 动作
- nft:    add rule [族] 表 链 匹配... 动作
- nft 的规则即表达式链:匹配 + 动作同一条

兼容:iptables-nft 后端让旧工具转 nftables,但新项目直接用 nft。

记忆:nftables 赢在三处——表链自定义、集合批量、单二进制统一族;语法从 iptables 的 -t/-A/-j 变成 nft 的 add rule 族 表 链 匹配 动作。


3. 表、链与规则:基础操作

三层结构:

族(inet/ip/ip6)→ 表(table)→ 链(chain)→ 规则(rule)

建表建链:

# inet 族同时管 IPv4+IPv6;filter 表名自定义
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; }

添加规则:

# 允许回环与 SSH
nft add rule inet filter input iif "lo" accept
nft add rule inet filter input tcp dport 22 accept
# 默认丢弃(策略)
nft add rule inet filter input drop

查看与删除:

nft list ruleset          # 全部规则
nft list table inet filter
nft delete rule inet filter input handle 12   # 按 handle 删
nft flush table inet filter                    # 清空

优先级与类型:

- filter 链:过滤(priority 0)
- nat 链:NAT(priority -100,先于过滤)
- 同一钩子多个链按优先级先后

记忆:nft 三段式——add table 建表、add chain 挂钩子、add rule 加规则;list ruleset 全览、按 handle 精确删、优先级决定处理顺序。


4. 匹配条件:地址、端口、协议与集合

常用匹配表达式:

# 地址与端口
nft add rule inet filter input ip saddr 192.168.1.0/24 accept
nft add rule inet filter input tcp dport { 80, 443 } accept

# 协议
nft add rule inet filter input ip protocol icmp accept

# 接口与方向
nft add rule inet filter input iif "eth0" accept
nft add rule inet filter output oifname "eth0" accept

集合(Set):把「一组地址/端口」定义成集合,规则引用一次:

# 定义 ip 集合
nft add set inet filter trusted { type ipv4_addr \; }
# 加成员
nft add element inet filter trusted { 10.0.0.1, 10.0.0.2 }
# 引用
nft add rule inet filter input ip saddr @trusted accept

集合的优点:成员增减不改规则本身,批量管理。

区间与通配:nft 支持 10.0.0.1-10.0.0.100 区间、eth* 接口通配。

记忆:匹配四件——ip saddr/daddr、tcp/udp dport、iif/oif 接口、协议;集合 Set 把地址/端口定义成 @集合一次引用,成员动态增删不碰规则。


5. 连接跟踪:conntrack 与有状态规则

无状态防火墙每包单独判——有状态防火墙认「连接」。conntrack 跟踪连接状态:

状态:new(新连接)established(已建立)related(相关)invalid(无效)

有状态规则(最关键的一步):

# 允许已建立/相关连接回应,拒绝无效包
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input ct state invalid drop
# 只放行新的合法连接
nft add rule inet filter input ct state new tcp dport 22 accept

为什么重要:

- 无状态:只放行 dport 80 → 应答流量也得单独放
- 有状态:established 自动放行应答,规则少且安全

conntrack 维护:

conntrack -L          # 查看连接表
nft add rule inet filter input ct state related accept  # FTP/ICMP 相关

注意:conntrack 有表容量上限,高并发 NAT 需调 nf_conntrack_max。

记忆:有状态防火墙认连接——ct state established,related accept 放行应答、ct state invalid drop 拒垃圾包、ct state new 只开新连接;conntrack 表限容量、大并发要调。


6. NAT:SNAT、DNAT 与端口转发

NAT 在 nat 表、nat 链上,改包地址:

nft add table inet nat
nft add chain inet nat postrouting { type nat hook postrouting priority 100 \; }
nft add chain inet nat prerouting  { type nat hook prerouting  priority -100 \; }

SNAT(出网伪装/出口地址转换):

# 内网出网伪装成出口 IP
nft add rule inet nat postrouting ip saddr 192.168.1.0/24 masquerade
# 或固定 IP
nft add rule inet nat postrouting ip saddr 192.168.1.0/24 snat to 203.0.113.5

DNAT(端口转发/入站映射):

# 外部 8080 → 内部 10.0.0.10:80
nft add rule inet nat prerouting tcp dport 8080 dnat to 10.0.0.10:80

masquerade vs SNAT:

- masquerade:自动取出口 IP(适合 DHCP/动态出口)
- snat to:固定出口 IP(适合固定公网 IP)

回环问题:内网访问自己映射的公网地址走 PREROUTING,需额外规则或 hairpin。

记忆:NAT 三类——postrouting 出口 masquerade/SNAT、prerouting 入站 DNAT 端口转发;动态出口用 masquerade、固定 IP 用 snat;内网回环访问要另加规则。


7. 集合与 Maps:动态管理与黑名单

**集合(Set)**适合「名单」,Maps 适合「名单→动作/地址」的映射。

动态黑名单(add 触发):

# 集合:动态加 IP 进黑名单即封禁
nft add set inet filter blacklist { type ipv4_addr \; }
nft add rule inet filter input ip saddr @blacklist drop

# 运维时封禁
nft add element inet filter blacklist { 1.2.3.4 }

Maps(映射):命中名单执行对应动作或转到对应地址:

# IP → 动作 的 map
nft add map inet filter dmz { type ipv4_addr : verdict \; }
nft add rule inet filter input ip saddr @dmz

# 端口 → 目标 的 map(批量端口转发)
nft add map inet nat dports { type inet_service : ipv4_addr . inet_service \; }
nft add element inet nat dports { 80 : 10.0.0.10 . 80, 443 : 10.0.0.10 . 443 }
nft add rule inet nat prerouting tcp dport @dports dnat to @dports

批量管理的优势:几十条规则 → 一个 map,内核线性扫描更短。

记忆:Set 管名单(黑名单动态 add element 即封)、Map 管映射(IP/端口 → 动作/目标,批量转发一条规则);集合让防火墙从逐条生写变成数据驱动。


8. 常见防护场景:Web、服务与微隔离

场景一:Web 服务器最小规则集:

nft add table inet web
nft add chain inet web input { type filter hook input priority 0 \; }
nft add rule inet web input iif "lo" accept
nft add rule inet web input ct state established,related accept
nft add rule inet web input ct state invalid drop
nft add rule inet web input tcp dport { 22, 80, 443 } accept
nft add rule inet web input drop

场景二:端口转发网关:见第 6 节,prerouting DNAT + postrouting masquerade。

场景三:微隔离(按接口/网段):

# 应用 A(10.0.0.0/24)→ 应用 B(10.0.1.0/24)只放 8080
nft add rule inet filter forward ip saddr 10.0.0.0/24 ip daddr 10.0.1.0/24 tcp dport 8080 accept
nft add rule inet filter forward ip saddr 10.0.0.0/24 ip daddr 10.0.1.0/24 drop

场景四:防扫描/限速:tcp flags & (fin|syn) == (fin|syn) 丢半开扫描;limit 限速。

记忆:场景四件——Web 放 22/80/443 + established、网关 prerouting+postrouting、微隔离按网段只放必要端口、防扫描用 tcp flags + limit 限速;规则集小而明确最好。


9. 调试与排错:计数器、trace 与持久化

排错第一步:看规则是否命中:

# 给规则加计数器
nft add rule inet filter input tcp dport 80 accept counter
nft list ruleset          # 看到 counter 递增与否

trace 追踪包路径:

nft add rule inet filter input meta nftrace set 1
nft monitor trace        # 实时看包经过每条规则

持久化(开机生效):

# 导出
nft list ruleset > /etc/nftables.conf
# 或 Debian/Ubuntu:nft save > /etc/nftables.conf 后启用 nftables.service
systemctl enable --now nftables

常见问题:

□ 改完立即生效,但重启丢失 → 没持久化
□ 顺序错误(drop 在 accept 前)→ 包被提前丢
□ 忘放 established → 应答流量被丢(连接卡死)
□ 规则没进正确钩子 → NAT 放 prerouting、过滤放 input

回滚:改前 nft list ruleset > backup,出问题 nft flush table + 重灌。

记忆:排错三件——counter 看命中、nftrace set 1 + nft monitor trace 追踪路径、nft list ruleset > /etc/nftables.conf 持久化;顺序、established、正确钩子是最常见三类坑。


10. 速查表与一句话记忆

操作命令
查看全部规则nft list ruleset
建表nft add table inet filter
加链nft add chain inet filter input { type filter hook input priority 0 \\; }
放行nft add rule inet filter input tcp dport 22 accept
有状态nft add rule ... ct state established,related accept
伪装出网nft add rule inet nat postrouting ... masquerade
端口转发nft add rule inet nat prerouting tcp dport 8080 dnat to 10.0.0.10:80
持久化nft list ruleset > /etc/nftables.conf
追踪nft monitor trace

一句话记忆:nftables = Netfilter 五钩子(PREROUTING/INPUT/FORWARD/OUTPUT/POSTROUTING)上的三段式规则——add table 建表、add chain 挂钩子、add rule 匹配+动作;有状态靠 ct state established,related accept 放应答、invalid drop 拒垃圾;NAT 在 nat 表(prerouting DNAT 入站、postrouting SNAT/masquerade 出网);Set/Map 把名单与映射数据化,一条规则管一批;排错用 counter、trace、持久化 /etc/nftables.conf——把防火墙从逐条生写升级为「表 + 集合 + 有状态」的现代防线。


延伸阅读

  • /linux-network-commands/ — 网络配置与连通性排查
  • /linux-security-hardening/ — 系统安全加固体系
  • /linux-containers-isolation/ — 网络命名空间与容器网络
  • /linux-user-permissions/ — root 权限与安全基线
  • [[network]] — 网络协议原理
  • [[security]] — 安全攻防与加固

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「linux」更多文章

  1. Linux 高级文件系统:XFS、Btrfs、ZFS 与存储进阶
  2. Linux 高可用与负载均衡:HAProxy、Keepalived 与集群方案
  3. Linux 虚拟化实战:KVM/QEMU、libvirt、virt-manager 与嵌套虚拟化