nftables的配置与使用
1 iptables替换为nftables
将 iptables 替换为 nftables 大致涉及几个步骤,包括:
安装 nftables、
迁移现有规则、
配置系统以使用 nftables
禁用 iptables
不推荐使用该转换方法,本次操作失败
1.1 安装nftables
内核版本较新的Linux默认安装了nftables,
apt-get update
apt-get install nftables
1.2 备份现有的iptables规则
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
1.3 迁移iptables规则到nftables
使用 iptables-save 和 iptables-restore 工具将现有的 iptables 规则转换为 nftables 规则格式,并保存到/etc/nftables.conf 文件中
iptables-save | iptables-restore-translate -o /etc/nftables.conf
ip6tables-save | ip6tables-restore-translate -o /etc/nftables.conf --ipv6
1.4 配置nftables
编辑生成的 /etc/nftables.conf 文件,确保其符合需求。
1.5 启用nftables服务
systemctl start nftables
systemctl enable nftables
systemctl status nftables
# 查看当前加载的 nftables 规则
nft list ruleset
1.6 禁用iptables服务
为了确保 iptables 不会干扰 nftables 的正常工作,建议禁用 iptables 相关的服务。
apt-get remove iptables-persistent netfilter persistent
systemctl stop iptables
systemctl disable iptables
现在新版的linux系统底层已经是用的nftables了,只是留下了iptables兼容工具。
当用iptables创建规则时实际上系统自动转换成了nftables规则。
用iptables创建的规则可以用nft命令查到,用nft创建的规则用iptables看不到。
1.7 iptables-translate命令
用于将 iptables 规则转换为 nftables 规则的工具。
1.7.1 单规则翻译
直接在命令行中使用 iptables-translate 来翻译单条 iptables 规则
iptables-translate -A INPUT -p tcp --dport 80 -j ACCEPT
1.7.2 从文件翻译
如果有多条 iptables 规则存储在一个文件中,可以逐行读取并翻译这些规则。
假设有一个文件 iptables-rules.txt,内容如下:
-A INPUT -p tcp --dport 80 -j ACCEPT
-A OUTPUT -p udp --sport 53 -j ACCEPT
while read line; doecho "iptables $ line" | iptables-translate
done < iptables-rules.txt
2 nftables配置与使用
# 启动nftables
systemctl enable nftables
systemctl start nftables
# 关闭iptables
systemctl stop iptables
systemctl disable iptables
2.1 nft命令
nft是一个命令行工具,用于在Linux内核的nftables框架中设置、维护和检查包过滤和分类规则。
Linux 内核子系统称为 nf_tables,"nf"代表Netfilter。
2.2 nftables的结构
跟iptables一样,nftables也使用了table->chain->rule的概念。并使用family(地址簇)的概念区分了报文类型。
2.2.1 地址簇
nftables 地址簇是用于确定 nftables 框架处理哪种类型数据包的关键概念。
每个表在创建时必须指定一个地址簇,并且只能处理属于该地址簇的数据包。
这种机制允许用户根据需要创建特定类型的表和规则,从而实现对不同类型数据包的精细控制。
在 nftables 中,主要有以下几种地址簇:
ip:适用于 IPv4 地址簇的数据包
ip6:适用于 IPv6 地址簇的数据包
inet:同时适用于 IPv4 和 IPv6 地址簇的数据包,统一了 ip 和 ip6 簇,方便用户定义规则
arp:适用于地址解析协议 (ARP) 地址簇的数据包
bridge:适用于处理桥接数据包
netdev:适用于网络设备相关的数据包
如果指定的标识符没有地址族,则默认使用ip簇
2.2.2 钩子hooks
nftables 钩子(Netfilter hooks)是 Linux 内核中Netfilter 框架的一部分,用于在数据包通过网络协议栈的关键点处拦截和处理数据包。
nftables 是一个用于配置 Linux 内核防火墙规则的用户空间工具,基于 Netfilter 钩子来实现数据包的过滤、修改和监控等功能。
钩子的作用:
数据包拦截与处理:钩子允许内核模块在数据包经过网络协议栈的特定点时对其进行拦截,然后执行相应的处理操作,如修改、比较、丢弃或放行。
常见IPv4/IPv6/Inet 地址簇的hooks:
hook | 描述 |
---|---|
prerouting | 所有进入系统的数据包都有它处理,在路由之前调用。用于早期过滤或更改影响路由器的数据包属性。 |
input | 处理传输到本地的数据包 |
forward | 处理转发到不同主机的数据包 |
output | 处理本地进程发送的数据包 |
postrouting | 处理所有离开系统的数据包 |
ingress | 处理所有进入系统的数据包,在第三层协议处理程序之前调用,因此在prerouting钩子之前调用,并且可以用于过滤和管理。仅适用于inet系列 |
2.2.3 规则集ruleset
ruleset关键词被用来标识被放置在内核中的整套表、链、规则的集合。
操作命令有list和flush:
# 查询所有规则
nft -a list ruleset
# 按照地址簇查询,只查询inet地址簇的规则集
nft –a list ruleset inet
# 清空规则集危险操作
nft flush ruleset
# 按地址簇清空规则
nft flush ruleset arp
nft flush ruleset ip
nft flush ruleset ip6
nft flush ruleset bridge
nft flush ruleset inet
nft flush ruleset netdev
2.2.4 支持的链类型
类型 | 协议簇 | 钩子 | 描述 |
---|---|---|---|
filter | all | all | 使用的标准链类型 |
nat | ip、ip6、inet | prerouting、input、output、postrouting | 根据conntrack条目执行本地地址转换 |
route | ip、ip6 | output |
netdev簇仅支持一种组合:即filter类型和ingress钩子。基本链还需要存在设备参数,因为他们仅存在于每个传入接口。
arp簇仅支持filter类型链的input和output钩子。
inet簇还支持ingress钩子,在与netdev链input钩子相同的位置过滤 IPv4 和 IPv6 数据包。这个inet hook允许你在prerouting、input、forward、output、postrouting和这个ingress hook之间共享集合和映射。
2.2.5 表table
table是链、集合和有状态对象的容器。
通过地址簇与命名区分。地址簇是ip ip6 inet arp bridgenetdev六个其中之一,若未指定,默认为ip地址簇。inet是dummy虚拟的簇,代表IPv4/IPv6的混合hybrid。
元表达式nfproto关键字可用来测试 正在处理的包属于哪个地址簇上下文(ipv4 或 ipv6)。
以交互模式启动nft 后面就不用一直输入nft命令,当远程服务器有堡垒机的root用户限制时候,可以更为方便的使用:nft --interactive
- 创建表:不指定地址簇默认ip
nft add table [地址簇] [表名]
nft create table [地址簇] [表名]
add和create的唯一的区别是若表已经存在,add不会报错,create会报错Error: Could not process rule: Fileexists;因为add命令可以修改表的状态。
- 暂时禁用表,规则会失效
nft add table nat { flags dormant\; }
- 激活表
nft add table nat
- 清空表,不包括基础链
nft flush table inet mytable
- 删除表
nft delete table inet mytable
2.2.6 链chain
链是规则的容器。有两种形式——基础链和常规链。
基础链是来自网络堆栈的数据包的入口点,常规链可用作跳转目标并用于更好的组织规则。
指定钩子和优先级值后,该链将被创建为基础链并链接到到网络堆栈。
若基础链的类型填写了不匹配的钩子,会报错Error: Could not process rule: Operation not supported
- 新增链语法:
nft add chain inet mytable mychain { type filter hook input priority 100; }
- 添加新的基础链
# 获取输入
nft add chain inet mytable mychain { type filter hook input priority 100\; }
# 转发给其它主机
nft add chain inet mytable forward { type nat hook postrouting priority 150\; }
# 优先级为-100
nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }
优先级为负的时必须将–选项传递给nft命令,以避免shell将负优先级值解析为nft命令的选项。
- 修改链名
nft rename chain [表地址簇] [表名] [旧链名] [新链名]
nft rename chain inet mytable mychain mychain1
2.2.7 规则rule
规则被添加到指定表指定链中,由表达式和语句组成。操作有add insert replace delete
add和insert命令可支持用 句柄handle或index(以0开始)新增规则。
在内部,规则位置总是由handle标识,index的转换发生在用户空间。如果在翻译完成后发生并发规则集更改,这有两个潜在影响: 如果在引用的规则之前插入或删除规则,则有效规则index可能会更改。如果引用的规则被删除,则该命令将被内核拒绝,就像给出了无效句柄一样。
- 创建规则
- add 将规则添加到链的末尾
- insert 则将规则添加到链的开头
# 创建 nat 表(如果尚未创建)
nft add table ip nat
# 在 nat 表中创建 postrouting 链(如果尚未创建)
nft add chain ip nat postrouting '{ type nat hook
postrouting priority 100 ; }'
# 插入 SNAT 规则到 postrouting 链
nft insert rule nat postrouting oifname eth0 snat to 1.2.3.5
将规则添加到链中指定位置有两种方法:利用handle或index,推荐handle,因为链中有其他规则增加到index之前,则index会发生变化。
- 通过-a参数输出handle信息
nft -a list ruleset
-
add配handle,添加到对应handle后面
- nft add rule [表名] [链名] handle number [规则]
-
insert加handle添加到对应handle之前
- nft insert rule [表名] [链名] handle number [规则]
-
示例
# 对从eth0接口出去的数据包进行源网络地址转换,将源IP地址改为1.2.3.7
nft add rule nat postrouting handle 9 oifname eth0 snat to 1.2.3.7
nft add rule:表示要添加一个新的防火墙规则
nat postrouting:指定这个规则属于网络地址转换(NAT)的postrouting链。这意味着规则将在数据包离开本地系统并准备发送到网络之前应用。
handle 9:给这条规则分配一个句柄,句柄用于唯一标识规则,便于后续的管理和引用。
oifname eth0:表示规则应用于数据包离开的网络接口是eth0。这意味着只有从eth0接口 出去的数据包才会受到这条规则的影响。
snat to 1.2.3.7:指定要进行源网络地址转换(SNAT),将数据包的源IP地址转换 为1.2.3.7。这通常用于隐藏内部网络的真实IP地址,或者在只有一个公共IP地址的情 况下,让多个内部主机能够访问互联网。
2.2.8 常规规则展示
- 允许SSH连接
nft add rule inet filter input tcp dport ssh accept
- 允许HTTP和HTTPS连接
nft add rule inet filter input tcp dport http accept
nft add rule inet filter input tcp dport https accept
- 丢弃所有入站流量
nft add rule inet filter input drop
- 允许本地回环接口的所有流量
nft add rule inet filter input iif lo accept
- 允许ICMP流量
nft add rule inet filter input icmp type echo-request accept
- 规则操作
# 查看规则
nft list ruleset
# 删除规则
nft delete rule nat postrouting handle number
# 清空所有的nftables规则
nft flush ruleset
# 更新规则
nft replace rule nat postrouting handle 12 oif eth0 snat
to 1.2.3.7
2.3 备份|恢复
- 备份
nft list ruleset >> backup.nft
- 回复
nft -f backup.nft
- 立即应用更改
nft -f /etc/nftables.conf
2.4 完整的防火墙配置示例
允许SSH、HTTP、HTTPS和ICMP流量,并丢弃其他所有入站流量
# 创建表
nft add table inet filter
# 创建链
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
# 允许本地回环接口的所有流量
nft add rule inet filter input iif lo accept
# 允许SSH连接
nft add rule inet filter input tcp dport ssh accept
# 允许HTTP和HTTPS连接
nft add rule inet filter input tcp dport http accept
nft add rule inet filter input tcp dport https accept
# 允许ICMP流量
nft add rule inet filter input icmp type echo-request accept
# 查看规则
nft list ruleset