在Ubuntu系统中实现状态防火墙并统计流量,nftables是当前最推荐的工具。它取代了传统的iptables,提供了更简洁的语法、更高的性能以及统一的管理框架。本文将详细讲解如何在Ubuntu 20.04 LTS及更新版本上,使用nftables配置一个具备连接状态跟踪、数据包计数和基础防护功能的防火墙。
理解nftables的核心概念:表、链与规则
nftables的配置围绕三个核心层级展开。表(Table)是最高层级,用于隔离不同的协议族,例如ip(IPv4)、ip6(IPv6)、inet(同时处理IPv4和IPv6)以及arp、bridge等。链(Chain)存在于表中,是规则的容器,分为基础链和常规链。基础链是网络数据包的入口点,需要绑定钩子(hook)和优先级。规则(Rule)则包含具体的匹配表达式和判决动作。理解这个结构是进行有效配置的前提。
安装与基本配置初始化
Ubuntu通常预装了nftables。如果没有,可以使用sudo apt update && sudo apt install nftables进行安装。首先,建议清除所有现有规则并加载一个干净的配置。备份现有规则后,使用sudo nft flush ruleset清空。然后,创建一个初始配置文件,例如/etc/nftables.conf。我们将主要使用inet协议族来同时管理IPv4和IPv6流量,这能简化双栈网络的配置。
构建一个具备状态跟踪的基础防火墙
状态防火墙的核心是能够识别数据包属于一个新连接、已建立的连接还是相关的连接(如ICMP错误或FTP数据通道)。nftables内置了连接跟踪系统(conntrack)。以下是一个基础防火墙配置框架,定义了输入(input)、转发(forward)和输出(output)策略,并默认丢弃所有流量。
#!/usr/sbin/nft -f
flush ruleset
table inet firewall {
chain input {
type filter hook input priority filter; policy drop;
# 允许本地回环接口流量
iif "lo" accept
ct state established,related accept
# 允许ICMP(ping)
ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } accept
ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply, destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept
# 允许SSH(端口22)和HTTP/HTTPS(端口80,443)的入站新连接
tcp dport { 22, 80, 443 } ct state new accept
# 记录并丢弃所有其他入站流量
log prefix "[nftables] Denied INPUT: " group 0
counter drop
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
log prefix "[nftables] Denied FORWARD: " group 0
counter drop
}
chain output {
type filter hook output priority filter; policy accept;
ct state established,related accept
}
}这个配置中,input链默认丢弃,但允许回环、已建立/相关的连接、必要的ICMP协议以及访问22、80、443端口的新TCP连接。forward链在作为网关时有用,此处也设为默认丢弃。output链默认允许,确保系统发出的流量不受阻。
实现精确的流量计数与监控
nftables的计数器(counter)功能强大且易于使用。你可以将计数器附加到任何规则上,也可以创建独立的计数器对象供多条规则引用。这对于分析流量模式、排查问题至关重要。以下是如何在规则中内联使用计数器,并创建命名计数器。
table inet firewall {
# 创建一个名为"web_traffic"的命名计数器
counter web_traffic {
packets 0 bytes 0
}
chain input {
type filter hook input priority filter; policy drop;
# 内联计数器:统计所有SSH连接尝试
tcp dport 22 ct state new counter accept
# 使用命名计数器:统计HTTP/HTTPS流量
tcp dport { 80, 443 } ct state new counter name "web_traffic" accept
# 计数器记录被拒绝的SYN包
tcp flags syn ct state new counter log prefix "[nftables] Rejected SYN: " drop
}
}要查看计数器结果,使用命令sudo nft list counters。你可以看到每个计数器的数据包数量和字节总数,这为流量审计提供了量化依据。
高级状态管理与安全加固技巧
除了基本的established和related状态,nftables的连接跟踪还支持更精细的管理。例如,可以限制新建连接的速率以防止洪水攻击,或为特定连接设置更长的超时时间。以下规则展示了如何限制每分钟来自同一IP的新SSH连接不超过3次,并调整HTTP连接的跟踪超时。
table inet firewall {
set ssh_ratelimit {
type ipv4_addr
flags dynamic, timeout
timeout 1m
}
chain input {
type filter hook input priority filter; policy drop;
# SSH连接速率限制
tcp dport 22 ct state new add @ssh_ratelimit { ip saddr } limit rate 3/minute accept
# 调整HTTP连接在跟踪表中的超时为5分钟(默认可能更短)
tcp dport 80 ct state new ct helper set "http" ct timeout set 5m accept
}
}此外,建议显式地丢弃无效状态的数据包以提升安全:ct state invalid drop。对于面向公网的服务器,考虑使用ip daddr != { 私有网段 }等条件来限制管理端口的源IP范围。
规则的持久化与运维管理
测试规则无误后,必须将其持久化,否则重启后会丢失。在Ubuntu中,nftables服务会从/etc/nftables.conf读取配置。将最终配置写入该文件,然后执行sudo systemctl enable --now nftables启用服务。日常运维中,常用命令包括:sudo nft list ruleset(查看所有规则)、sudo nft flush chain inet firewall input(清空特定链)、sudo nft monitor trace(实时跟踪规则匹配,用于深度调试)。
与iptables的对比及迁移建议
虽然iptables在旧系统中仍可使用,但nftables在架构上优势明显。其语法更统一(IPv4/IPv6合一),规则集可像编程一样使用变量和集合,执行效率也因更少的内核模块依赖而更高。对于新部署的Ubuntu系统,应直接采用nftables。对于已有iptables规则的系统,可以使用iptables-translate和ip6tables-translate工具进行辅助迁移,但复杂规则仍需手动调整和测试。
总结来说,在Ubuntu上使用nftables构建状态防火墙是一个高效且面向未来的选择。通过定义清晰的表结构、利用连接跟踪状态、灵活运用计数器进行监控,并实施速率限制等高级策略,你可以构建一个既安全又可观测的防火墙系统。关键在于理解数据包流经钩子的路径,并在此基础上编写精确的匹配规则。
