如何通过终端(而不是在脚本中)使用 Nftables 中定义的变量

如何通过终端(而不是在脚本中)使用 Nftables 中定义的变量

我想在交互式 shell 中依次运行这两个命令(以 root 身份并加载“过滤器”表和“输入”链):

nft define lala=1.2.3.4
nft add rule ip filter input ip saddr \$lala accept

您可以看到我转义了“$”以避免 shell 扩展。但我收到此错误消息“未知标识符‘lala’”。如果我不转义“$”,则会收到此错误消息:“语法错误,意外接受”。如果我写\$$啦啦相反,我收到这个错误消息:“语法错误,未预期的接受,预期字符串”,并且显示这个错误规则:添加规则 ip 过滤器输入 ip saddr $ accept。

那么,在交互式 shell 中使用 Nft 变量的正确语法是什么?在 Nft 脚本中执行相同操作效果很好(无需担心转义)。

多谢

答案1

符号变量正在使用nft 用户空间命令被解析为其值仅有的通过此命令。该nft命令将变量解析为其指定的值以组合最终结果。然后nft命令使用网络链接接口与内核通信并向其发送要添加的新规则。内核绝不看不到lala=1.2.3.4,也没有任何符号变量的概念。

因此,如果你将nft命令分成两次调用,则会发生以下情况:

  • 第一个nft命令定义了一个符号变量以供自己以后使用。但是没有做其他事情。它甚至不必与内核通信,因为没有要求更改规则集。(实际上它确实进行了通信,但是发送了“无”内容,就像使用命令一样nft '')。在命令结束时,符号的定义会丢失,因为尚未使用。

  • 该命令的第二次调用nft需要解析$lala符号,但找不到定义:nft因错误而停止。

所以这一切都必须在 nft调用,因此第二条语句仍然知道符号变量。有多种方法可以做到这一点。我在下面的示例中保留了nft不应输入的 shell 和 提示。

  • 交互的nft

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

    # nft -i
    nft> define lala=1.2.3.4
    nft> add rule ip filter input ip saddr $lala accept
    nft> quit
    
  • 一次nft调用即可执行两个命令。

    # nft 'define lala=1.2.3.4; add rule ip filter input ip saddr $lala accept'
    

    请注意,需要额外的;,因为在这种情况下,nft它接收一行参数,但它们应该拆分成两个逻辑命令。它还nft拥有自己的解析器,因此它不关心命令是作为单个命令参数还是多个单独的参数接收的。在这里,所有内容都包含在一对 中,''以避免出现;$字符的 shell 问题。

  • 然后nft有一个从文件读取的选项。从文件读取时,所有输入都是同一nft命令上下文的一部分。

    -f, --file filename
    从文件名读取输入。如果文件名为 -,则从标准输入读取。

    nft 脚本必须启动#!/usr/sbin/nft -f

    因此,有一个名为的文件test.nft具有以下内容:

    define lala=1.2.3.4
    add rule ip filter input ip saddr $lala accept
    

    然后就可以使用它:

    # nft -f test.nft
    

    下面的变体在“nftables语言”。test.nft文件内容如下:

    #!/usr/sbin/nft -f
    define lala=1.2.3.4
    add rule ip filter input ip saddr $lala accept
    

    然后:

    # chmod a+rx test.nft
    # ./test.nft
    

    这也行得通:

    # nft -f - <<'EOF'
    > define lala=1.2.3.4
    > add rule ip filter input ip saddr $lala accept
    > EOF
    

对于每个先前的命令,生成的规则集是相同的(假设表和链之前已创建):

# nft list chain ip filter input
table ip filter {
    chain input {
        type filter hook input priority filter; policy accept;
        ip saddr 1.2.3.4 accept
    }
}

不会再留下任何痕迹$lala:内核从未收到过任何东西$lala,而只1.2.3.4收到它所回馈的东西。

相关内容