nftables 防火墙实战:iptables 的现代接班人,一套规则守住你的 VPS 和家庭服务器
折腾自建服务这几年,服务器的安全防线我换过好…
折腾自建服务这几年,服务器的安全防线我换过好几拨。从最早只会敲一条 iptables -A INPUT -j DROP,到后来靠 Fail2ban 和 UFW 续命,再到最近把主力机全都迁到了 nftables。说实话,迁移之前我也犹豫——iptables 用了这么多年,规则都背熟了,干嘛折腾?真迁完才发现,nftables 这玩意值得早点上手。今天这篇就把它讲透,从为什么换、怎么装,到一套能直接抄的生产级规则,一步步来。
为什么是 nftables,iptables 差在哪
先不吹。iptables 这么多年没白干,稳定、资料多、社区熟。但它有几个祖传毛病,越到后面越难受。
第一是语法反人类。iptables 的匹配条件散落在 -p tcp --dport 22 -m state --state NEW -j ACCEPT 这么长一串里,写的时候要记扩展模块(-m state、-m conntrack),换行、引号、顺序一个都不能错。规则一多,几百行揉在一起,改一条得从头捋一遍。
第二是性能。iptables 每次匹配都要遍历规则链,规则越多越慢;而 nftables 内部用哈希和集合(set)做查找,匹配是 O(1) 级别,几千条规则也不慌。
第三是双栈麻烦。IPv4 和 IPv6 在 iptables 里是两套独立命令(iptables 和 ip6tables),同样的规则要写两遍。nftables 一个框架同时管 v4 和 v6,换一下家族(family)参数就行。
一句话总结:iptables 是「够用但老」,nftables 是「现代且该换了」。内核从 3.13 起就支持 nftables,现在主流发行版默认都带,没有理由不学。
安装与现状检查
绝大多数现代发行版已经内置 nftables。先确认一下:
nft --version
如果提示找不到命令,装一下(Debian/Ubuntu):
sudo apt update && sudo apt install -y nftables
顺便看看当前有没有残留的 iptables 规则(迁移前最好清空,避免两套打架):
sudo iptables -L -n -v
如果是全新机器,基本是空的,直接开始。
一套能直接用的生产级规则
我习惯把规则写成一个文件,然后一次性加载,这样可读、可做版本管理、可回滚。新建 /etc/nftables.conf,贴入下面这套(注释我写清楚了,按需改):
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
# 定义一个集合,用来放要封禁的 IP,随时往里面加
set blacklist {
type ipv4_addr
flags timeout
}
chain input {
type filter hook input priority 0; policy drop;
# 回环接口全放行
iif lo accept
# 已建立、相关的连接直接放行,保证正常通信不断
ct state established,related accept
# 放行 ICMP,方便 ping 和排错
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# 命中黑名单的,直接拒绝
ip saddr @blacklist counter drop
# 允许 SSH(改端口就把 22 换掉)
tcp dport 22 accept
# 允许 HTTP/HTTPS(跑网站才需要)
tcp dport { 80, 443 } accept
# 限速:同 IP 每秒最多新建 10 条连接,防扫描和爆破
ct state new ip saddr limit rate 10/second accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
加载并验证:
sudo nft -f /etc/nftables.conf
sudo nft list ruleset
看得到整张规则表,说明加载成功。确认无误后设置开机自启:
sudo systemctl enable --now nftables
几个高频操作,记这几个就够
临时封一个 IP(比如日志里看到一个疯狂扫端口的):
sudo nft add element inet filter blacklist { 203.0.113.66 timeout 1h }
timeout 1h 表示一小时后自动解封,不用记着去删,比 iptables 的 -A INPUT -s IP -j DROP 舒服太多。
解封某个 IP:
sudo nft delete element inet filter blacklist { 203.0.113.66 }
临时放行某个端口(比如今天要开个 8080 测试):
sudo nft insert rule inet filter input tcp dport 8080 accept
改完记得持久化,否则重启就丢:
sudo nft list ruleset > /etc/nftables.conf
从 iptables 迁移的注意点
- 先备份现有 iptables 规则:
sudo iptables-save > /tmp/iptables.rules,出问题随时sudo iptables-restore < /tmp/iptables.rules回滚。 - iptables 和 nftables 不能同时接管同一台机器的规则,迁移时先
iptables -F清空,再加载 nftables,别让两套叠着跑。 - 有些老教程还在用
-m state,nftables 里统一用ct state(连接跟踪),语义一样但更现代。
安全这事,永远是「够用 + 顺手」才坚持得下去。nftables 语法更清晰、性能更好、双栈统一,一套规则管住 IPv4 和 IPv6,对常年折腾 VPS 和家庭服务器的人来说,早换早省心。上面这套规则拿过去改改端口就能上线,遇到扫端口的小鬼,一条 add element 就能把他送进小黑屋一小时。
