Nftables覚書
概要
Linuxにおけるパケットフィルタリングやアドレス変換のバックエンドには以前よりiptablesが使用されてきました。nftablesはiptablesに変わる手段であり、現在のほとんどのディストリビューションでは、公式リポジトリからインストールすることができます。以下ではnftablesの動作についての内容をメモ程度にまとめたものです。
Nftablesとは
出典: https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks
上図はLinuxマシンでのパケットの流れを簡略化したものです。nftablesはNetfilterへ定義されたフックを使用します。フックとはパケットフィルタリングの際に判定を行うタイミングを指します。例えば、Input Hook はSSHサーバやWebサーバなどのアプリケーションへパケットが進入する直前で実行されるため、アプリケーションが実行する前に特定の送信元IPアドレスを持ったパケットを破棄するなどといったルール及びセット定義することができます。また、ルールはチェインごとに設定することができます。iptablesとは異なり、nftablesはチェインをあらかじめ定義することはありません。しかし、ベースチェインと呼ばれるチェインへエントリポイントとして、各フックを定義する必要があります。さらに、チェインはIPv4トラフィックごとやL2トラフィックごとといったテーブル(ファミリ) 単位で定義することができます。
用語をまとめると次のようになります。
- ルール: フィルタリングなどの処理
- フック: ルールを評価するタイミング
- チェイン: ルールのあつまり
- テーブル: フックを評価するレイヤやプロトコル
nftablesの起動
nftablesをインストールした直後はあらかじめ/etc/nftables.conf
へステートフルファイアウォールの設定が記述されています。この設定はsystemctl start nftables.service
やnft -f /etc/nftables.conf
コマンドで実行することができます。ここで、留意する必要がある項目はnftablesは特定のデーモンを持たず、常にファイルからルールを読み込む点です。systemd
のExecStart
行から確認することができます。
ステートフルファイアウォール
以下は/etc/nftables.conf
の内容です。
#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:
# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.
table inet filter
delete table inet filter
table inet filter {
chain input {
type filter hook input priority filter
policy drop
ct state invalid drop comment "early drop of invalid connections"
ct state {established, related} accept comment "allow tracked connections"
iifname lo accept comment "allow from loopback"
ip protocol icmp accept comment "allow icmp"
meta l4proto ipv6-icmp accept comment "allow icmp v6"
tcp dport ssh accept comment "allow sshd"
pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
counter
}
chain forward {
type filter hook forward priority filter
policy drop
}
}
table <ファミリ> <テーブル名>
でテーブルを定義することができます。同様にchain <チェイン名>
でチェインを定義することができます。ただし、ベースチェインにはフックと優先度を明記する必要があります。type <ベースチェインタイプ> hook <フック> priority <優先度>
のように指定し、ベースチェインタイプはfilter
, route
, nat
の3つがあり、それぞれ使用できるフックやフックの処理内容が異なります。優先度は予約語か数値で指定することができます。
inetファミリにおけるフックの動作
nftablesをファイアウォールとして使用する際はほとんどの場合inetファミリが使用されます。inetファミリはIPv4とIPv6に関するパケットを扱います。
Prerouting
冒頭の図の通りNICに侵入したIPパケットが最初に処理されるHookです。この時点では宛先に関係なく処理することができます。
Input
Preroutingフック後に宛先がサーバのリスナーソケットなどのローカルプロセスの場合はInputフックへ進みます。このフックでは一般的なパケットフィルタリングをするファイアウォールとしての役割を定義することができます。
Output
ブラウザやWebサーバなどのローカルプロセスが生成するパケットは最初にOutputフックへ進みます。
Forward
Preroutingフック後に宛先が別のネットワークデバイスの場合はForwardフックへ進みます。ここでは転送するパケットに対しての処理が行われます。
Postrouting
NICから外部へ送信されるパケットはPostroutingフックへ進みます。このフックでは送信元アドレスを変換するNATとしての役割を定義することができます。
ルールの定義
nftablesのルールはチェイン内で定義することができ、式とステートメントを含みます。
ステートメントとは前述でのaccept
のようにパケットを許可、拒否、破棄するといったアクションやロギングの有効化といった操作を指定します。
式は使用することでインターフェース名やIPアドレス、ポート番号などを指定したルールを定義することができます。以下ではメタ式、IPv4ヘッダー式、TCPヘッダー式について説明します。式についてはここでは全てを説明しません。filter
チェインでよく利用するものについて説明します。その他、必要な場合はmanページを参照してください。
メタ式
メタ式は次のように利用します。
meta <メタ式タイプ>
メタ式タイプは例えばiifnameやoifnameのように入出力のインターフェースを指定してパケットを評価することができます。
meta iifname “lo” accept
上記の場合、入力インターフェースがループバックのパケットを許可します。
IPv4ヘッダー式
IPv4ヘッダー式は次のように利用します。
ip <IPv4ヘッダー式タイプ>
IPv4ヘッダー式タイプへは、宛先IPアドレスや送信元IPアドレス、上位層のプロトコルなどを指定できます。
ip saddr 192.168.1.1/24 accept
上記の場合、送信元IPアドレスが192.168.1.1
のパケットを許可します。
TCPヘッダー式
TCPヘッダー式は次のように利用します。
tcp <TCPヘッダー式タイプ>
TCPヘッダー式タイプへは、送信元ポート番号や宛先ポート番号などを指定することができます。
tcp dport 22 accept
上記の場合、宛先ポート番号が22のパケットを許可します。また、一部のウェルノウンポートについては予約語で指定することができます。tcp dport ssh accept
は上記と同じ意味です。
参考
- Nftables Wiki. https://wiki.nftables.org/wiki-nftables/index.php/Main_Page
- Arch manual page. "nft(8)". https://www.netfilter.org/projects/nftables/manpage.html
- Teldat. "Connecting some of the dots between Nftables, Iptables and Netfilter". https://www.teldat.com/blog/nftables-and-netfilter-hooks-via-linux-kernel/
- ArchWiki. "nftables". https://wiki.archlinux.jp/index.php/Nftables
- InfoSec Write-ups. "Linux Kernel Communication — Netfilter Hooks". https://infosecwriteups.com/linux-kernel-communication-part-1-netfilter-hooks-15c07a5a5c4e
- Torvalds. "GitHub". https://github.com/torvalds/linux/blob/master/net/netfilter
Discussion