如何通過終端在 Nftables 中使用定義的變數(不在腳本中)
我想在互動式shell中執行這兩個命令,一個接一個(作為root並載入“過濾器”表和“輸入”鏈):
nft define lala=1.2.3.4 nft add rule ip filter input ip saddr \$lala accept
你可以看到我逃脫了“ $ " to avoid shell expansion. But I get this error message “Unkown identifier ’lala’”. If I don’t escape the " $ ”,我得到這個錯誤消息:“語法錯誤,意外的接受”。如果我寫*$* $lala,我得到這個錯誤消息:“語法錯誤,未接受的接受,期望字元串”,並且顯示了這個錯誤的規則:添加規則 ip 過濾器輸入 ip saddr $ 接受。
那麼,在互動式 shell 中使用 Nft 變數的正確語法是什麼。在 Nft 腳本中做同樣的事情效果很好(不用擔心轉義)。
非常感謝
nft
使用者空間命令使用的符號變數僅由該命令解析為它們的值。該nft
命令將變數解析為其分配的值以組合最終結果。然後nft
命令使用netlink API與核心通信並向它發送新規則以添加。核心從來沒有看到lala=1.2.3.4
也沒有任何符號變數的概念。因此,如果您將
nft
命令拆分為兩個呼叫,則會發生以下情況:
- 第一個
nft
命令定義了一個符號變數供其以後使用。但是什麼都不做。它甚至不必與核心通信,因為不需要更改規則集。(實際上它確實進行了通信,但發送“無”,就像使用命令一樣nft ''
)。在命令結束時,符號的定義失去,沒有被使用。- 該命令的第二次呼叫
nft
需要解析$lala
符號,但找不到定義:nft
因錯誤而停止。所以這必須在一次
nft
呼叫中完成,所以第二個語句仍然知道符號變數。有多種方法可以做到這一點。我在 shell 下面的範例中留下了nft
不應輸入的提示。
- 互動的
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
有自己的解析器,它不關心命令是作為單個命令參數還是多個單獨的參數接收的。在這裡,所有內容都包含在一對中,''
以避免;
和$
字元的外殼問題。
- 然後
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
這就是它所返回的。