nftables
はパケットフィルタリングツールで、iptables
、ip6tables
などの後継。
簡単なユースケースではfirewalld
を使用するが、複雑なケースやネットワーク全体に対する設定はnftables
を使用する。今後はiptables
の代わりに、nftables
の試用が推奨される。
設定構造
nftablesの設定全体のことをルールセットと呼ぶ。ルールセットには、アドレスファミリごとに設定されるテーブルがある。テーブルにはチェーンがあり、そこにルールが含まれる。
- ルールセット
- テーブル A
- チェーン i
- ルール 1
- ルール 2
- チェーン ii
- ルール 1
- ルール 2
- チェーン i
- テーブル B
- チェーン i
- ルール 1
- ルール 2
- チェーン i
- テーブル A
テーブルは、アドレスファミリ(=プロトコル)毎にを作成する。
アドレスファミリの種類
アドレスファミリには次のような種類がある。
nftables
はdnf install nftablesでインストールできる(もちろん
yum install nftables`でもよい)
# dnf install nftables # systemctl start nftables # dnf list installed | grep nftables nftables.x86_64 1:1.0.4-11.el9 @anaconda # rpm -qa | grep nftables nftables-1.0.4-11.el9.x86_64
nftables
はnft
コマンドで設定できる。アドレスファミリが「ip」である テーブル「table01」を作成する場合は、次のようなコマンドになる。
# nft create table ip table01 # アドレスファミリが「ip」のテーブル「table01」を作成 # nft list ruleset table ip table01 { }
さらにチェーンを作成する。(詳細は後述)
# nft create chain ip table01 chain01 { type filter hook input priority 1 \; policy accept \; } # チェーンの作成。タイプ「filter」、フック「input」、プライオリティ「1」、ポリシー「drop」を指定 # nft list ruleset table ip table01 { chain chain01 { type filter hook input priority filter + 1; policy drop; } }
チェーン内にルールを追加する。(詳細は後述)
# nft add rule ip table01 chain01 ip saddr 59.138.xxx.xxx accept # nft -a list ruleset table ip table01 { # handle 1 chain chain01 { # handle 1 type filter hook input priority filter + 1; policy accept; ip saddr 59.138.xxx.xxx accept # handle 2 } }
削除は次のような感じ。{ flags dormant \; }
で作成したテーブルを無効化することもできる
# nft delete rule ip table01 chain01 handle 2 # nft -a list ruleset table ip table01 { # handle 1 chain chain01 { # handle 1 type filter hook input priority filter + 1; policy accept; } } # # nft delete chain ip table01 chain01 # チェーンの削除 # nft list ruleset table ip table01 { } # nft add table ip table01 { flags dormant \; } # テーブルの無効化 # nft list ruleset table ip table01 { flags dormant } # nft delete table ip table01 # テーブル削除 # nft list ruleset #
テーブル
テーブルを作成するにはnft create table [アドレスファミリ] [テーブル名]
とする。
チェーン
次にチェーンを作成するには、nft create chain [アドレスファミリ] [テーブル名] [チェーン名] { type [タイプ] hook [フック] priority [プライオリティ] ; policy [ポリシー] ; }
とする。
タイプ
以下の3種類が存在する。
- filter
- フィルタリングに使用
- nat
- NATの実行に使用
- ip、ip6のみ使用可能
- route
- パケットのルーティングに使用
- ip、ip6のみ使用可能
フック
以下の6種類が存在する
- prerouting
- パケット受信時、かつルーティング前に実行
- ip、ip6、inet、bridgeに対応
- input
- ローカルホスト向けのパケット受信時
- ip、ip6、inet、bridge、arpに対応
- forward
- 転送される際に実行
- ip、ip6、inet、bridgeに対応
- output
- ローカルプロセスがパケット生成時に実行
- ip、ip6、inet、bridge、arpに対応
- postrouting
- パケット送信時に実行
- ip、ip6、inet、bridgeに対応
- ingress
- パケット受信時に実行
- netdevに対応
プライオリティ
- チェーン毎の優先順位(=同じフックが指定されたチェーンが複数存在する場合にどのチェーンから実行するか決める)
- 値が小さい順にチェーンが実行される
ポリシー
- チェーン内のルールに該当しなかった場合、パケットを許可(
accept
)するか、破棄(drop
)するかを指定する - 省略された場合は
accept
とみなされる
ルール
ルールの追加はnft insert rule
またはnft add rule
で行う。insert
だと指定したハンドル番号の前に、add
だと指定したハンドル番号の後にルールを追加する。ハンドル番号を指定しないと、insert
の場合先頭にルールが追加され、add
の場合末尾にルールが追加される。
nft add rule ip table01 chain01 handle [ハンドル番号] [式] [処理]
チェーンに登録されているルールを順に実行していき、全ルールの評価が完了するか、パケットがdrop
されるなどして評価を継続しない場合、そのチェーンでの評価が完了し、次のチェーンの評価を行う。
以下の例だと2つのルールを追加し、送信元IP59.138.xxx.xxx
からのパケットは許可して、それ以外はdropさせている。
# nft add rule ip table01 chain01 ip saddr 59.138.xxx.xxx accept # nft add rule ip table01 chain01 drop # nft -a list ruleset table ip table01 { # handle 1 chain chain01 { # handle 1 type filter hook input priority filter + 1; policy accept; ip saddr 59.138.xxx.xxx accept # handle 2 drop # handle 3 } }
以下の例だとハンドル番号3の前に、ルールがを追加している。
# nft insert rule ip table01 chain01 handle 3 ip saddr 59.139.xxx.xxx accept # nft -a list ruleset table ip table01 { # handle 1 chain chain01 { # handle 1 type filter hook input priority filter + 1; policy accept; ip saddr 59.138.xxx.xxx accept # handle 2 ip saddr 59.139.xxx.xxx accept # handle 4 drop # handle 3 } }
ルールの修正はreplace
、削除はdelete
で行う。
代表的な処理は次のようなものがある。
おそらく一番多い用途は送信元/先IPと送信先ポートの指定だと思う。
ip saddr 100.122.34.10 ip daddr 22.31.33.44 tcp dport 443 accept
上の例だと、送信元IPをip saddr
で指定し、送信先をip daddr
、接続先ポート番号をtcp dport
で指定している。
よく使用しそうなキーワードは以下の通り。
- IPアドレス指定
ip saddr [IPアドレス]
、ip daddr [IPアドレス]
(IPv6の場合はip6 saddr
、ICMPの場合はicmp saddr
といった感じ)
- プロトコル指定
ip protocol [プロトコル指定]
- ポート番号指定
tcp sport [ポート番号]
、tcp dport [ポート番号]
(UDPの場合は、udp sport
といった感じ)
他にもコネクションの状態やバイト数、など様々なキーワードがあり、複雑なケースにも対応できる。
ルールセットの保存と削除
ルールセットはnft list ruleset
で出力したテキストを読み込むことで復元できる。なので、nft list ruleset > ruleset.txt
でルールを保存することができる。ルールセットの削除はnft flush rulese
で行い、復元はnft -f ruleset.txt
とする。
# nft list ruleset table ip table01 { } # nft list ruleset > ruleset.txt # ルールセットの保存 # nft flush ruleset # ルールセットの削除 # nft list ruleset # nft -f ruleset.txt # ルールセットの読み込み # nft list ruleset table ip table01 { }
ルールセットの自動読み込み
nftablesコマンドによる設定は、電源を落としたり、再起動したりすると消える。RHELの場合は以下の方法で、システム起動時にnftablesルールを自動で読み込むことができる。これにより、常にシステムにルールが反映されるようにする。
RHELでは、/etc/sysconfig/nftables.conf
ファイルにシステム起動時に読み込むファイルをinclude
文で記述する。
/etc/sysconfig/nftables.conf
include "/etc/nftables/_example_.nft"
上記設定により、/etc/nftables/_example_.nft
から設定を読み込む。
systemctl restart nftables
で再起動せずに設定を読み込んでくれる。
参考
nftables
https://linuc.org/study/knowledge/1118/
https://knowledge.sakura.ad.jp/22636/
https://tech-blog.rakus.co.jp/entry/20220301/iptables
https://www.designet.co.jp/faq/term/?id=aXB0YWJsZXM#