nftables使用说明

nftables 使用说明

这份文档根据你提供的内容整理,主要用于服务器上常见的 nftables 防火墙配置。

主要用途:

  1. 封锁 IP
  2. 端口过滤,比如允许或封锁某些端口
  3. 默认封锁所有端口
  4. 做基础的流量限制,限制某个端口或某个 IP 的访问速率

0. nftables 配置流程图

flowchart TD
A[开始] --> B[安装 nftables]
B --> C[确认 SSH 真实端口]
C --> D[编写完整 /etc/nftables.conf]
D --> E[规则中先放行 SSH]
E --> F[再放行回环和已建立连接]
F --> G[按需放行 80 和 443]
G --> H[执行语法检查 nft -c -f /etc/nftables.conf]
H --> I{语法是否通过}
I -- 否 --> J[修正规则文件]
J --> H
I -- 是 --> K[一次性加载 nft -f /etc/nftables.conf]
K --> L[查看规则 sudo nft list ruleset]
L --> M[新开终端测试 SSH 和业务端口]
M --> N{连接是否正常}
N -- 否 --> O[不要关闭当前会话 回滚或修正规则]
N -- 是 --> P[systemctl enable nftables]
P --> Q[完成]

1. 安装 nftables

安装:

sudo apt update
sudo apt install nftables

2. 最基础的启用流程

这里先做一个最基本的规则集,核心思路是:

  1. 创建表
  2. 创建 input
  3. 把默认策略设为 drop
  4. 先放行 SSH
  5. 放行回环接口
  6. 放行已建立连接

3. 最基础的配置步骤

这里先明确一个重要点:

下面这些 sudo nft add ... 命令可以帮助你理解规则是怎么加进去的,适合学习和临时测试。
但如果你是在远程服务器上操作,不推荐在生产环境里慢慢一条一条手动敲,因为你一旦先把默认策略改成 drop,而放行 SSH、回环、已建立连接这些规则还没全部补齐,就可能把当前 SSH 会话直接断掉。

更稳的做法是:

  1. 先把完整规则写到 /etc/nftables.conf
  2. 再用一条命令一次性加载

也就是这种思路:

sudo nft -f /etc/nftables.conf

下面这些分步命令仍然保留,主要用于理解规则结构。

3.1 创建表

sudo nft add table inet filter

3.2 创建链,并设置默认策略为丢弃

sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }

这一步的意思是:

  • 创建一个 input
  • 绑定到输入流量
  • 默认策略是 drop

也就是默认不放行,后面按规则一点一点加允许项。

3.3 先允许 SSH 端口

sudo nft add rule inet filter input tcp dport 22 accept

这里默认先放行 22 端口,也就是 SSH。

如果你的 SSH 端口不是 22,就把 22 改成你自己的端口。

3.4 允许回环接口流量

sudo nft add rule inet filter input iif lo accept

这个是为了允许本机回环接口通信。

3.5 允许已建立的连接继续通信

sudo nft add rule inet filter input ct state established,related accept

这条规则很重要。
例如你当前已经连着 SSH,会话要继续正常通信,就需要允许已建立连接。

4. 一个重要提醒

上面这几条基础命令,实际操作时建议连续完成,不要中间停太久。
尤其是你把默认策略改成 drop 以后,如果没有先放行 SSH,就很容易把自己锁在服务器外面。

建议顺序就是:

  1. 创建表
  2. 创建默认 dropinput
  3. 立刻允许 SSH 端口
  4. 允许回环接口
  5. 允许已建立连接

如果你是在远程服务器上正式操作,还是更推荐直接编辑完整的 /etc/nftables.conf,然后一次性执行:

sudo nft -f /etc/nftables.conf

5. 查看规则是否生效

sudo nft list ruleset

查看后重点看类似这样的结构:

table inet filter {
chain input {
type filter hook input priority filter; policy drop;
tcp dport 22 accept
iif "lo" accept
ct state established,related accept
}
}

这说明:

  • 默认策略是 drop
  • SSH 端口已放行
  • 回环接口已放行
  • 已建立连接已放行

6. 常见规则操作

这里还要注意一个关键点:

nftables 的规则是按顺序匹配的。
也就是说,如果前面已经有一条更宽泛的 accept,那后面再加更具体的 drop,后面的规则可能根本不会生效。

所以在写规则时要特别注意顺序,不是简单地“后加一条 drop 就一定能拦住”。

6.1 添加端口

如果只是放行一个端口,把 22 改成你要的端口即可:

sudo nft add rule inet filter input tcp dport 22 accept

添加多个端口

sudo nft add rule inet filter input tcp dport {22, 80} accept

也就是同时放行 2280

6.2 查看 nftables 规则

sudo nft list ruleset

6.3 允许单个 IP 访问所有端口

sudo nft add rule inet filter input ip saddr 192.168.1.100 accept

6.4 允许多个 IP 访问所有端口

这里分三步:

  1. 创建一个 allowed_ips 集合
  2. 往集合里加入 IP
  3. 放行这个集合里的 IP
sudo nft add set inet filter allowed_ips { type ipv4_addr\; }
sudo nft add element inet filter allowed_ips { 192.168.1.100, 192.168.1.101 }
sudo nft add rule inet filter input ip saddr @allowed_ips accept

6.5 允许单个 IP 访问特定端口

sudo nft add rule inet filter input ip saddr 192.168.1.100 tcp dport {22, 80} accept

6.6 允许多个 IP 访问特定端口

sudo nft add rule inet filter input ip saddr {192.168.1.100, 192.168.1.101} tcp dport {22, 80} accept

6.7 封锁 IP 或端口

accept 改成 drop,基本就可以理解为禁止。

例如:

sudo nft add rule inet filter input ip saddr 192.168.1.100 drop
sudo nft add rule inet filter input ip saddr {192.168.1.100, 192.168.1.101} drop
sudo nft add rule inet filter input ip saddr 192.168.1.100 tcp dport {22, 80} drop
sudo nft add rule inet filter input ip saddr {192.168.1.100, 192.168.1.101} tcp dport {22, 80} drop

7. 流量限制

你原本提到 nftables 还可以做流量限制,用来限制某个端口或某个 IP 的访问速率,防止 DDoS 攻击。

这一点确实可以做,但你给的内容里还没有具体规则示例。
所以这里先不乱补一套命令,避免直接给出不合适的限速规则。

如果你后面要,我可以再单独给你补一版:

  1. 按 IP 限速
  2. 按端口限速
  3. SSH 防爆破限速
  4. Web 端口基础限速

8. 推荐的持久化方式

如果你是新机器初始化,最推荐的方式不是先执行很多临时规则再导出,而是:

  1. 直接把完整规则写进 /etc/nftables.conf
  2. sudo nft -f /etc/nftables.conf 测试加载
  3. 确认没问题后启用 nftables 服务

你前面那些 sudo nft add rule ... 的方式,更适合临时试验或学习规则写法。

9. 规则持久化

如果你临时加了规则,想让系统重启后依然生效,就要做持久化。

8.1 导出当前规则

sudo nft list ruleset > /etc/nftables.conf

9.2 创建或编辑 systemd 服务文件

sudo vim /etc/systemd/system/nftables.service

添加以下内容:

[Service]
ExecStart=/usr/sbin/nft -f /etc/nftables.conf

你原来的说明里还提到:

  • ExecStartExecReload 指定了 nftables 服务如何启动和重载规则
  • WantedBy=multi-user.target 确保系统启动时自动加载

不过这里要注意一点:
你给出的服务文件内容并不完整,只写一个 [Service] 段通常不够做成完整可启用的 systemd 单元。
如果系统本身已经安装了 nftables 包,很多 Debian / Ubuntu 环境其实已经自带 nftables.service,一般直接启用即可,不一定要手工重写整个 service 文件。

所以更稳的做法通常是直接:

sudo systemctl enable nftables
sudo systemctl restart nftables

9.3 重新加载 systemd

如果你真的改了 service 文件,再执行:

sudo systemctl daemon-reload
sudo systemctl restart nftables

9.4 设置开机自启

sudo systemctl enable nftables

这样系统启动时会自动加载规则。

10. 重启后验证

重启系统后,执行:

sudo nft list ruleset

这会列出当前已经加载的规则。

11. 最常用的一套基础思路

如果只是做最基础的服务器防火墙,通常就是:

  1. 默认 drop
  2. 先允许 SSH
  3. 允许回环接口
  4. 允许已建立连接
  5. 按需再放行 80443 等业务端口
  6. 规则确认无误后做持久化

12. 使用时最需要注意的事

11.1 先放行 SSH,再做默认封锁

如果顺序反了,你很容易把自己锁在服务器外面。

11.2 改了 SSH 端口,就要同步改防火墙

如果你 SSH 不是 22,那规则里的 22 一定要改成你自己的真实端口。

11.3 先测试,再退出当前会话

不管是新规则还是新端口,先新开一个终端测试成功,再关旧会话。

11.4 持久化前先确认规则正确

不然你把错误规则保存进去,重启后会更麻烦。