nftables 速成

功能确实很强大,但这也太复杂了

简介

Nftables 是现代 Linux 内核数据包分类框架。新的代码应该使用它来代替遗留的 {ip, ip6, arp, eb}_tables (xtables) 基础设施。对于尚未转换的现有代码库,遗留的 xtables 基础设施将维护到到 2021 年。

在 Linux 服务器的日常维护中,网络防火墙是很重要的一环。对于一般用途而言,其实需要的防火墙策略都不是很复杂,没有必要为此而购买独立的软硬件防火墙,使用 Linux 内嵌的基础网络包处理就完全足够应对。

iptables 作为这方面的老大哥,在 Linux 系统的基础网络包处理一线坚挺了多年。但随着时代的发展,老大哥也到了该退休的岁数,目前公认的继任者就是 nftables。

相较于 iptables,nftables 的框架设计更为合理,功能更为全面,命令行的语法也更为清晰。但从网络上关于 nftables 的资料并不多这一点就不难看出,nftables 目前的应用仍不是非常广泛。(和 IPv6 同病相怜)这主要是因为 nftables 丰富的功能和特性立足于陡峭的学习曲线之上,令用户望而却步。

关于 nftables 的具体简介可以参照这里 Waht is nftables?

命令

nft 选项 动作 对象

动作

基础动作 动作目标

选项

  • -n, --numeric 打印完整的数字输出

  • -c, --check 检查命令的有效性,而不实际应用更改

  • -a, --handle 在输出中显示对象句柄

  • -e, --echo 当使用 addinsertreplace 命令将项目插入到规则集时,就像 nft monitor 一样打印通知

  • -I, --includepath directory 在要搜索包含的文件目录列表中添加 directory。这个选项可以被多次指定

  • -f, --file filenamefilename 读取输入。如果 filename-,则从 stdin 读取

  • -i, --interactive 从一个交互式的 readline CLI 中读取输入。你可以使用 quit 来退出,或者使用 EOF 标记,通常是 CTRL-D

基础动作

  • list 查看

  • create 创建

  • add 添加

  • insert 插入

  • replace 替换

  • delete 删除

  • flush 清空

addcreate 的唯一区别是,如果指定的内容已经存在,add 不会返回错误,而 create 会返回错误。

动作目标

  • ruleset

  • table

  • chain

  • rule

  • set

  • map

  • element

动作目标与对象是对应关系。

对象

Address Family 地址族

地址族决定处理的数据包的类型。对于每个地址族,内核在数据包处理路径的特定阶段包含所谓的钩子,如果存在这些钩子的规则,这些钩子将调用 nftables。

  • ip IPv4,默认

  • ip6 IPv6

  • inet Internet (IPv4/IPv6)

  • arp 处理 IPv4 ARP 数据包

  • bridge 处理通过网桥设备的数据包

  • netdev 处理来自入口的数据包

Ruleset 规则集

ruleset 关键字用于标识内核中当前到位的整个表、链等集合。

{list | flush} ruleset [family]

Tables 表

表是链、集和有状态对象的容器,通过地址族家庭和名称来识别。

{add | create} table [family] table [{ flags flags ; }]
{delete | list | flush} table [family] table
list tables [family]
delete table [family] handle handle

Chain 链

链条是规则的容器,分为基链和规则链两种。

{add | create} chain [family] table chain [{ type type hook hook [device device] priority priority ; [policy policy ;] }]
{delete | list | flush} chain [family] table chain
list chains [family]
delete chain [family] table handle handle
rename chain [family] table chain newname

基本链

基本链是网络堆栈中数据包的入口点,必须包含类型、钩子和优先级参数。

类型

  • filter 过滤时使用的标准类型。

  • nat 基于连接跟踪条目执行地址转换。只有连接的第一个数据包实际穿越该链——其规则通常定义所创建的连接跟踪条目的细节(例如 NAT 语句)。

  • route 如果一个数据包已经穿越了这种类型的链,并且即将被接受,如果 IP 头的相关部分发生了变化,就会进行新的路由查询。这允许在 nftables 中实现策略路由选择器。

钩子

  • prerouting 刚到达并未被 nftables 的其他部分所路由或处理的数据包。

  • input 已经被接收并且已经经过 prerouting 钩子的传入数据包。

  • forward 如果数据报将被发送到另一个设备,它将会通过 forward 钩子。

  • output 从本地传出的数据包。

  • postrouting 仅仅在离开系统之前,可以对数据包进行进一步处理。

优先级

优先级参数接受一个带符号的整数值或一个标准的优先级名称,该名称指定具有相同钩子值的链的遍历顺序。排序是升序的,也就是说低优先级的值优先于高优先级的值。标准的优先级值可以用容易记忆的名称替换。并不是所有的名字在每个钩子族中都有意义 (参见 钩子可用性) ,但是它们的数值仍然可以用来排列链的优先级。

  • raw

  • mangle

  • dstnat

  • filter

  • security

  • srcnat

规则链

规则链可以作为跳转目标,用于更好地组织规则。

Rule 规则

规则是根据一套语法规则由两类成分构成的:表达式和声明。

{add | insert} rule [family] table chain [handle handle | index index] statement ... [comment comment]
replace rule [family] table chain handle handle statement ... [comment comment]
delete rule [family] table chain handle handle

规则内容过于冗杂,建议直接阅读 Quick reference-nftables in 10 minutes

输入文件

  • \ 如果上一行的最后一个字符是非引号反斜杠,则下一行被视为延续

  • ; 将同一行中的多个命令分开

  • # 后面的同一行字符都被忽略

  • include filename 包含 filename 文件的内容

  • define variable = expr 定义值为 expr 的变量 variable

  • $variable 引用变量 variable 的值

标识符以字母字符 [a-zA-Z] 开头,后面跟着零个或多个字母数字字符 [a-zA-Z0-9] 和字符斜杠 [/] 、反斜杠 [\\]、下划线 [_] 和点 [\.] 。使用不同字符或与关键字冲突的标识符需要用双引号 ["] 括起来。

通用容器

Set 集合

nftables 提供了两种集合概念:匿名集和命名集。

匿名集

匿名集是没有特定名称的集合。集合成员用花括号括起来,在创建集合使用的规则时,用逗号分隔元素。一旦该规则被删除,集合也会被删除。它们不能被更新,也就是说,一旦一个匿名集被声明,它就不能再被更改,除非删除/更改使用匿名集的规则。

命名集

add set [family] table set { type type | typeof expression ; [flags flags ;] [timeout timeout ;] [gc-interval gc-interval ;] [elements = { element[, ...] } ;] [size size ;] [policy policy ;] [auto-merge ;] }
{delete | list | flush} set [family] table set
list sets [family]
delete set [family] table handle handle
{add | delete} element [family] table set { element[, ...] }

Keyword

Description

Type

type

集合中元素的数据类型

string: ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service, mark

typeof

集合中元素的数据类型

要用于获取类型的表达式

flags

设置标志

string: constant, dynamic, interval, timeout

timeout

一个元素停留在集合中的时间,如果集合被添加到数据包路径(规则集),则是强制性的

string, decimal followed by unit. Units are: d, h, m, s

gc-interval

垃圾收集时间间隔,只有在超时或标志超时激活时才可用

string, decimal followed by unit. Units are: d, h, m, s

elements

集合包含的元素

集合的数据类型

size

集合中的最大元素数,如果集合是由数据包路径(规则集)添加的,则是强制性的

unsigned integer (64 bit)

policy

设置策略

string: performance [default], memory

auto-merge

自动合并相邻/重叠的集合元素(仅适用于区间集合)

Map 映射

映射根据用作输入的某个特定键存储数据。它们由用户定义的名称唯一标识并附加到表中。

add map [family] table map { type type | typeof expression [flags flags ;] [elements = { element[, ...] } ;] [size size ;] [policy policy ;] }
{delete | list | flush} map [family] table map
list maps [family]
KeywordDescriptionType

type

映射中元素的数据类型

string: ipv4_addr, ipv6_addr, ether_addr, inet_proto, inet_service, mark, counter, quota 计数器和配额不能作为键使用

typeof

映射中元素的数据类型

要用于获取类型的表达式

flags

设置标志

string: constant, interval

elements

映射包含的元素

映射的数据类型

size

映射中元素的最大数量

string: performance [default], memory

policy

映射策略

string: performance [default], memory

Element 元素

与元素相关的命令允许更改命名集和映射的内容。

{add | create | delete | get } element [family] table set { ELEMENT[, ...] }

ELEMENT := key_expression OPTIONS [: value_expression]
OPTIONS := [timeout TIMESPEC] [expires TIMESPEC] [comment string]
TIMESPEC := [numd][numh][numm][num[s]]

Option

Description

timeout

带有超时标志的集合/映射的超时值

expires

给定元素过期的时间,仅对规则集复制有用

comment

每个元素的注释字段

参考图表

钩子触发流程

钩子可用性

白名单列举,没有明确标为 Yes 的都不可用。

Chain typeingresspreroutingforwardinputoutputpostroutingegress

inet family

filter

Yes

Yes

Yes

Yes

Yes

Yes

nat

Yes

Yes

Yes

Yes

route

Yes

ip6 family

filter

Yes

Yes

Yes

Yes

Yes

nat

Yes

Yes

Yes

Yes

route

Yes

ip family

filter

Yes

Yes

Yes

Yes

Yes

nat

Yes

Yes

Yes

Yes

route

Yes

arp family

filter

Yes

Yes

bridge family

filter

Yes

Yes

Yes

Yes

Yes

netdev family

filter

Yes

Yes(5.7)

钩内优先级

在给定的钩子中,会按照数字递增的顺序执行操作,所以 数字越小优先级越高

nftables Families

Typical hooks

nft Keyword

Value

Netfilter Internal Priority

Description

prerouting

-450

NF_IP_PRI_RAW_BEFORE_DEFRAG

inet, ip, ip6

prerouting

-400

NF_IP_PRI_CONNTRACK_DEFRAG

Packet defragmentation / datagram reassembly

inet, ip, ip6

all

raw

-300

NF_IP_PRI_RAW

Traditional priority of the raw table placed before connection tracking operation

-225

NF_IP_PRI_SELINUX_FIRST

SELinux operations

inet, ip, ip6

prerouting, output

-200

NF_IP_PRI_CONNTRACK

Connection tracking processes run early in prerouting and output hooks to associate packets with tracked connections.

inet, ip, ip6

all

mangle

-150

NF_IP_PRI_MANGLE

Mangle operation

inet, ip, ip6

prerouting

dstnat

-100

NF_IP_PRI_NAT_DST

Destination NAT

inet, ip, ip6, arp, netdev

all

filter

0

NF_IP_PRI_FILTER

Filtering operation, the filter table

inet, ip, ip6

all

security

50

NF_IP_PRI_SECURITY

Place of security table, where secmark can be set for example

inet, ip, ip6

postrouting

srcnat

100

NF_IP_PRI_NAT_SRC

Source NAT

postrouting

225

NF_IP_PRI_SELINUX_LAST

SELinux at packet exit

inet, ip, ip6

postrouting

300

NF_IP_PRI_CONNTRACK_HELPER

Connection tracking helpers, which identify expected and related packets.

inet, ip, ip6

input, postrouting

INT_MAX

NF_IP_PRI_CONNTRACK_CONFIRM

Connection tracking adds new tracked connections at final step in input & postrouting hooks.

bridge

prerouting

dstnat

-300

NF_BR_PRI_NAT_DST_BRIDGED

bridge

all

filter

-200

NF_BR_PRI_FILTER_BRIDGED

bridge

0

NF_BR_PRI_BRNF

bridge

output

out

100

NF_BR_PRI_NAT_DST_OTHER

bridge

200

NF_BR_PRI_FILTER_OTHER

bridge

postrouting

srcnat

300

NF_BR_PRI_NAT_SRC

参考源

最后更新于