Ubuntu-nftables安装与配置
nftables作为Linux内核中的新一代防火墙系统,已在Ubuntu 22.04及以上版本中成为默认的防火墙框架。相比传统的iptables,nftables提供了更简洁的语法、更高的性能和更强大的功能,能够满足现代网络环境下的各种需求。本文将从基础概念入手,详细讲解如何在Ubuntu系统上安装、配置和管理nftables,帮助读者构建一个高效、灵活的防火墙系统。
一、nftables与iptables的区别及Ubuntu现状
nftables是iptables、ip6tables、arptables和ebtables的继承者,于2013年引入Linux内核。在Ubuntu 22.04及以上版本中,默认通过iptables-nft兼容层支持nftables,这意味着用户仍然可以使用iptables命令,但实际是由xtables-nft-multi工具转换为nftables规则进行管理。这种设计使得从iptables迁移到nftables变得平滑,同时保留了nftables的优势。
与iptables相比,nftables主要有以下优势:
统一管理:nftables使用单一的工具(nft命令)管理IPv4、IPv6、ARP和桥接流量,而iptables需要多个不同的工具(iptables、ip6tables等)。
简洁语法:nftables的规则语法更接近自然语言,例如可以使用一条规则处理多个协议字段,如
meta l4proto { tcp, udp }
,而iptables需要多条规则。性能优化:nftables使用更高效的规则匹配算法,能够处理更高的数据包吞吐量,同时占用更少的系统资源。
可扩展性:nftables支持集合(sets)和映射(maps),可以处理大量动态变化的IP地址或端口,而iptables在处理此类情况时较为繁琐。
桥接支持:nftables原生支持桥接流量管理,无需依赖ebtables,这在虚拟化环境中尤为重要。
在Ubuntu系统中,nftables已成为未来发展的方向,虽然iptables命令仍然可用,但推荐直接使用nftables以获得最佳性能和功能支持。此外,Ubuntu的ufw工具也已支持nftables后端,用户可以通过简单的命令实现基本的防火墙管理。
二、安装与配置nftables服务
在Ubuntu系统上安装nftables非常简单,可以通过apt包管理器完成。以下是安装和基本配置的步骤:
1. 安装nftables
sudo apt update
sudo apt install nftables
2. 启动并启用nftables服务
sudo systemctl start nftables
sudo systemctl enable nftables
安装完成后,nftables服务会立即启动,并设置为开机自启。此时,系统已经具备了基本的防火墙功能,但默认情况下是空规则集,不会对任何流量进行过滤。
3. 创建并加载规则文件
nftables的规则可以通过命令行直接添加,也可以通过配置文件批量加载。推荐使用配置文件方式,便于管理和持久化。
首先,创建规则文件:
sudo nano /etc/nftables.conf
然后,在文件中添加基本规则:
#!/usr/sbin/nft -f
table ip filter {
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口流量
iifname lo accept
# 允许已建立和相关的连接
ct state established,related accept
# 允许ICMP(ping)流量
ip protocol icmp accept
# 允许SSH连接
tcp dport ssh ct state new accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority 0; policy accept;
# 允许NAT转换(假设eth0是外网接口)
oifname "eth0" masquerade
}
}
保存文件后,加载规则:
sudo nft -f /etc/nftables.conf
4. 持久化规则
nftables的规则在重启后默认不会保留,需要手动持久化。可以通过以下命令将当前规则集保存到配置文件:
sudo nft list ruleset > /etc/nftables.conf
这样,在系统重启或服务重新加载时,规则会从配置文件中读取并应用。
5. 验证配置
sudo nft list ruleset
执行上述命令会列出所有已加载的规则,确保配置正确生效。如果输出显示了之前创建的表、链和规则,则表示配置成功。
三、基础操作与常用命令
nftables提供了一套完整的命令行工具,用于管理防火墙规则。以下是常用的基本操作和命令:
1. 查看规则
# 查看所有表、链和规则
sudo nft list ruleset
# 查看特定表
sudo nft list table ip filter
# 查看特定链
sudo nft list chain ip filter input
2. 添加规则
# 添加允许HTTP流量的规则
sudo nft add rule ip filter input tcp dport 80 accept
# 添加允许HTTPS流量的规则
sudo nft add rule ip filter input tcp dport 443 accept
# 添加限制SSH连接速率的规则(每秒最多10个新连接)
sudo nft add rule ip filter input tcp dport ssh ct state new limit rate 10/second accept
3. 删除规则
# 根据规则编号删除
sudo nft list chain ip filter input --line-numbers
sudo nft delete rule ip filter input 3
# 根据规则描述删除
sudo nft delete rule ip filter input tcp dport 80 accept
4. 修改规则
# 修改允许HTTP流量的规则为仅限特定IP
sudo nft add rule ip filter input ip saddr 192.168.1.0/24 tcp dport 80 accept position 2
5. 加载/刷新规则
# 从配置文件加载规则
sudo nft -f /etc/nftables.conf
# 刷新所有规则(慎用)
sudo nft flush ruleset
6. 高级操作
# 创建集合(用于处理大量IP或端口)
sudo nft add set ip filter drop_ips { type ip saddr; flags dynamic; }
# 将IP添加到集合
sudo nft add element ip filter drop_ips { 192.168.1.100, 10.0.0.0/24 }
# 使用集合的规则
sudo nft add rule ip filter input ip saddr @drop_ips drop
7. 日志记录
# 添加日志记录规则
sudo nft add rule ip filter input ct state invalid log prefix "Invalid-Input: " level debug
sudo nft add rule ip filter input tcp dport ssh ct state new log prefix "New SSH connection: "
# 查看日志
sudo tail -f /var/log/syslog | grep "Invalid-Input: "
通过这些基本操作,可以实现防火墙规则的动态管理,无需重启服务即可应用变更。nftables的规则是即时生效的,这一点与iptables有所不同,使得调试和测试规则更加便捷。
四、实际应用场景案例
1. 基础防火墙配置
以下是一个完整的基础防火墙配置示例,包括允许SSH、HTTP、HTTPS、ICMP等常用服务:
#!/usr/sbin/nft -f
# 创建filter表
table ip filter {
# 输入链(处理进入系统的流量)
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口流量
iifname lo accept
# 允许已建立和相关的连接
ct state established,related accept
# 允许ICMP(ping)流量
ip protocol icmp accept
# 允许SSH连接
tcp dport ssh ct state new accept
# 允许HTTP/HTTPS流量
tcp dport { 80, 443 } ct state new accept
# 允许DNS流量
meta l4proto { tcp, udp } ip dport 53 ct state new accept
# 允许本地网络流量
ip saddr 192.168.1.0/24 accept
# 拒绝其他所有流量
drop
}
# 转发链(处理经过系统的流量)
chain forward {
type filter hook forward priority 0; policy drop;
}
# 输出链(处理从系统出去的流量)
chain output {
type filter hook output priority 0; policy accept;
}
}
将上述规则保存到/etc/nftables.conf
文件中,并通过sudo nft -f /etc/nftables.conf
命令加载,即可实现一个基本的安全防火墙。
2. NAT转换配置
在Ubuntu系统作为路由器使用时,需要配置NAT以实现内网设备访问外网。以下是NAT配置示例:
#!/usr/sbin/nft -f
# 创建NAT表
table ip nat {
# 预路由链(处理进入系统的流量)
chain prerouting {
type nat hook prerouting priority 0; policy accept;
}
# 后路由链(处理离开系统的流量)
chain postrouting {
type nat hook postrouting priority 0; policy accept;
# 允许地址转换(假设eth0是外网接口,br0是内网桥接接口)
oifname "eth0" ip saddr 192.168.1.0/24 counter masquerade
}
}
加载规则后,内网设备(IP地址范围192.168.1.0/24)可以通过Ubuntu系统访问互联网。记得同时启用IP转发功能:
sudo sysctl -w net.ipv4.ip_forward=1
3. 端口转发配置
端口转发(DNAT)允许将外部请求转发到内网服务器。以下是一个将外部8080端口转发到内网192.168.1.100:80的示例:
#!/usr/sbin/nft -f
# 创建NAT表(如果不存在)
table ip nat {
# 预路由链(处理入站流量)
chain prerouting {
type nat hook prerouting priority 0; policy accept;
# 将外部8080端口的HTTP请求转发到内网服务器
iifname "eth0" tcp dport 8080 dnat to 192.168.1.100:80
}
# 转发链(处理经过系统的流量)
chain forward {
type filter hook forward priority 0; policy drop;
# 允许转发到内网服务器的HTTP流量
ip daddr 192.168.1.100 tcp dport 80 accept
}
# 后路由链(处理出站流量)
chain postrouting {
type nat hook postrouting priority 0; policy accept;
# 允许地址转换(假设eth0是外网接口)
oifname "eth0" ip saddr 192.168.1.0/24 counter masquerade
}
}
加载上述规则后,外部用户访问Ubuntu系统的8080端口时,请求会被转发到内网的192.168.1.100服务器的80端口。
4. 桥接网络配置
在虚拟化环境中,Ubuntu系统常作为桥接路由器使用,需要配置桥接接口的防火墙规则。以下是一个桥接网络配置示例:
#!/usr/sbin/nft -f
# 创建filter表
table ip filter {
# 输入链(处理进入系统的流量)
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口流量
iifname lo accept
# 允许已建立和相关的连接
ct state established,related accept
# 允许桥接接口的流量
iifname "br0" accept
# 其他规则...
}
# 转发链(处理经过系统的流量)
chain forward {
type filter hook forward priority 0; policy drop;
# 允许桥接接口之间的流量
iifname "br0" oifname "eth0" accept
iifname "eth0" oifname "br0" accept
# 其他规则...
}
}
在Ubuntu系统中配置桥接网络后,需要确保防火墙规则允许桥接流量通过。桥接网络的流量处理与传统网络不同,需要特别关注接口匹配条件。
5. 流量控制与DDoS防护
nftables支持流量控制和速率限制,这对于防止DDoS攻击非常有用。以下是一个限制HTTP请求速率的示例:
#!/usr/sbin/nft -f
# 创建filter表
table ip filter {
# 输入链(处理进入系统的流量)
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口流量
iifname lo accept
# 允许已建立和相关的连接
ct state established,related accept
# 限制HTTP请求速率(每秒最多50个新连接)
meta l4proto tcp tcp dport 80 ct state new limit rate 50/second burst 100 packets accept
# 允许SSH连接
tcp dport ssh ct state new accept
# 允许其他流量...
}
# 其他链...
}
上述规则会限制对80端口(HTTP)的新连接速率,每秒最多50个新连接,突发最多100个包。这可以有效防止简单的DDoS攻击。
6. 安全防护(IPS能力)
nftables可以实现基本的入侵防御系统(IPS)功能,通过阻止已知恶意端口或IP来增强系统安全性。以下是一个阻止勒索病毒常用端口的示例:
#!/usr/sbin/nft -f
# 创建filter表
table ip filter {
# 输入链(处理进入系统的流量)
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口流量
iifname lo accept
# 允许已建立和相关的连接
ct state established,related accept
# 允许ICMP(ping)流量
ip protocol icmp accept
# 允许SSH连接
tcp dport ssh ct state new accept
# 阻止已知恶意端口
meta l4proto tcp tcp dport { 135, 137, 139, 445, 1433, 1434, 3389 } ct state new drop
meta l4proto udp udp dport { 135, 137, 139, 445, 1433, 1434, 3389 } ct state new drop
# 允许其他流量...
}
# 其他链...
}
上述规则会阻止对已知勒索病毒常用端口(如135、137、139、445等)的连接尝试,提供额外的安全层。
五、高级功能与技巧
1. 动态集合管理
nftables的集合(sets)功能允许动态管理大量IP或端口,非常适合处理频繁变化的黑名单或白名单:
# 创建IP集合
sudo nft add set ip filter drop_ips { type ip saddr; flags dynamic; }
# 将IP添加到集合
sudo nft add element ip filter drop_ips { 192.168.1.100, 10.0.0.0/24 }
# 使用集合的规则
sudo nft add rule ip filter input ip saddr @drop_ips drop
集合可以通过脚本或API动态更新,无需重新加载整个规则集,提高了管理效率。
2. 基于连接跟踪的状态管理
nftables的连接跟踪(connection tracking)功能允许更精细地控制流量状态:
#!/usr/sbin/nft -f
# 创建filter表
table ip filter {
# 输入链(处理进入系统的流量)
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口流量
iifname lo accept
# 允许已建立和相关的连接
ct state established,related accept
# 允许新连接
ct state new accept
# 其他规则...
}
# 其他链...
}
通过ct state
匹配,可以区分新连接、已建立连接和相关连接,实现更智能的流量管理。
3. 多协议统一管理
nftables的inet地址族(address family)允许同时管理IPv4和IPv6流量:
#!/usr/sbin/nft -f
# 创建inet表(同时管理IPv4和IPv6)
table inet filter {
# 输入链(处理进入系统的流量)
chain input {
type filter hook input priority 0; policy drop;
# 允许本地回环接口流量
iifname lo accept
# 允许已建立和相关的连接
ct state established,related accept
# 允许ICMP(ping)流量
meta protocol icmp accept
# 允许SSH连接
meta protocol tcp tcp dport ssh ct state new accept
# 允许HTTP/HTTPS流量
meta protocol { tcp, udp } meta l4proto { tcp, udp } tcp dport { 80, 443 } ct state new accept
# 其他规则...
}
# 其他链...
}
使用inet
地址族可以简化IPv4和IPv6的双重配置,提高管理效率。
4. 防火墙规则调试
nftables提供了强大的调试工具,帮助用户理解规则如何处理数据包:
# 启用数据包跟踪
sudo nft add rule ip filter input meta nftrace set 1
# 监控数据包跟踪结果
sudo nft monitor trace
通过跟踪功能,可以实时查看数据包如何被规则处理,便于调试复杂规则集。
六、常见问题与解决方案
1. 规则不生效
原因:规则语法错误、规则顺序不正确或表/链未正确加载。
解决方案:
- 使用
nft list ruleset
检查规则是否正确加载。 - 确保规则按照正确的顺序排列(nftables按顺序处理规则,第一个匹配的规则会生效)。
- 确认表和链的名称、类型和钩子是否正确。
2. 规则冲突
原因:多个规则同时匹配同一数据包,导致处理结果不确定。
解决方案:
- 使用
counter
语句统计每个规则匹配的数据包数量,找出高频匹配的规则。 - 重新排列规则顺序,确保更具体的规则优先于更通用的规则。
- 使用
log
语句记录被拒绝的连接尝试,便于分析和调整规则。
3. 桥接网络规则不生效
原因:桥接网络的流量处理与传统网络不同,需要特别配置。
解决方案:
- 在
bridge
表中配置桥接流量规则。 - 确保规则中使用桥接接口名称而非物理接口名称。
- 对于桥接网络,通常需要同时配置
filter
和nat
表的规则。
4. 规则加载失败
原因:规则文件语法错误或权限问题。
解决方案:
- 使用
nft -f /etc/nftables.conf
加载规则时,nftables会提供详细的错误信息。 - 检查规则文件的语法是否正确,特别是花括号和分号的使用。
- 确保规则文件具有正确的权限(通常为644)。
七、总结与最佳实践
nftables作为Linux新一代防火墙工具,提供了更简洁、更高效、更强大的网络流量管理能力。在Ubuntu系统上,掌握nftables的使用方法对于构建安全、高效的网络环境至关重要。
在使用nftables时,建议遵循以下最佳实践:
最小权限原则:默认策略设为
drop
,只允许必要的流量通过。分层配置:将规则按功能分组,便于管理和维护。
使用集合和映射:对于大量IP或端口,使用集合动态管理,提高效率。
日志记录:对关键规则添加日志功能,便于分析和调试。
定期审计:定期检查和更新规则集,确保安全性。
性能监控:使用
nft monitor
监控规则性能,及时调整。
通过本文的详细指导,读者应该能够从零开始构建一个基于nftables的Ubuntu防火墙系统,并根据实际需求进行定制化配置。随着nftables在Ubuntu上的普及,掌握这一工具将成为Linux系统管理员必备的技能。