nftables是一个集成的过滤工具,集成了iptables、ip6tables、arptables和ebtables。
从Red Hat Enterprise Linux8,nftables取代了iptables。相应地CentOS8及RockyLinux8也采用了nftables。
nftables启动和停止
nftables已服务(service)的形式被安装到系统上,因此可使用systemctl命令进行操作。
nftables设定文件
nftables 服务启动时,会读取 /etc/sysconfig/nftables.conf 设定文件。而实际的Ruleset的设定文件,一般保存在 /etc/nfttables/ 目录下,文件名需要在 /etc/sysconfig/nftables.conf 文件里进行 include。
nftables的3个因素
设定nftables之前首先需要理解Family,Type,Hook3个因素。
■Family表
Family | 概要 |
---|---|
ip | 表示IPv4,相当于iptables。 |
ip6 | 表示IPv6,相当于ip6tables。 |
inet | 表示IPv4及IPv6。 |
arp | 表示ARP,可操作IPv4的ARP |
bridge | 表示Bridge,可操作通过Bridge设备的数据包。 |
netdev | 可分类NIC驱动程序传递到网络堆栈后的所有流量,例如可进行DDoS对策。 |
■Type表
Type | 概要 |
---|---|
filter | 可用于所有的 family和hook |
route | 可用于routing。可用于Family:ip,ip6,inet及Hook:output |
nat | 用于NAT。可用于Family:ip,ip6,inet及Hook:input,output,prerouting,postrouting |
■Hook表
Hook | 概要 |
---|---|
input | 可用于Family:ip,ip6,inet,arp,bridge及Type:filter,nat |
output | 可用于Family:ip,ip6,inet,arp,bridge及Type:filter,route,nat |
forward | 可用于Family:ip,ip6,inet,bridge及Type:filter |
prerouting | 可用于Family:ip,ip6,inet,bridge及Type:filter,nat |
postrouting | 可用于Family:ip,ip6,inet,bridge及Type:filter,nat |
ingress | 可用于Family:netdev及Type:filter |
创建table
nftables的默认设定没有table,因此需要从创建table开始。创建table的命令格式如下。
nft add table [family] [tableName]
确认当前的Ruleset。
[root@sys-blog ~]# nft list ruleset
Family inet上添加firewall001 table。
[root@sys-blog ~]# nft add table inet firewall001
[root@sys-blog ~]# nft list tables inet
table inet firewall001
确认添加table之后的Ruleset。
[root@sys-blog ~]# nft list ruleset
table inet firewall001 {
}
删除table使用下面的命令。
[root@sys-blog ~]# nft delete table inet firewall001
创建chain
创建table后,接下来创建chain。创建chain的命令格式如下。
nft add chain [family] [table name] [chain name] { type [type] hook [hook} priority [priority] \; }
priority是整数,数值越小优先度越高。
创建如下的Chain。
- Type:filter
- Hook:input
- Family:inet
- Table:firewall001
- Chain:fiter_INPUT
[root@sys-blog ~]# nft add chain inet firewall001 filter_INPUT { type filter hook input priority 0 \;}
[root@sys-blog ~]# nft list ruleset
table inet firewall001 {
chain filter_INPUT {
type filter hook input priority filter; policy accept;
}
}
删除Chain使用如下命令。
[root@sys-blog ~]# nft delete chain inet firewall00 filter_INPUT
设定Rule
创建Table及Chain后,开始设定Rule。
开始追加Rule之前,先确认当前的Rule。
[root@sys-blog ~]# nft list ruleset
table inet firewall001 {
chain filter_INPUT {
type filter hook input priority filter; policy accept;
}
}
追加允许connection状态为 related, established 数据包的Rule。在这里ct为Conntrack或者Connection Tracking。
[root@sys-blog ~]# nft add rule inet firewall001 filter_INPUT ct state related,established accept
[root@sys-blog ~]# nft list table inet firewall001
table inet firewall001 {
chain filter_INPUT {
type filter hook input priority filter; policy accept;
ct state established,related accept
}
}
追加允许从loopback接口的连接。
[root@sys-blog ~]# nft add rule inet firewall001 filter_INPUT iif lo accept
[root@sys-blog ~]# nft list table inet firewall001
table inet firewall001 {
chain filter_INPUT {
type filter hook input priority filter; policy accept;
ct state established,related accept
iif "lo" accept
}
}
追加丢弃所有数据包的Rule。nft命令 -a 选项,会显示handle号。
[root@sys-blog ~]# nft add rule inet firewall001 filter_INPUT drop
[root@sys-blog ~]# nft -a list table inet firewall001
table inet firewall001 { # handle 17
chain filter_INPUT { # handle 1
type filter hook input priority filter; policy accept;
ct state established,related accept # handle 4
iif "lo" accept # handle 6
drop # handle 7
}
}
在handle6的后面,追加允许目标端口为22,connection状态为 new, untracked 数据包的Rule。
[root@sys-blog ~]# nft add rule inet firewall001 filter_INPUT handle 6 tcp dport 22 ct state { new,untracked } accept
[root@sys-blog ~]#nft -a list table inet firewall001
table inet firewall001 { # handle 17
chain filter_INPUT { # handle 1
type filter hook input priority filter; policy accept;
ct state established,related accept # handle 4
iif "lo" accept # handle 6
tcp dport 22 ct state { new, untracked } accept # handle 9
drop # handle 7
}
}
在handle9后面,追加允许数据包metadata为 icmp,ipv6-icmp 数据包的Rule。
[root@sys-blog ~]# nft add rule inet firewall001 filter_INPUT handle 9 meta l4proto { icmp,ipv6-icmp } accept
[root@sys-blog ~]# nft -a list table inet firewall001
table inet firewall001 { # handle 17
chain filter_INPUT { # handle 1
type filter hook input priority filter; policy accept;
ct state established,related accept # handle 4
iif "lo" accept # handle 6
tcp dport 22 ct state { new, untracked } accept # handle 9
meta l4proto { icmp, ipv6-icmp } accept # handle 11
drop # handle 7
}
}
删除Rule时指定handle号,在这里删除handle号为11的Rule。
[root@sys-blog ~]# nft delete rule inet firewall001 filter_INPUT handle 11
[root@sys-blog ~]# nft -a list table inet firewall001
table inet firewall001 { # handle 17
chain filter_INPUT { # handle 1
type filter hook input priority filter; policy accept;
ct state established,related accept # handle 4
iif "lo" accept # handle 6
tcp dport 22 ct state { new, untracked } accept # handle 9
drop # handle 7
}
}
修改nftables的方法
- 将nftables的结果保存到指定的文件
- 修改文件
- 反应到nftables
把当前配置的nftables设置写入到文件中(/tmp/nftables.nft)。
[root@sys-blog ~]# nft list ruleset > /tmp/nftables.nft
“nft list ruleset” 命令显示nftables当前规则集的命令,可以用来检查规则集。
修改/tmp/nftables.nft文件后,使用 “nft -f <文件名>” 修改后的规则集反映到系统。
[root@sys-blog ~]# nft -f /tmp/nftables.nft
一般Ruleset内容会保存 /etc/nfttables/ruleset.nft 文件。
小结
修改nftables需谨慎,万一修改时犯错,可能再也无法从外部连接该服务器。