脚本

一些人喜欢在 shrll 脚本里维护规则集,这允许他们可以添加一些适合人类阅读的注释。但是这是有问题的,因为应用规则集时是非原子性的,因此在加载规则集时过滤策略是非一致性应用的。

幸运的是,nftables 提供了一个原生的脚本环境来解决这些问题,它允许你包含其它规则集文件,定义变量和添加注释。你需要使用 nft -f my-ruleset.file 命令恢复原生脚本文件中的内容。

要创建一个 nftables 脚本,你需要在你的脚本文件头部添加下面一行:

#!/usr/sbin/nft

添加注释

你可以使用 # 字符在你的脚本文件中添加注释。# 字符之后的所有字符都会被忽略。

#!/usr/sbin/nft

#
# 声明表
#
add table filter

#
# 声明链
#
add chain filter input { type filter hook input priority 0; policy drop; }

#
# 声明规则
#
add rule filter input ct state established,related counter accept

包含文件

下面的例子显示了怎么包含其它规则集文件:

#!/usr/sbin/nft

include "ipv4-nat.ruleset"
include "ipv6-nat.ruleset"

定义变量

你可以使用 define 关键字定义变量,下面的例子显示了一个简单的规则集用来对源地址是 8.8.8.8 (常用的 Google DNS 服务器)的连接进行计数。

#!/usr/sbin/nft

define google_dns = 8.8.8.8

add table filter
add chain filter input { type filter hook input priority 0; }
add rule filter input ip saddr $google_dns counter

你也可以为集合(sets)定义一个变量:

#!/usr/sbin/nft

define ntp_servers = { 84.77.40.132, 176.31.53.99, 81.19.96.148, 138.100.62.8 }

add table filter
add chain filter input { type filter hook input priority 0; }
add rule filter input ip saddr $ntp_servers counter

不要忘了在规则中使用时,大括号有特殊的意思,因为它们指明了这个变量代表了一个集合(set)。因此,避免这样:

define google_dns = { 8.8.8.8 }

定义一个集合(set)却只有一个元素有点滥用了,你应该使用单独的定义:

define google_dns = 8.8.8.8