それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

nft のコマンドの使い方の例。NFTテーブル操作ガイドを作ろう

nft 使い方まとめ

nft の使い方は、本当にややこしい。覚えることが多くてる辛いので、調べたことをまとめ直す。

ルール閲覧

"コマンド" "役割"
nft list ruleset 全部見る
nft- a list ruleset 管理番号を含める

全体を見渡すコマンドがコレ。ruleではなくruleset

テーブル

"コマンド" "役割"
nft list tables テーブル一覧
nft add table TABLE テーブル追加
nft create table TABLE テーブル追加(既存チェック有り)
nft list table TABLE テーブル中身表示

TABLE<?family> <name> で定義される。

<?family> <name>inet mytableのように、アドレスファミリを付ける場合とつけない場合がある。作成時にアドレスファミリをつけたら以降は全部つけて識別する。作成時の省略なら以後は省略して作業する。

<?family> に使えるのは、inet | ip | ip6 | arp | netdev | bridgeであるが、パケット転送に限ればip, ip6, inet である。inetip,ip6の両方を含む。

add と create の違い

$ nft add    table ip mytable 
$ nft add    table ip mytable 
$ nft add    table ip mytable # 何度もaddでも既存があればスキップ
$ nft create table ip mytable # create は既存があればエラー

チェイン

"コマンド" "役割"
nft list chain TABLE CHAIN チェイン一覧
nft insert chain TABLE CHAIN '{ <rule> }' チェインの先頭にルールを追加
nft add chain TABLE CHAIN '{ <rule> }' チェインの末尾にルールを追加

nft -a list chain inet fw4  srcnat_VmNet

チェインにルールを追加する例

nft -a list chain inet fw4  srcnat_VmNet
nft add chain inet fw4 srcnat_VmNet { oifname "eth2" ip saddr 192.168.11.0/0 counter packets 0 bytes 0 masquerade comment "!fw4: my-sample" \; }

ルール

"コマンド" "役割"
nft insert rule TABLE CHAIN <rule> チェインの先頭にルールを追加
nft add rule TABLE CHAIN <rule> チェインの末尾にルールを追加
nft delete rule TABLE CHAIN handle <ID> ハンドルを指定して消す。
nft add table TABLE { flags dormant \; } ルールを一時休止

ルールの削除は、今のところ、ルールの削除は、Handle <ID>をつかって指定する。

指定したルールの後ろに追加する方法は現在発見されていない。ルールを作り直すほうが確実。

ルール削除はHandle ID

ルール削除は次の通り

nft delete rule TABLE CHAIN handle `<ID>` 

コメント活用したIDの探索

書いたルールがどのハンドルになっているか探すのが大変煩わしい、そこでコメントを使う方法を考えた。

コメントを利用した削除例

例えば、こんな感じに頑張る。

## 追加して
nft add rule inet fw4 srcnat oif eth0 accept comment mycomment      
## コメントを探す
nft -a list chain inet fw4 srcnat | grep mycomment
## コメントから handle を取り出し
HNDL_ID=$(nft -a list chain inet fw4 srcnat | grep mycomment | grep -oP '(?<=handle )\d+')
## ID指定で消す
[ -n $HNDL_ID ] && nft delete rule inet fw4 srcnat handle $HNDL_ID

いずれは、次のような記述も可能になると思うが、まだ無理っぽい。

nft delete rule inet fw4 srcnat oif eth0 accept comment mycomment      

コメントを用いたルールの削除と、JSON出力を組み合わせて頑張ろう

テーブルの追加削除

テーブル存在確認と作成と削除

## 作成  ( add または create )
nft add table ip mytable
## 確認
nft list table ip mytable
## 削除
nft delete table ip mytable

追加の失敗例 :既存がある。

nft create table ip mytable
Error: Could not process rule: File exists
create table ip mytable
                ^^^^^^^

追加の失敗例: 文法エラー

nft create table ip mytable chain
Error: syntax error, unexpected chain, expecting end of file or newline or semicolon
create table ip mytable chain
                        ^^^^^

チェインの追加と削除

## 作成 ( add または create )
nft add chain ip mytable srcnat
## 確認
nft list chain ip mytable srcnat
## 削除
nft delete table ip mytable

srcnat は、予約語なので注意

テーブル名は自由に決められるが、予約語がある。詳しくは、man nftCHAINSを参照すること

予約語については公式ページも参考になる。Priority_within_hook

MASQUERADE を作る例

テーブルにチェインを追加

nft add table ip mytable
nft add chain ip mytable srcnat 
nft add chain ip mytable srcnat_vpn
nft add rule ip mytable srcnat  oifname "eth2" jump srcnat_vpn comment jump-to-my-vpn
nft add rule ip mytable srcnat_vpn ip saddr 192.168.11.0/24  masquerade comment '"srcnat to my vpn';

いくつか、ポイントを解説。

meta nfproto ipv4 oifname "eth2" と書きたいところだが、ip mytable と、v4 限定のテーブルを書いているので、不要である。

コメントで、クォートしている。次のようにコメント記入しているcomment '"srcnat to my vpn'、コレは、bashにより、展開されるので、確実に文字列を引き渡す必要があるため。

確認

$ nft list table ip mytable
table ip mytable {
    chain srcnat {
      oifname "eth2" jump srcnat_vpn comment "jump-to-my-vpn"
  }
  chain srcnat_vpn {
    ip saddr 192.168.11.0/24 masquerade comment "srcnat to my vpn"
  }
}

動作チェック方法

counterを入れてマッチしたパケットの個数をカウントすればいい

nft add rule ip mytable srcnat  oifname "eth2" conter jump srcnat_vpn

counter を入れると、バイト数とパケット数がカウントされる。

丸暗記ポイント追加と削除

追加と削除が、ぱっと見てわかりにくい。

発展途上のコマンドのためサブコマンドが混乱を招きやすい体系である。留意しながら丸暗記しないと大変である。もしかしたら手作業による管理がnftに想定されてないのかもしれない。溜息が出るほどとっつきにくい。

追加と削除がわかりにくいので、とくに致命的じゃないかなって思う。

心配なのは、いま苦労して覚えても、数年後にはガラッとコマンド体系が改められそうと懸念している。懸念でるほど煩雑だ。

ルールの追加がわかりにくい

ルールの追加は add chain table chain { <rule> } 、ルールの削除は delete rule table chain handle <ID>

と思いきや、ルール追加は、add rule table chain <rule> でも行ける。

ルールの削除がわかりにくい

そして、削除はdel では無い。deleteである。add と来たら、ついついdelと打ちがち。しかしdelは存在しない。

愚痴をこぼすと、nftablesをnft って省略するのに、delete をdel って省略したらだめってのはひどい。nft は某用語なので検索しづらい。delを認めないのであれば、同じように nft コマンドではなく、nftables コマンドにしてほしい。

[add | insert] , [add | create] のペアがわかりにくい

テーブルとチェインは、add / create で、ルールはadd / insertになる。

初見殺しである。カジュアル利用の私達は、そんな違いをいちいち覚えてられない。めんどくさい。