nftables
nftables は既存の ip-, ip6-, arp-, ebtables フレームワークを置き換える netfilter のプロジェクトです。新しいパケットフィルタリングフレームワーク、新しいユーザースペースユーティリティ (nft)、そして ip- と ip6tables の互換レイヤーを提供します。現行のフック、接続追跡システム、ユーザースペースのキューイングコンポーネント、そして netfilter のログサブシステムを使っています。
nftables の公式 wiki には詳しい情報が載っています。
最初のリリースは Linux 3.13 から使うことが可能で、このカーネルは現在 [core] リポジトリに入っています (linux)。(ユーザースペースコンポーネントの) nftables は [extra] リポジトリから利用でき (nftables)、AUR には nftables-gitAUR パッケージがあります。
目次
概要
nftables は3つのメインコンポーネントから構成されています: カーネルの実装、libnl netlink communication そして nftables ユーザースペースフロントエンド。カーネルは netlink の設定インターフェイスだけでなく、小さなクラス言語インタプリタを使用するランタイムのルールセットの評価も提供します。libnl にはカーネルと通信するためのローレベルな関数が含まれています。nftables フロントエンドはユーザーが対話するものです。
nft
nftables のユーザースペースユーティリティ nft
は現在カーネルのためにルールセットを処理する前にほとんどのルールセットの評価を行います。そのため、nftables はデフォルトのテーブルやチェインを提供していません。しかしながらユーザーが iptables のような設定をエミュレートすることが可能です。
nft は ifconfig や iproute2 と同じような感じで動作します。iptables のように引数のスイッチを使う代わりに、長く構造化された連続のコマンドになります。例えば:
nft add rule ip6 filter input ip6 saddr ::1 accept
add
はコマンドです。rule
は add
のサブコマンドです。ip6
は rule
の引数で、ip6 ファミリーを使うことを宣言しています。filter
と input
は rule
の引数で、それぞれ使用するテーブルとチェインを指定しています。残りはルールの定義で、マッチ (ip
) とパラメータ (saddr
)、パラメータの引数 (::1
) そしてジャンプ (accept
) からなります。
以下は nft で利用できるコマンドの不完全なリストです:
list tables [family] table [family] <name> chain [family] <table> <name> add table [family] <name> chain [family] <table> <name> [chain definitions] rule [family] <table> <chain> <rule definition> table [family] <name> (shortcut for `add table`) insert rule [family] <table> <chain> <rule definition> delete table [family] <name> chain [family] <table> <name> rule [family] <table> <handle> flush table [family] <name> chain [family] <table> <name>
family
は任意ですが、デフォルトは ip
になります。
テーブル
テーブルの用途はチェインを保持することです。iptables のテーブルと違って、nftables には初めから組み込まれているテーブルはありません。テーブルは指定の5つのファミリーのうちどれか一つを持つことができ、それによって様々な iptables のユーティリティを一つに統一します:
nftables ファミリー | iptables ユーティリティ |
---|---|
ip | iptables |
ip6 | ip6tables |
inet | iptables と ip6tables |
arp | arptables |
bridge | ebtables |
ip
がデフォルトのファミリーです。inet
を使うには Linux 3.15 が必要で、ip と ip6 ファミリーを統一してルールを簡単に定義できます。
表示
ファミリーの現在のテーブルは nft list
コマンドで一覧できます。
# nft list tables # nft list tables ip6
テーブルの名前を指定することで完全なテーブルの定義を一覧できます:
# nft list table foo # nft list table ip6 foo
作成
テーブルは2つのコマンド (片方はもう片方のショートカットです) で追加することができます。以下は foo という名前の ip テーブルと foo という名前の ip6 テーブルを追加する例です:
# nft add table foo # nft table ip6 foo
ファミリーが異なっていれば同じ名前のテーブルを作ることが可能です。
削除
テーブルを削除することができるのはチェインが存在しない場合だけです。
# nft delete table foo # nft delete table ip6 foo
チェイン
チェインの用途はルールを保持することです。iptables のチェインと違って、nftables には初めから組み込まれているチェインはありません。そのためチェインが netfilter フレームワークにあるタイプやフックをどれも使わない場合、iptables とは異なりチェインを通り抜けるパケットは nftables の影響を受けません。
表示
nft list table foo
コマンドは foo テーブルの全てのチェインを表示します。個々のチェインからルールを一覧することもできます。
# nft list chain foo bar # nft list chain ip6 foo bar
上記コマンドは ip と ip6 の foo
テーブルの bar
チェインを表示します。
作成
テーブルがファイル定義や nft add chain
コマンドによって作成されたら、チェインを追加することができます。
# nft add chain foo bar # nft add chain ip6 foo bar
上記コマンドは bar
という名前のチェインを ip と ip6 の foo
テーブルに追加します。
プロパティ
nftables には組み込みチェインが存在しないため、チェインは netfilter フレームワークの特定の機能にアクセスすることができます。
# nft add chain filter input \{ type filter hook input priority 0\; \}
上記コマンドは nftables に input
という名前のチェインを filter
テーブルに追加させ、そのタイプ・フック・プライオリティを定義します。これらのプロパティは基本的に iptables で組み込まれているテーブルやチェインを置き換えるものです。
タイプ
チェインには3つのタイプがあり、iptables で使われているテーブルと対応しています:
- filter
- nat
- route (mangle)
フック
チェインは5つのフックを使うことができ、iptables で使われているチェインと対応しています:
- input
- output
- forward
- prerouting
- postrouting
プライオリティ
プライオリティは nftables がどのパケットを初めに通過させるかを示します。整数で指定し、高い値を与えるほど優先されます。
削除
チェインはルールが存在しない場合にのみ削除することができます。
# nft delete chain foo bar # nft delete chain ip6 foo bar
以上のコマンドは ip と ip6 の foo
テーブルから bar
チェインを削除します。
ルール
ルールの用途はパケットを識別(マッチ)して処理を実行(ジャンプ)することです。iptables と同じように、様々なマッチやジャンプが利用できますが、nftables には欠けている機能も存在します。
表示
テーブルを表示するのと同じ方法を使って、nft list
コマンドでテーブルの中の現在のルールを表示することができます。個別のチェインからルールを表示することも可能です。
# nft list chain foo bar # nft list chain ip6 foo bar
上記のコマンドで、ip と ip6 の foo
テーブルの bar
チェインのルールが表示されます。
作成
テーブルがファイル定義や nft add rule
コマンドによって作成されたら、ルールを追加することができます。
# nft add rule foo bar ip saddr 127.0.0.1 accept # nft add rule ip6 foo bar ip saddr ::1 accept
上記のコマンドで、ip と ip6 の foo
テーブルの bar
チェインにルールが追加され、saddr
(ソースアドレス) が 127.0.0.1 (IPv4) や ::1 (IPv6) の場合に ip
パケットにマッチして、パケットを許可します。
マッチ
nftables では様々なマッチを使うことができ、ほとんどは、iptables と対応するようになっています。一番大きな違いは汎用的なマッチと暗黙的なマッチが存在しないことです。汎用的なマッチとは、--protocol
や --source
のように、いつでも使うことができるマッチで、暗黙的なマッチとは、--sport
のように、特定のプロトコルでしか使えないマッチのことです。
以下は利用できるマッチの一部です:
- meta (meta properties, e.g. interfaces)
- icmp (ICMP protocol)
- icmpv6 (ICMPv6 protocol)
- ip (IP protocol)
- ip6 (IPv6 protocol)
- tcp (TCP protocol)
- udp (UDP protocol)
- sctp (SCTP protocol)
- ct (connection tracking)
以下はマッチ引数の一部です (完全なリストは man 8 nft
を見て下さい):
meta: oif <output interface INDEX> iif <input interface INDEX> oifname <output interface NAME> iifname <input interface NAME> (oif and iif accept string arguments and are converted to interface indexes) (oifname and iifname are more dynamic, but slower because of string matching) icmp: type <icmp type> icmpv6: type <icmpv6 type> ip: protocol <protocol> daddr <destination address> saddr <source address> ip6: daddr <destination address> saddr <source address> tcp: dport <destination port> sport <source port> udp: dport <destination port> sport <source port> sctp: dport <destination port> sport <source port> ct: state <new | established | related | invalid>
ジャンプ
ジャンプは iptables と同じように使うことができますが、ひとつのルールで複数のジャンプを使用できるようになっています。
# nft add rule filter input tcp dport 22 log accept
以下はジャンプの未完成なリストです:
- accept (accept a packet)
- reject (reject a packet)
- drop (drop a packet)
- snat (perform source NAT on a packet)
- dnat (perform destination NAT on a packet)
- log (log a packet)
- counter (keep a counter on a packet; counters are optional in nftables)
- return (stop traversing the chain)
- jump <chain> (jump to another chain)
- goto <chain> (jump to another chain, but do not return)
挿入
nft insert rule
コマンドでチェインにルールを挿入することができます。
# nft insert rule filter input ct state established,related accept
削除
個々のルールはハンドルを使わないと削除することができません。nft --handle list
コマンドを使うことでルールのハンドルを確認できます。--handle
スイッチを付けると、nft
はハンドルを出力するようになります。
以下ではルールのハンドルを確認してルールを削除しています。未解決の IP アドレスのような、数字の出力を表示するときは --number
引数を使うと良いでしょう。
# nft --handle --numeric list chain filter input
table ip fltrTable { chain input { type filter hook input priority 0; ip saddr 127.0.0.1 accept # handle 10 } }
# nft delete rule fltrTable input handle 10
nft flush table
コマンドを使うことでテーブルの全てのチェインをフラッシュできます。個別のチェインをフラッシュするときは nft flush chain
または nft delete rule
コマンドを使います。
# nft flush table foo # nft flush chain foo bar # nft delete rule ip6 foo bar
最初のコマンドでは ip foo
テーブルのチェイン全てをフラッシュします。2番目のコマンドは ip foo
テーブルの bar
チェインをフラッシュします。3番目のコマンドは ip6 foo
テーブルの bar
チェインの全てのルールを削除します。
アトミックリロード
現在のルールセットをフラッシュする:
# echo "flush ruleset" > /tmp/nftables
現在のルールセットをダンプする:
# nft list ruleset >> /tmp/nftables
/tmp/nftables
を編集して次のコマンドで変更を適用:
# nft -f /tmp/nftables
ファイル定義
nft -f
コマンドでファイル定義を利用することができます。このコマンドは iptables-restore
コマンドと同じように動作します。ただし、iptables-restore
と違って、既存のルールセットをフラッシュしないので、前もって flush コマンドを実行する必要があります。
/etc/nftables/filter.rules
flush table ip filter table ip filter { chain input { type filter hook input priority 0; ct state established,related accept ip saddr 127.0.0.1 accept tcp dport 22 log accept reject } }
ルールを (iptables-save
のように) エクスポートするには:
# nft list ruleset
基本的なファイアウォール
以下の例は nft コマンドを使ってベーシックな IPv4 ファイアウォールを設定する方法を示しています。IPv4 と IPv6 の両方をフィルタリングしたい場合、/usr/share/nftables
にある他のサンプルを見たり、/etc/nftables.conf
のデフォルト (IPv4/IPv6 で動作するように設定済みです) を使うようにしてください。
iptables のようなチェインを設定するには、まず備え付けの IPv4 フィルターファイルを使う必要があります:
# nft -f /usr/share/nftables/ipv4-filter
作成されたチェインを表示するには:
# nft list table filter
Drop output to a destination:
# nft add rule ip filter output ip daddr 1.2.3.4 drop
Drop packets destined for local port 80:
# nft add rule ip filter input tcp dport 80 drop
チェインの全てのルールを削除:
# nft delete rule filter output
サンプル
シンプルな IP/IPv6 ファイアウォール
firewall.rules
# A simple firewall flush ruleset table firewall { chain incoming { type filter hook input priority 0; # established/related connections ct state established,related accept # invalid connections ct state invalid drop # loopback interface iifname lo accept # icmp icmp type echo-request accept # open tcp ports: sshd (22), httpd (80) tcp dport {ssh, http} accept # everything else drop } } table ip6 firewall { chain incoming { type filter hook input priority 0; # established/related connections ct state established,related accept # invalid connections ct state invalid drop # loopback interface iifname lo accept # icmp # routers may also want: mld-listener-query, nd-router-solicit icmpv6 type {echo-request,nd-neighbor-solicit} accept # open tcp ports: sshd (22), httpd (80) tcp dport {ssh, http} accept # everything else drop } }
Limit rate IP/IPv6 ファイアウォール
firewall.2.rules
table firewall { chain incoming { type filter hook input priority 0; # no ping floods: ip protocol icmp limit rate 10/second accept ip protocol icmp drop ct state established,related accept ct state invalid drop iifname lo accept # avoid brute force on ssh: tcp dport ssh limit rate 15/minute accept reject } } table ip6 firewall { chain incoming { type filter hook input priority 0; # no ping floods: ip6 nexthdr icmpv6 limit rate 10/second accept ip6 nexthdr icmpv6 drop ct state established,related accept ct state invalid drop # loopback interface iifname lo accept # avoid brute force on ssh: tcp dport ssh limit rate 15/minute accept reject } }
ジャンプ
設定ファイルでジャンプを使うときは、先にターゲットチェインを定義する必要があります。そうしないと Error: Could not process rule: No such file or directory
というエラーが発生します。
jump.rules
table inet filter { chain web { tcp dport http accept tcp dport 8080 accept } chain input { type filter hook input priority 0; ip saddr 10.0.2.0/24 jump web drop } }
起動時にルールをロードする
システムの起動時にルールを自動的にロードするには、systemctl enable nftables
を実行して nftables の systemd サービスを有効にしてください。
ルールは /etc/nftables.conf
からデフォルトでロードされるようになっています。
Syslog にログを出力する
Linux カーネル 3.17 未満を使っている場合、ログ出力を有効にするには xt_LOG
を modprobe する必要があります。