2.2. 编写和执行 nftables 脚本

使用 nftables 框架的主要优点是脚本的执行是原子的。这意味着,系统会应用整个脚本,或者在出现错误时防止执行。这样可保证防火墙始终处于一致状态。

另外,使用 nftables 脚本环境时,您可以:

  • 添加评论
  • 定义变量
  • 包括其他规则集文件

当安装 nftables 软件包时,Red Hat Enterprise Linux 会在 /etc/nftables/ 目录中自动创建 *.nft 脚本。这些脚本包含为不同目的创建表和空链的命令。

2.2.1. 支持的 nftables 脚本格式

您可以使用以下格式在 nftables 脚本环境中编写脚本:

  • nft list ruleset 命令相同的格式显示规则集:

    #!/usr/sbin/nft -f
    
    # Flush the rule set
    flush ruleset
    
    table inet example_table {
      chain example_chain {
        # Chain for incoming packets that drops all packets that
        # are not explicitly allowed by any rule in this chain
        type filter hook input priority 0; policy drop;
    
        # Accept connections to port 22 (ssh)
        tcp dport ssh accept
      }
    }
  • nft 命令的语法相同:

    #!/usr/sbin/nft -f
    
    # Flush the rule set
    flush ruleset
    
    # Create a table
    add table inet example_table
    
    # Create a chain for incoming packets that drops all packets
    # that are not explicitly allowed by any rule in this chain
    add chain inet example_table example_chain { type filter hook input priority 0 ; policy drop ; }
    
    # Add a rule that accepts connections to port 22 (ssh)
    add rule inet example_table example_chain tcp dport ssh accept

2.2.2. 运行 nftables 脚本

您可以通过将脚本传递给 nft 实用程序或直接执行脚本来运行 nftables 脚本。

流程

  • 要通过将其传给 nft 工具来运行 nftables 脚本,请输入:

    # nft -f /etc/nftables/<example_firewall_script>.nft
  • 要直接运行 nftables 脚本:

    1. 在进行这个时间时:

      1. 确保脚本以以下 shebang 序列开头:

        #!/usr/sbin/nft -f
        重要

        如果省略 -f 参数,nft 实用程序不会读取脚本并显示:Error: syntax error, unexpected newline, expecting string

      2. 可选:将脚本的所有者设置为 root

        # chown root /etc/nftables/<example_firewall_script>.nft
      3. 使脚本可以被其所有者执行:

        # chmod u+x /etc/nftables/<example_firewall_script>.nft
    2. 运行脚本:

      # /etc/nftables/<example_firewall_script>.nft

      如果没有输出结果,系统将成功执行该脚本。

重要

即使 nft 成功地执行了脚本,在脚本中错误放置的规则、缺失的参数或其他问题都可能会导致防火墙的行为不符合预期。

其他资源

2.2.3. 使用 nftables 脚本中的注释

nftables 脚本环境将 # 字符右侧的所有内容解释为行尾。

注释可在行首或命令旁边开始:

...
# Flush the rule set
flush ruleset

add table inet example_table  # Create a table
...

2.2.4. 使用 nftables 脚本中的变量

要在 nftables 脚本中定义一个变量,请使用 define 关键字。您可以在变量中存储单个值和匿名集合。对于更复杂的场景,请使用 set 或 verdict 映射。

只有一个值的变量

以下示例定义了一个名为 INET_DEV 的变量,其值为 enp1s0

define INET_DEV = enp1s0

您可以通过输入 $ 符号后再输入变量名称来使用脚本中的变量:

...
add rule inet example_table example_chain iifname $INET_DEV tcp dport ssh accept
...
包含匿名集合的变量

以下示例定义了一个包含匿名集合的变量:

define DNS_SERVERS = { 192.0.2.1, 192.0.2.2 }

您可以通过在 $ 符号后跟变量名称来在脚本中使用变量:

add rule inet example_table example_chain ip daddr $DNS_SERVERS accept
注意

当您在规则中使用大括号时具有特殊的语义,因为它们表示变量代表一个集合。

2.2.5. 在 nftables 脚本中包含文件

nftables 脚本环境中,您可以使用 include 语句包含其他脚本。

如果您只指定文件名,而没有绝对路径或相对路径,则 nftables 包括默认搜索路径中的文件,该路径被设为 Red Hat Enterprise Linux 上的 /etc

例 2.1. 包含默认搜索目录中的文件

从默认搜索目录中包含一个文件:

include "example.nft"

例 2.2. 包含目录中的所有 *.nft 文件

要包括所有存储在 /etc/nftables/rulesets/ 目录中、以 *.nft 结尾的文件:

include "/etc/nftables/rulesets/*.nft"

请注意,include 语句不匹配以点开头的文件。

其他资源

  • nft(8) 手册页中的 Include files 部分

2.2.6. 系统引导时自动载入 nftables 规则

nftables systemd 服务加载包含在 /etc/sysconfig/nftables.conf 文件中的防火墙脚本。

先决条件

  • nftables 脚本存储在 /etc/nftables/ 目录中。

流程

  1. 编辑 /etc/sysconfig/nftables.conf 文件。

    • 如果您使用 nftables 软件包的安装修改了在 /etc/nftables/ 中创建的 *.nft 脚本,请取消对这些脚本的 include 语句的注释。
    • 如果您编写了新脚本,请添加 include 语句以包含这些脚本。例如,要在 nftables 服务启动时加载 /etc/nftables/example.nft 脚本,请添加:

      include "/etc/nftables/_example_.nft"
  2. 可选:启动 nftables 服务以在不重启系统的情况下加载防火墙规则:

    # systemctl start nftables
  3. 启用 nftables 服务。

    # systemctl enable nftables