nftables 是 Linux 内核中的新一代数据包过滤框架,旨在替代传统的 iptables。它提供了更简洁的语法、更好的性能和更多的功能。
基础概念
主要组件
-
表 (Tables):规则的容器,类似于数据库中的表
-
链 (Chains):规则的集合,类似于iptables中的链
-
规则 (Rules):具体的过滤条件
-
集合 (Sets):命名的元素集合,用于高效匹配
与 iptables 对比
-
统一的配置语法
-
更好的性能
-
支持匿名集合和映射
-
更简洁的规则管理
安装与基本配置
安装 nftables
Ubuntu/Debian:
<span class="token function">sudo</span> <span class="token function">apt</span> update
<span class="token function">sudo</span> <span class="token function">apt</span> <span class="token function">install</span> nftables
CentOS/RHEL:
<span class="token function">sudo</span> yum <span class="token function">install</span> nftables
<span class="token comment"># 或对于较新版本</span>
<span class="token function">sudo</span> dnf <span class="token function">install</span> nftables
启动服务
<span class="token comment"># 启动服务</span>
<span class="token function">sudo</span> systemctl start nftables
<span class="token comment"># 设置开机自启</span>
<span class="token function">sudo</span> systemctl <span class="token builtin class-name">enable</span> nftables
<span class="token comment"># 检查状态</span>
<span class="token function">sudo</span> systemctl status nftables
基本语法结构
基本命令格式
nft <span class="token punctuation">[</span>选项<span class="token punctuation">]</span> 命令 <span class="token punctuation">[</span>对象<span class="token punctuation">]</span> 规则
常用选项
-
add- 添加规则 -
delete- 删除规则 -
list- 列出规则 -
flush- 清空规则
常用规则实例
1. 基本防火墙配置
创建简单的防火墙表
<span class="token comment"># 创建表</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> table inet filter
<span class="token comment"># 创建输入链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet filter input <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook input priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy drop <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 创建输出链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet filter output <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook output priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy accept <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 创建转发链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet filter forward <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook forward priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy drop <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
保存配置
<span class="token comment"># 保存当前规则</span>
<span class="token function">sudo</span> nft list ruleset <span class="token operator">></span> /etc/nftables.conf
<span class="token comment"># 使配置永久生效(系统启动时加载)</span>
<span class="token builtin class-name">echo</span> <span class="token string">'include "/etc/nftables.conf"'</span> <span class="token operator">></span> /etc/sysconfig/nftables.conf
2. 常用防火墙规则
允许本地回环
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input iifname <span class="token string">"lo"</span> accept
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter output oifname <span class="token string">"lo"</span> accept
允许已建立的连接
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input ct state established,related accept
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter output ct state established,related accept
允许 SSH 连接
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">22</span> accept
允许 HTTP 和 HTTPS
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token punctuation">{</span><span class="token number">80</span>, <span class="token number">443</span><span class="token punctuation">}</span> accept
允许 DNS 查询
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input udp dport <span class="token number">53</span> accept
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter output udp dport <span class="token number">53</span> accept
3. 网络地址转换 (NAT)
创建 NAT 表
<span class="token comment"># 创建 nat 表</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> table <span class="token function">ip</span> nat
<span class="token comment"># 创建 prerouting 链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain <span class="token function">ip</span> nat prerouting <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> nat hook prerouting priority <span class="token parameter variable">-100</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 创建 postrouting 链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain <span class="token function">ip</span> nat postrouting <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> nat hook postrouting priority <span class="token number">100</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
SNAT 示例(源地址转换)
<span class="token comment"># 将内部网络 192.168.1.0/24 的流量转换为公网 IP</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule <span class="token function">ip</span> nat postrouting <span class="token function">ip</span> saddr <span class="token number">192.168</span>.1.0/24 oifname <span class="token string">"eth0"</span> masquerade
DNAT 示例(目的地址转换)
<span class="token comment"># 将公网 IP 的 80 端口转发到内部服务器</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule <span class="token function">ip</span> nat prerouting iifname <span class="token string">"eth0"</span> tcp dport <span class="token number">80</span> dnat to <span class="token number">192.168</span>.1.100:80
4. 流量限制
限制 SSH 连接频率
<span class="token comment"># 创建限制集合</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> <span class="token builtin class-name">set</span> inet filter ssh_limits <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> ipv4_addr <span class="token punctuation">\</span><span class="token punctuation">;</span> flags <span class="token function">timeout</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 限制 SSH 连接:每分钟最多 3 次新连接</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">22</span> <span class="token function">ip</span> saddr @ssh_limits drop
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">22</span> limit rate <span class="token number">3</span>/minute <span class="token function">add</span> @ssh_limits <span class="token punctuation">{</span> <span class="token function">ip</span> saddr <span class="token punctuation">}</span>
限制 ICMP 请求
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input proto icmp icmp <span class="token builtin class-name">type</span> echo-request limit rate <span class="token number">1</span>/second accept
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input proto icmp icmp <span class="token builtin class-name">type</span> echo-request drop
表、链和规则集管理
表管理
列出所有表
<span class="token function">sudo</span> nft list tables
查看特定表
<span class="token function">sudo</span> nft list table inet filter
删除表
<span class="token function">sudo</span> nft delete table inet filter
链管理
创建自定义链
<span class="token comment"># 创建自定义链用于日志记录</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet filter logchain
<span class="token comment"># 向自定义链添加规则</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter logchain log prefix <span class="token string">"Dropped: "</span> level info
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter logchain drop
跳转到自定义链
<span class="token comment"># 将特定流量跳转到日志链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">23</span> jump logchain
规则管理
列出所有规则
<span class="token function">sudo</span> nft list ruleset
添加带注释的规则
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">22</span> accept comment <span class="token string">"Allow SSH"</span>
删除规则
<span class="token comment"># 首先找到规则的句柄</span>
<span class="token function">sudo</span> nft <span class="token parameter variable">--handle</span> list chain inet filter input
<span class="token comment"># 然后使用句柄删除规则</span>
<span class="token function">sudo</span> nft delete rule inet filter input handle <span class="token number">3</span>
高级功能
使用集合
定义命名集合
<span class="token comment"># 创建 IP 地址集合</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> <span class="token builtin class-name">set</span> inet filter allowed_ips <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> ipv4_addr <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 向集合添加元素</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> element inet filter allowed_ips <span class="token punctuation">{</span> <span class="token number">192.168</span>.1.100, <span class="token number">192.168</span>.1.200 <span class="token punctuation">}</span>
<span class="token comment"># 使用集合进行匹配</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input <span class="token function">ip</span> saddr @allowed_ips accept
使用匿名集合
<span class="token comment"># 直接在规则中使用匿名集合</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token punctuation">{</span><span class="token number">22</span>, <span class="token number">80</span>, <span class="token number">443</span><span class="token punctuation">}</span> accept
使用映射
创建端口映射
<span class="token comment"># 创建端口转发映射</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> map inet filter port_forward <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> inet_service <span class="token builtin class-name">:</span> ipv4_addr <span class="token builtin class-name">.</span> inet_service <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 添加映射条目</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> element inet filter port_forward <span class="token punctuation">{</span> <span class="token number">8080</span> <span class="token builtin class-name">:</span> <span class="token number">192.168</span>.1.100 <span class="token builtin class-name">.</span> <span class="token number">80</span> <span class="token punctuation">}</span>
<span class="token comment"># 使用映射进行 DNAT</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule <span class="token function">ip</span> nat prerouting tcp dport map @port_forward dnat to <span class="token function">ip</span> daddr <span class="token builtin class-name">.</span> tcp dport
日志记录
基本日志记录
<span class="token comment"># 记录被拒绝的数据包</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">23</span> log prefix <span class="token string">"Telnet attempt: "</span> drop
带限制的日志记录
<span class="token comment"># 限制日志记录频率</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">23</span> log prefix <span class="token string">"Telnet: "</span> limit rate <span class="token number">3</span>/minute drop
实用脚本示例
完整的家庭防火墙配置
<span class="token shebang important">#!/bin/bash</span>
<span class="token comment"># 清空现有规则</span>
<span class="token function">sudo</span> nft flush ruleset
<span class="token comment"># 创建表</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> table inet firewall
<span class="token comment"># 创建链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet firewall input <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook input priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy drop <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet firewall forward <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook forward priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy drop <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet firewall output <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook output priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy accept <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 允许本地回环</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input iif <span class="token string">"lo"</span> accept
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall output oif <span class="token string">"lo"</span> accept
<span class="token comment"># 允许已建立和相关的连接</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input ct state established,related accept
<span class="token comment"># 允许 ICMP (ping)</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input <span class="token function">ip</span> protocol icmp icmp <span class="token builtin class-name">type</span> echo-request limit rate <span class="token number">1</span>/second accept
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input <span class="token function">ip</span> protocol icmp icmp <span class="token builtin class-name">type</span> echo-request drop
<span class="token comment"># 允许 SSH (限制连接频率)</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> <span class="token builtin class-name">set</span> inet firewall ssh_limit <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> ipv4_addr <span class="token punctuation">\</span><span class="token punctuation">;</span> flags <span class="token function">timeout</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input tcp dport <span class="token number">22</span> <span class="token function">ip</span> saddr @ssh_limit drop
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input tcp dport <span class="token number">22</span> limit rate <span class="token number">3</span>/minute <span class="token function">add</span> @ssh_limit <span class="token punctuation">{</span> <span class="token function">ip</span> saddr <span class="token punctuation">}</span> accept
<span class="token comment"># 允许 HTTP 和 HTTPS</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input tcp dport <span class="token punctuation">{</span><span class="token number">80</span>, <span class="token number">443</span><span class="token punctuation">}</span> accept
<span class="token comment"># 允许 DNS</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input udp dport <span class="token number">53</span> accept
<span class="token comment"># 记录并拒绝其他所有输入流量</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet firewall input log prefix <span class="token string">"Dropped input: "</span> limit rate <span class="token number">3</span>/minute drop
<span class="token comment"># 保存配置</span>
<span class="token function">sudo</span> nft list ruleset <span class="token operator">></span> /etc/nftables.conf
<span class="token builtin class-name">echo</span> <span class="token string">"Firewall configuration completed and saved."</span>
Web 服务器防火墙配置
<span class="token shebang important">#!/bin/bash</span>
<span class="token comment"># 清空规则</span>
<span class="token function">sudo</span> nft flush ruleset
<span class="token comment"># 创建表</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> table inet web_firewall
<span class="token comment"># 创建链</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet web_firewall input <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook input priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy drop <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> chain inet web_firewall output <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> filter hook output priority <span class="token number">0</span> <span class="token punctuation">\</span><span class="token punctuation">;</span> policy accept <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment"># 基本规则</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet web_firewall input iif <span class="token string">"lo"</span> accept
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet web_firewall input ct state established,related accept
<span class="token comment"># Web 服务端口</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet web_firewall input tcp dport <span class="token punctuation">{</span><span class="token number">80</span>, <span class="token number">443</span><span class="token punctuation">}</span> accept
<span class="token comment"># SSH 访问(限制来源 IP)</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> <span class="token builtin class-name">set</span> inet web_firewall allowed_ssh_ips <span class="token punctuation">{</span> <span class="token builtin class-name">type</span> ipv4_addr <span class="token punctuation">\</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> element inet web_firewall allowed_ssh_ips <span class="token punctuation">{</span> <span class="token number">192.168</span>.1.0/24, <span class="token number">203.0</span>.113.50 <span class="token punctuation">}</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet web_firewall input tcp dport <span class="token number">22</span> <span class="token function">ip</span> saddr @allowed_ssh_ips accept
<span class="token comment"># 监控端口</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet web_firewall input tcp dport <span class="token number">9090</span> accept
<span class="token comment"># 保存配置</span>
<span class="token function">sudo</span> nft list ruleset <span class="token operator">></span> /etc/nftables.conf
<span class="token builtin class-name">echo</span> <span class="token string">"Web server firewall configuration completed."</span>
调试和故障排除
查看规则统计信息
<span class="token function">sudo</span> nft list ruleset <span class="token parameter variable">-a</span>
监控实时流量
<span class="token comment"># 查看数据包计数</span>
<span class="token function">sudo</span> nft list ruleset <span class="token operator">|</span> <span class="token function">grep</span> <span class="token parameter variable">-E</span> <span class="token string">"(counter|packets)"</span>
<span class="token comment"># 重置计数器</span>
<span class="token function">sudo</span> nft reset counters
测试规则
<span class="token comment"># 临时添加规则进行测试</span>
<span class="token function">sudo</span> nft <span class="token function">add</span> rule inet filter input tcp dport <span class="token number">8080</span> accept
<span class="token comment"># 测试后删除</span>
<span class="token function">sudo</span> nft delete rule inet filter input handle <span class="token punctuation">[</span>handle-number<span class="token punctuation">]</span>
总结
nftables 提供了强大而灵活的数据包过滤功能,具有以下优势:
-
统一语法:替代 iptables、ip6tables、arptables 和 ebtables
-
更好性能:使用更高效的数据结构
-
动态更新:支持原子规则更新
-
丰富功能:支持集合、映射等高级功能
通过本教程的实例,您可以开始使用 nftables 构建适合自己需求的防火墙配置。建议在生产环境部署前充分测试所有规则。
「点点赞赏,手留余香」
声明:本文为原创文章,版权归旷野小站所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ mysql删除log日志文件命令02/06
- ♥ wordpress网站文章迁移并保留URL和分类标签的方法11/12
- ♥ 实现网站一个目录内的网页跳转到另一个目录的方法06/21
- ♥ FRP简单配置 HTTP 类型的代理让用户访问到内网的 Web 服务12/07
- ♥ nginx 配置:限制连接数02/19
- ♥ Linux的一些常用命令04/15