概述
Linux 防火墙经历了从 ipfwadm → ipchains → iptables → nftables 的演进。底层均基于 Netfilter 框架,但上层语法和管理方式不断改进。从 Netfilter 架构出发,深入 iptables 的五链四表、nftables 的优势与用法、NAT/端口转发、连接追踪机制以及生产环境的性能优化实践。
Netfilter 框架
架构概览
Netfilter 是 Linux 内核中的数据包处理框架,通过在内核网络栈的关键位置挂载钩子(hook)来实现数据包过滤、地址转换、连接追踪等功能。
Netfilter 钩子点
[数据包进入] → PREROUTING → [路由判断] →─┬─→ FORWARD → POSTROUTING → [数据包发出]
│
└─→ INPUT → [本地进程] → OUTPUT → POSTROUTING → [数据包发出]
五大钩子点
| 钩子点 | 触发时机 | 中文含义 |
|---|---|---|
NF_INET_PRE_ROUTING | 数据包进入网络栈,路由前 | 路由前 |
NF_INET_LOCAL_IN | 数据包目的地是本机 | 输入 |
NF_INET_FORWARD | 数据包需要转发到其他接口 | 转发 |
NF_INET_LOCAL_OUT | 本机产生的数据包 | 输出 |
NF_INET_POST_ROUTING | 数据包即将离开网络栈 | 路由后 |
数据包流向
入站(访问本机):
NIC → PREROUTING → INPUT → 本机进程
出站(本机发出):
本机进程 → OUTPUT → POSTROUTING → NIC
转发(经过本机):
NIC → PREROUTING → FORWARD → POSTROUTING → NIC
iptables 五链四表
四张表
iptables 通过"表"来组织不同功能的规则链:
| 表 | 功能 | 链 |
|---|---|---|
raw | 在连接追踪前处理(CONNTRACK 之前) | PREROUTING, OUTPUT |
mangle | 修改数据包的 TTL/TOS/Mark 等 | 全部五链 |
nat | 地址转换(DNAT/SNAT) | PREROUTING, OUTPUT, POSTROUTING, INPUT |
filter | 数据包过滤(ACCEPT/DROP/REJECT) | INPUT, FORWARD, OUTPUT |
表的优先级:raw → mangle → nat → filter。数据包经过每个钩子点时,按此顺序依次匹配各表的规则。
五条链
| 链 | 所属表 | 说明 |
|---|---|---|
INPUT | filter, mangle, nat | 入站数据包 |
OUTPUT | raw, mangle, nat, filter | 出站数据包 |
FORWARD | filter, mangle | 转发数据包 |
PREROUTING | raw, mangle, nat | 路由前 |
POSTROUTING | mangle, nat | 路由后 |
规则匹配流程
数据包进入钩子点
│
▼
[raw 表] ──→ [mangle 表] ──→ [nat 表] ──→ [filter 表]
│ │ │ │
│ │ │ ├─→ ACCEPT(接受)
│ │ │ ├─→ DROP(丢弃,无响应)
│ │ │ ├─→ REJECT(拒绝,返回 ICMP)
│ │ │ └─→ RETURN(返回上一链)
│ │ └─→ DNAT/SNAT
│ └─→ 修改 TTL/TOS/Mark
└─→ NOTRACK(不追踪连接)
基本 iptables 命令
# 查看规则
$ iptables -L -n -v --line-numbers
$ iptables -t nat -L -n -v
# 追加规则
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 插入规则(在第 1 条前插入)
$ iptables -I INPUT 1 -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
# 删除规则
$ iptables -D INPUT 3 # 删除第 3 条
$ iptables -D INPUT -p tcp --dport 22 -j ACCEPT # 按内容删除
# 设置默认策略
$ iptables -P INPUT DROP
$ iptables -P FORWARD DROP
$ iptables -P OUTPUT ACCEPT
常用匹配条件
# 协议匹配
$ iptables -A INPUT -p tcp ...
$ iptables -A INPUT -p udp ...
$ iptables -A INPUT -p icmp ...
# 端口匹配
$ iptables -A INPUT -p tcp --dport 80 # 目标端口
$ iptables -A INPUT -p tcp --sport 1024:65535 # 源端口范围
# IP 匹配
$ iptables -A INPUT -s 10.0.0.0/8 # 源地址
$ iptables -A INPUT -d 192.168.1.1 # 目标地址
# 接口匹配
$ iptables -A INPUT -i eth0 # 入站接口
$ iptables -A OUTPUT -o eth1 # 出站接口
# 连接状态匹配
$ iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 速率限制
$ iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/min --limit-burst 10 -j ACCEPT
# IP 集合
$ iptables -A INPUT -m set --match-set blacklist src -j DROP
# 字符串匹配
$ iptables -A INPUT -p tcp --dport 80 -m string --string "GET /admin" --algo bm -j DROP
# 时间匹配
$ iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
生产环境基础规则集
#!/bin/bash
# /etc/iptables/rules.sh - 生产环境防火墙规则
# 清空所有规则
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许回环
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 允许已建立的连接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 允许 ICMP(限制速率)
iptables -A INPUT -p icmp -m limit --limit 1/s -j ACCEPT
# SSH:允许内网,限制外网速率
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/min --limit-burst 5 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
# Web 服务
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# 监控(Prometheus node_exporter)
iptables -A INPUT -p tcp --dport 9100 -s 10.0.0.100 -j ACCEPT
# 记录被拒绝的连接
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables-dropped: " --log-level 4
iptables -A INPUT -j DROP
# 保存规则
iptables-save > /etc/iptables/rules.v4
nftables
nftables 的优势
| 特性 | iptables | nftables |
|---|---|---|
| 语法 | 分散(iptables/ip6tables/arptables/ebtables) | 统一 |
| 性能 | 每条规则独立 | 规则集批量加载 |
| 规则更新 | 逐条追加,有竞争条件 | 原子替换 |
| 数据类型 | 无类型 | 强类型 |
| 集合 | 有限(ipset) | 原生支持 |
| 映射 | 不支持 | 支持 |
| 表/链 | 固定 | 可自定义 |
| 连接追踪 | conntrack 模块 | 原生 ct 对象 |
nftables 基本概念
# 安装
$ apt install nftables # Debian/Ubuntu
$ dnf install nftables # RHEL/CentOS
# 查看规则集
$ nft list ruleset
表和链
# 创建表(指定协议族)
$ nft add table inet filter # IPv4+IPv6
$ nft add table ip nat # 仅 IPv4
$ nft add table ip6 filter # 仅 IPv6
$ nft add table bridge filter # 桥接
# 协议族
# inet: IPv4 + IPv6(推荐)
# ip: IPv4
# ip6: IPv6
# arp: ARP
# bridge: 桥接
# netdev: 入口(最早,在路由前)
# 创建链
$ nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
$ nft add chain inet filter forward '{ type filter hook forward priority 0; policy drop; }'
$ nft add chain inet filter output '{ type filter hook output priority 0; policy accept; }'
# 创建自定义链
$ nft add chain inet filter log_drop
$ nft add rule inet filter log_drop log prefix "nft-dropped: " counter drop
规则编写
# 基本规则
$ nft add rule inet filter input iifname "lo" accept
$ nft add rule inet filter input ct state established,related accept
$ nft add rule inet filter input icmp type echo-request limit rate 1/second accept
# 端口规则
$ nft add rule inet filter input tcp dport 22 accept
$ nft add rule inet filter input tcp dport { 80, 443 } accept
$ nft add rule inet filter input tcp dport 1000-2000 accept
# 源地址
$ nft add rule inet filter input ip saddr 10.0.0.0/8 tcp dport 22 accept
$ nft add rule inet filter input ip6 saddr fd00::/8 tcp dport 22 accept
# 计数器
$ nft add rule inet filter input tcp dport 80 counter accept
$ nft list ruleset
# tcp dport 80 counter packets 12345 bytes 6789012 accept
集合与映射
# 创建集合
$ nft add set inet filter blacklist '{ type ipv4_addr; flags interval; }'
$ nft add element inet filter blacklist '{ 192.168.1.100, 10.0.0.0/8 }'
# 使用集合
$ nft add rule inet filter input ip saddr @blacklist drop
# 创建映射
$ nft add map inet filter port_map '{ type inet_service : verdict; }'
$ nft add element inet filter port_map '{ 22 : accept, 80 : accept, 443 : accept }'
# 使用映射
$ nft add rule inet filter input tcp dport vmap @port_map
nftables 配置文件
# /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
set blacklist {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8, 192.168.1.100 }
}
chain input {
type filter hook input priority 0; policy drop;
# 回环
iifname "lo" accept
# 已建立连接
ct state established,related accept
# ICMP
icmp type echo-request limit rate 1/second accept
icmpv6 type { echo-request, nd-neighbor-solicit, nd-router-advert } accept
# SSH
tcp dport 22 ip saddr 10.0.0.0/8 accept
tcp dport 22 limit rate 3/minute burst 5 packets accept
# Web
tcp dport { 80, 443 } accept
# 监控
tcp dport 9100 ip saddr 10.0.0.100 accept
# 黑名单
ip saddr @blacklist drop
# 日志和丢弃
limit rate 5/minute log prefix "nft-dropped: " level warn
counter drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
# 加载配置
$ nft -f /etc/nftables.conf
# 启用开机加载
$ systemctl enable nftables
iptables 到 nftables 迁移
# 使用 iptables-nft 后端(兼容层)
$ update-alternatives --set iptables /usr/sbin/iptables-nft
$ update-alternatives --set ip6tables /usr/sbin/ip6tables-nft
# 转换 iptables 规则为 nftables
$ iptables-save > rules.v4
$ iptables-restore-translate -f rules.v4 > rules.nft
$ nft -f rules.nft
# RHEL 8+ 默认使用 nftables 后端
# firewalld 后端配置
# /etc/firewalld/firewalld.conf
FirewallBackend=nftables
NAT 与端口转发
SNAT(源地址转换)
# iptables: 将内网 10.0.0.0/8 的源地址改为公网 IP
$ iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -o eth0 -j SNAT --to-source 203.0.113.1
# MASQUERADE(动态 IP,如 DHCP/PPPoE)
$ iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -o eth0 -j MASQUERADE
# nftables
$ nft add table ip nat
$ nft 'add chain ip nat postrouting { type nat hook postrouting priority 100; }'
$ nft add rule ip nat postrouting ip saddr 10.0.0.0/8 oifname "eth0" masquerade
DNAT(目标地址转换/端口转发)
# iptables: 将访问 203.0.113.1:80 转发到 10.0.0.10:8080
$ iptables -t nat -A PREROUTING -d 203.0.113.1 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.10:8080
$ iptables -t nat -A POSTROUTING -d 10.0.0.10 -p tcp --dport 8080 -j SNAT --to-source 10.0.0.1
$ iptables -A FORWARD -p tcp -d 10.0.0.10 --dport 8080 -j ACCEPT
# 本地端口转发
$ iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 80 -j REDIRECT --to-ports 8080
# nftables
$ nft 'add chain ip nat prerouting { type nat hook prerouting priority -100; }'
$ nft add rule ip nat prerouting tcp dport 80 dnat to 10.0.0.10:8080
端口范围转发
# 将 20000-30000 端口转发到内部服务器
$ iptables -t nat -A PREROUTING -p tcp --dport 20000:30000 -j DNAT --to-destination 10.0.0.10
$ iptables -A FORWARD -p tcp -d 10.0.0.10 --dport 20000:30000 -j ACCEPT
透明代理
# 将所有 HTTP 流量重定向到 Squid 代理(3128 端口)
$ iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-ports 3128
$ iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner squid -j RETURN
$ iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 3128
连接追踪
工作原理
连接追踪(conntrack)记录每个网络连接的状态,用于状态匹配(-m conntrack --ctstate)和 NAT。
连接状态
| 状态 | 说明 |
|---|---|
NEW | 新连接的第一个包 |
ESTABLISHED | 连接已建立(双向通信) |
RELATED | 与已存在连接相关(如 FTP 数据连接、ICMP 错误) |
INVALID | 无法识别的包 |
SNAT/DNAT | 经过 SNAT/DNAT 的连接 |
conntrack 表管理
# 查看 conntrack 表大小
$ cat /proc/sys/net/netfilter/nf_conntrack_max
262144
# 查看当前连接数
$ cat /proc/sys/net/netfilter/nf_conntrack_count
12345
# 查看连接追踪统计
$ cat /proc/net/nf_conntrack | head -20
# src=10.0.0.1 dst=93.184.216.34 sport=54321 dport=443 protocol=tcp state=ESTABLISHED ...
# 统计各状态连接数
$ cat /proc/net/nf_conntrack | awk '{print $4}' | sort | uniq -c | sort -rn
conntrack 超时参数
# 查看超时参数
$ ls /proc/sys/net/netfilter/nf_conntrack_*_timeout_*
/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established # 432000 (5天)
/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_syn_sent # 120
/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_syn_recv # 60
/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_fin_wait # 120
/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait # 120
/proc/sys/net/netfilter/nf_conntrack_udp_timeout # 30
/proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream # 180
# 调整 TCP established 超时(默认 5 天太长)
$ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=86400 # 1 天
$ sysctl -w net.netfilter.nf_conntrack_udp_timeout=15
conntrack 表满的后果
当 conntrack 表满时,新连接会被丢弃,日志中出现:
nf_conntrack: table full, dropping packet
解决:
# 临时增大表大小
$ sysctl -w net.netfilter.nf_conntrack_max=524288
# 永久配置
# /etc/sysctl.d/conntrack.conf
net.netfilter.nf_conntrack_max = 524288
net.netfilter.nf_conntrack_buckets = 131072 # 必须是 2 的幂,通常 = max/4
conntrack 工具
# conntrack 命令行工具
$ apt install conntrack
# 查看连接
$ conntrack -L
# 查看统计
$ conntrack -S
# 删除特定连接
$ conntrack -D -s 10.0.0.1 -p tcp --dport 443
# 清空所有连接
$ conntrack -F
# 实时监控
$ conntrack -E
性能优化
规则顺序优化
iptables 规则按顺序匹配,将高频命中的规则放在前面:
# ❌ 不好的顺序:SSH 在 Web 之后
$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT # 高频但排后面
$ iptables -A INPUT -p tcp --dport 443 -j ACCEPT
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 低频却排前面
# ✅ 好的顺序:按流量从高到低
$ iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 最高频
$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 最高频
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
使用 ipset/nftables 集合
# iptables + ipset:替代多条规则
$ ipset create whitelist hash:net
$ ipset add whitelist 10.0.0.0/8
$ ipset add whitelist 192.168.0.0/16
# 一条规则替代多条
$ iptables -A INPUT -m set --match-set whitelist src -j ACCEPT
# 而非
# iptables -A INPUT -s 10.0.0.0/8 -j ACCEPT
# iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
禁用不需要的连接追踪
# 对不需要 NAT 的流量跳过连接追踪
$ iptables -t raw -A PREROUTING -i lo -j NOTRACK
$ iptables -t raw -A OUTPUT -o lo -j NOTRACK
# 对内网流量跳过连接追踪
$ iptables -t raw -A PREROUTING -s 10.0.0.0/8 -d 10.0.0.0/8 -j NOTRACK
# nftables
$ nft add table inet raw
$ nft 'add chain inet raw prerouting { type filter hook prerouting priority -300; }'
$ nft add rule inet raw prerouting iifname "lo" notrack
使用 SYNPROXY 防 SYN Flood
# 对入站 TCP 连接使用 SYNPROXY
$ iptables -t raw -A PREROUTING -p tcp -m tcp --syn -j CT --notrack
$ iptables -A INPUT -p tcp -m tcp --syn -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
$ iptables -A INPUT -p tcp -m conntrack --ctstate INVALID -j DROP
统计规则命中率
# 查看每条规则的命中次数
$ iptables -L -n -v --line-numbers
# 示例输出
Chain INPUT (policy DROP 56789 packets, 1234KB)
num pkts bytes target prot opt in out source destination
1 9876 456K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
2 1234 56K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
3 87654 12M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
# 根据命中率调整规则顺序:命中次数多的放前面
实战案例
案例 1:Kubernetes Node 防火墙
#!/bin/bash
# K8s 节点防火墙规则
iptables -F
iptables -t nat -F
iptables -X
# 默认策略
iptables -P INPUT DROP
iptables -P FORWARD ACCEPT # K8s 需要转发
iptables -P OUTPUT ACCEPT
# 回环
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i cni0 -j ACCEPT # CNI 网桥
iptables -A INPUT -i docker0 -j ACCEPT # Docker 网桥
# 已建立连接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# K8s 组件
iptables -A INPUT -p tcp --dport 6443 -s 10.0.0.0/8 -j ACCEPT # API Server
iptables -A INPUT -p tcp --dport 10250 -s 10.0.0.0/8 -j ACCEPT # kubelet
iptables -A INPUT -p tcp --dport 10257 -s 10.0.0.0/8 -j ACCEPT # controller-manager
iptables -A INPUT -p tcp --dport 10259 -s 10.0.0.0/8 -j ACCEPT # scheduler
# NodePort 范围
iptables -A INPUT -p tcp --dport 30000:32767 -j ACCEPT
# ICMP
iptables -A INPUT -p icmp -j ACCEPT
# SSH
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
案例 2:容器端口映射原理
Docker 端口映射底层使用 iptables NAT 规则:
# docker run -p 8080:80 nginx 产生的规则
# DNAT: 将宿主机 8080 端口转发到容器 80 端口
$ iptables -t nat -L -n -v | grep 8080
DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
# SNAT: 将容器出站流量源地址改为宿主机 IP
$ iptables -t nat -L POSTROUTING -n -v
MASQUERADE tcp -- * * 172.17.0.2 0.0.0.0/0 masq ports: 80
案例 3:高并发 Web 服务器防火墙优化
#!/bin/bash
# 高并发 Web 服务器(10万+ 连接)
# 1. 调大 conntrack 表
echo 1048576 > /proc/sys/net/netfilter/nf_conntrack_max
echo 262144 > /sys/module/nf_conntrack/parameters/hashsize
# 2. 缩短超时时间
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
sysctl -w net.netfilter.nf_conntrack_udp_timeout=15
# 3. 对 Web 流量跳过连接追踪(仅过滤,不追踪)
iptables -t raw -A PREROUTING -p tcp --dport 80 -j NOTRACK
iptables -t raw -A PREROUTING -p tcp --dport 443 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp --sport 80 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp --sport 443 -j NOTRACK
# 4. 使用无状态过滤(配合 NOTRACK)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
# 5. 限制 SYN 速率
iptables -A INPUT -p tcp --syn --dport 443 -m limit --limit 1000/s --limit-burst 2000 -j ACCEPT
iptables -A INPUT -p tcp --syn --dport 443 -j DROP
案例 4:使用 nftables 实现负载均衡
# 使用 nftables 的 nat 模块实现轮询负载均衡
$ nft add table ip nat
$ nft 'add chain ip nat prerouting { type nat hook prerouting priority -100; }'
# 将 80 端口流量轮询分发到 3 台后端服务器
$ nft add rule ip nat prerouting tcp dport 80 dnat to 10.0.0.{10,11,12}
# 或使用权重
$ nft add rule ip nat prerouting tcp dport 80 dnat numgen inc mod 3 map { 0: 10.0.0.10, 1: 10.0.0.11, 2: 10.0.0.12 }
规则持久化
iptables 持久化
# Debian/Ubuntu
$ apt install iptables-persistent
$ netfilter-persistent save
# 规则保存在 /etc/iptables/rules.v4 和 rules.v6
# RHEL/CentOS
$ iptables-save > /etc/sysconfig/iptables
$ systemctl enable iptables
# 手动保存/恢复
$ iptables-save > /path/to/rules.v4
$ iptables-restore < /path/to/rules.v4
nftables 持久化
# 保存当前规则集
$ nft list ruleset > /etc/nftables.conf
# 开机自动加载
$ systemctl enable nftables
总结
Linux 防火墙从 iptables 到 nftables 的演进,体现了"统一、简化、高性能"的设计方向。核心要点:
- 理解 Netfilter 五大钩子点:PREROUTING → INPUT/OUTPUT/FORWARD → POSTROUTING,是所有规则设计的基础。
- iptables 四表有优先级:raw → mangle → nat → filter,高优先级表先匹配。
- 规则顺序至关重要:高频命中的规则放前面,使用计数器分析命中率并优化顺序。
- nftables 是未来方向:统一语法、原生集合/映射、原子规则替换、更好的性能。
- 连接追踪是性能瓶颈:高并发场景下需要调大
nf_conntrack_max、缩短超时、对不需要追踪的流量使用 NOTRACK。 - ipset/nftables 集合可以大幅减少规则数量:一条规则 + 一个集合替代几十条独立规则。
- NAT 端口转发是常用功能:理解 DNAT + SNAT + FORWARD 的组合才能正确配置端口转发。
- SYNPROXY 是防 SYN Flood 的利器:在内核层面代理三次握手,过滤掉伪造源地址的 SYN 包。
防火墙配置的黄金法则:先放行,再阻断。配置防火墙前,务必确保 SSH 连接不会被意外阻断,否则可能锁死自己。建议设置定时任务在 5 分钟后自动清空规则,作为安全网。