iptablesの後継 nftables
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#