nftables で、パケットが該当ルールに来ているかチェックする方法
パケットの行先が不明のとき、どこまでマッチしているか調べる必要がある。このときcounter を使うのが一番簡単。
例えば、Google(v6) 宛のパケットを探したい
次のように、ターゲットとなるチェインにカウンタをINSERTする。
GGv6='2404:6800:400a:80b::200e' TBL='inet fw4' CHN='handle_reject' nft insert rule $TBL $CHN meta nfproto ipv6 ip6 daddr $GGv6 counter
このように、カウンタをいれる。実際にはもっと具体的な条件で挟む。( iifname / oifname / ip6 saddr / daddr など具体的に。)
カウンタが進むかチェックする
カウンタをいれたチェインを確認する
nft list chain $TBL $CHN
最初は、パケット数=0、バイト数=0である。
table inet fw4 { chain handle_reject { ip6 daddr 2404:6800:400a:80b::200e counter packets 0 bytes 0 meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic" reject comment "!fw4: Reject any other traffic" } }
ping などでパケットを送ってみる。
ping 2404:6800:400a:80b::200e Destination port unreachable. Destination port unreachable. Destination port unreachable. Destination port unreachable.
パケット数を再確認します。
nft list chain $TBL $CHN
カウントが進んでいるのがわかります。パケット数=4、バイト数=320
table inet fw4 { chain handle_reject { ip6 daddr 2404:6800:400a:80b::200e counter packets 4 bytes 320 meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic" reject comment "!fw4: Reject any other traffic" } }
このように、パケットの「カウント」を任意の場所に条件付きで挟み込んで、どこのチェインで処理されたかを知ることができる。
特に、reject / drop の手前に差し込むと効果がある。
nft がおかしいときは counter で探す。
accept -> accept -> reject
のように accept後にどこかでreject されてパケットが捨てられる可能性が高いためである。
nftablesでは、複数テーブルで処理されて、chainA accept && chainB reject => reject
のように複数チェインのどこかでDROPやREJECTされてしまい、気付かないうちにDROPされて届かないということが頻発する。
そのため、カウンタでどこに来ているかを慎重にチェックしないと、思わぬところでリジェクトされて届かない。