「Nftables」の版間の差分
細 (→シンプルな IP/IPv6 ファイアウォール: ポート番号修正) |
細 (マークアップの訂正 (""使用しない"" -> '''使用しない'')) |
||
(7人の利用者による、間の13版が非表示) | |||
3行目: | 3行目: | ||
[[en:nftables]] |
[[en:nftables]] |
||
{{Related articles start}} |
{{Related articles start}} |
||
− | {{Related|ファイアウォール}} |
||
{{Related|iptables}} |
{{Related|iptables}} |
||
+ | {{Related|Firewalld}} |
||
{{Related articles end}} |
{{Related articles end}} |
||
− | [ |
+ | [https://netfilter.org/projects/nftables/ nftables] は既存の ip-, ip6-, arp-, ebtables フレームワークを置き換える netfilter のプロジェクトです。新しいパケットフィルタリングフレームワーク、新しいユーザースペースユーティリティ (nft)、そして ip- と ip6tables の互換レイヤーを提供します。現行のフック、接続追跡システム、ユーザースペースのキューイングコンポーネント、そして netfilter のログサブシステムを使っています。 |
nftables は3つのメインコンポーネントから構成されています: カーネルの実装、libnl netlink communication そして nftables ユーザースペースフロントエンド。カーネルは netlink の設定インターフェイスだけでなく、小さなクラス言語インタプリタを使用するランタイムのルールセットの評価も提供します。libnl にはカーネルと通信するためのローレベルな関数が含まれています。nftables フロントエンドはユーザーが対話するものです。 |
nftables は3つのメインコンポーネントから構成されています: カーネルの実装、libnl netlink communication そして nftables ユーザースペースフロントエンド。カーネルは netlink の設定インターフェイスだけでなく、小さなクラス言語インタプリタを使用するランタイムのルールセットの評価も提供します。libnl にはカーネルと通信するためのローレベルな関数が含まれています。nftables フロントエンドはユーザーが対話するものです。 |
||
− | [ |
+ | [https://wiki.nftables.org/wiki-nftables/index.php/Main_Page nftables の公式 wiki] には詳しい情報が載っています。 |
== インストール == |
== インストール == |
||
− | + | nftables のユーザーランドユーティリティは {{Pkg|nftables}} パッケージで利用できます。開発版の {{AUR|nftables-git}} パッケージも存在します。 |
|
+ | {{Tip|ほとんどの [[iptables#Front-ends|iptables フロントエンド]] はnftables の直接的または間接的なサポートを備えていませんが、導入することは可能です。[https://www.spinics.net/lists/netfilter/msg58215.html] nftables と iptables の両方をサポートするグラフィカルなフロントエンドとしては、[[firewalld]] があります。[https://firewalld.org/2018/07/nftables-backend]}} |
||
− | == 基本的な実装 == |
||
+ | == 使用方法 == |
||
− | 他のファイアウォールと異なり、nftables ではコマンドラインで作成される一時的なルールと、ファイルに保存して読み込まれる永続的なルールを区別しています。デフォルトファイルの {{ic|/etc/nftables.conf}} には "inet filter" という名前のシンプルな ipv4/ipv6 ファイアウォールテーブルが既に記述されています。 |
||
+ | nftables ではコマンドラインで作成される一時的なルールと、ファイルに保存して読み込まれる永続的なルールを区別していません。デフォルトファイルの {{ic|/etc/nftables.conf}} には "inet filter" という名前のシンプルな ipv4/ipv6 ファイアウォールテーブルが既に記述されています。 |
||
− | === デフォルトルールセットのロード === |
||
{{ic|nftables.service}} を[[起動]]・[[有効化]]してください。 |
{{ic|nftables.service}} を[[起動]]・[[有効化]]してください。 |
||
28行目: | 28行目: | ||
# nft list ruleset |
# nft list ruleset |
||
+ | === シンプルなファイアウォール === |
||
− | inet filter テーブルの設定が表示された場合、デスクトップとしてインターネットを問題なく利用できます。 |
||
+ | |
||
+ | {{Pkg|nftables}} には、{{ic|/etc/nftables.conf}} ファイルに保存されたシンプルで安全なファイアウォール設定が付属しています。 |
||
+ | |
||
+ | {{ic|nftables.service}} は、[[起動]]または[[有効化]]時に、このファイルからルールを読み込みます。 |
||
+ | == 設定 == |
||
− | {{Note|systemd サービスが正しく動作するように必要な nftables 関連のモジュール全てのエントリを含む {{ic|/etc/modules-load.d/nftables.conf}} を作成する必要があります。モジュールのリストは次のコマンドで取得可能です: {{bc|<nowiki>$ lsmod | grep '^nf'</nowiki>}} 作成していないと、{{ic|Error: Could not process rule: No such file or directory}} エラーで終了してしまいます。}} |
||
+ | nftables のユーザースペースユーティリティ {{ic|nft}} は現在カーネルのためにルールセットを処理する前にほとんどのルールセットの評価を行います。ルールはチェインに保存され、チェインはテーブルに保存されます。下のセクションではルールを作成・編集する方法を説明します。 |
||
− | == nft == |
||
− | nftables のユーザースペースユーティリティ {{ic|nft}} は現在カーネルのためにルールセットを処理する前にほとんどのルールセットの評価を行います。そのため、nftables はデフォルトのテーブルやチェインを提供していません。しかしながらユーザーが iptables のような設定をエミュレートすることが可能です。 |
||
+ | 下のセクションで行った変更は全て一時的なものになります。変更を永続化するにはルールセットを {{ic|/etc/nftables.conf}} に保存してください (ルールセットは {{ic|nftables.service}} によって読み込まれます): |
||
− | {{Note|{{Pkg|nftables}} には "filter" テーブルが記述されている {{ic|/etc/nftables.conf}} が含まれています。このテーブルのルールでは、特定のプロトコルだけを許可して、他のプロトコルは全て拒否するようになっています。}} |
||
+ | # nft list ruleset > /etc/nftables.conf |
||
− | nft は ifconfig や iproute2 と同じような感じで動作します。iptables のように引数のスイッチを使う代わりに、長く構造化された連続のコマンドになります。例えば: |
||
− | nft add rule ip6 filter input ip6 saddr ::1 accept |
||
− | {{ic|add}} はコマンドです。{{ic|rule}} は {{ic|add}} のサブコマンドです。{{ic|ip6}} は {{ic|rule}} の引数で、ip6 ファミリーを使うことを宣言しています。{{ic|filter}} と {{ic|input}} は {{ic|rule}} の引数で、それぞれ使用するテーブルとチェインを指定しています。残りはルールの定義で、マッチ ({{ic|ip}}) とパラメータ ({{ic|saddr}})、パラメータの引数 ({{ic|::1}}) そしてジャンプ ({{ic|accept}}) からなります。 |
||
+ | {{Note|{{ic|nft list}} は変数の定義を出力しません。{{ic|/etc/nftables.conf}} に何か記述していた場合、定義は失われます。ルールによって使われていた変数は変数の値に置き換えられます。}} |
||
− | 以下は nft で利用できるコマンドの不完全なリストです: |
||
− | <nowiki> |
||
− | list |
||
− | tables [family] |
||
− | table [family] <name> |
||
− | chain [family] <table> <name> |
||
+ | ファイルから入力するには {{ic|-f}} フラグを使用します: |
||
− | add |
||
− | table [family] <name> |
||
− | chain [family] <table> <name> [chain definitions] |
||
− | rule [family] <table> <chain> <rule definition> |
||
+ | # nft -f ''filename'' |
||
− | table [family] <name> (shortcut for `add table`) |
||
+ | ロード済みのルールは自動的に消去されることはないので注意してください。 |
||
− | insert |
||
− | rule [family] <table> <chain> <rule definition> |
||
+ | 利用可能なコマンドの一覧は {{man|8|nft}} を参照してください。 |
||
− | delete |
||
− | table [family] <name> |
||
− | chain [family] <table> <name> |
||
− | rule [family] <table> <handle> |
||
+ | ===テーブル=== |
||
− | flush |
||
− | table [family] <name> |
||
− | chain [family] <table> <name></nowiki> |
||
− | {{ic|family}} は任意ですが、デフォルトは {{ic|ip}} になります。 |
||
+ | テーブルは[[#チェイン|チェイン]]を保持します。iptables のテーブルと違って、nftables には初めから組み込まれているテーブルはありません。テーブルの数や名前はユーザーが自由に決めることができますが、各テーブルにはアドレスファミリーをひとつしか保持することができません。5つのファミリーのうち指定したファミリーのパケットにだけ適用されます: |
||
− | ==テーブル== |
||
− | テーブルの用途はチェインを保持することです。iptables のテーブルと違って、nftables には初めから組み込まれているテーブルはありません。テーブルは指定の5つのファミリーのうちどれか一つを持つことができ、それによって様々な iptables のユーティリティを一つに統一します: |
||
{| class="wikitable" |
{| class="wikitable" |
||
84行目: | 69行目: | ||
| bridge || ebtables |
| bridge || ebtables |
||
|} |
|} |
||
− | |||
− | === ファミリー === |
||
{{ic|ip}} (IPv4) がデフォルトのファミリーです。特に指定がなければ {{ic|ip}} が使われます。 |
{{ic|ip}} (IPv4) がデフォルトのファミリーです。特に指定がなければ {{ic|ip}} が使われます。 |
||
+ | IPv4 と IPv6 の両方に適用されるルールを作成するには {{ic|inet}} を使います。{{ic|inet}} を使うには Linux 3.15 以上が必要で、{{ic|ip}} と {{ic|ip6}} ファミリーを統一してルールを簡単に定義できます。 |
||
− | IPv6 は {{ic|ip6}} で指定できます。 |
||
+ | |||
+ | {{Note|{{ic|inet}} は {{ic|nat}} タイプのチェインでは使えず、{{ic|filter}} タイプのチェインを使う必要があります ([https://www.spinics.net/lists/netfilter/msg56411.html ソース])。}} |
||
+ | |||
+ | アドレスフファミリーの完全な定義は {{man|8|nft}} の {{ic|ADDRESS FAMILIES}} セクションを参照してください。 |
||
+ | |||
+ | 以下で例示しているコマンドの {{ic|''family''}} は全て任意であり、指定しなかった場合は {{ic|ip}} が使われます。 |
||
+ | |||
+ | ==== テーブルの作成 ==== |
||
+ | |||
+ | 以下のコマンドで新しいテーブルが追加されます: |
||
+ | |||
+ | # nft add table ''family'' ''table'' |
||
+ | ==== テーブルの表示 ==== |
||
− | IPv4 と IPv6 の両方に適用されるルールを作成するには {{ic|inet}} を使います。Linux 3.15 以上が必要で、{{ic|ip}} と {{ic|ip6}} ファミリーを統一してルールを簡単に定義できます。 |
||
+ | 全てのテーブルを表示するには: |
||
− | {{Note|{{ic|inet}} は {{ic|nat}} タイプのチェインでは使えず、{{ic|filter}} タイプのチェインを使う必要があります ([http://www.spinics.net/lists/netfilter/msg56411.html ソース])。}} |
||
− | ===表示=== |
||
− | ファミリーの現在のテーブルは {{ic|nft list}} コマンドで一覧できます。 |
||
# nft list tables |
# 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 list table ''family'' ''table'' |
||
− | ===削除=== |
||
− | テーブルを削除することができるのはチェインが存在しない場合だけです。 |
||
− | # nft delete table ''foo'' |
||
− | # nft delete table ''ip6 foo'' |
||
+ | 例えば {{ic|inet}} ファミリーの {{ic|filter}} テーブルのルールを全て表示するには: |
||
− | ==チェイン== |
||
− | チェインの用途はルールを保持することです。iptables のチェインと違って、nftables には初めから組み込まれているチェインはありません。そのためチェインが netfilter フレームワークにあるタイプやフックをどれも使わない場合、iptables とは異なりチェインを通り抜けるパケットは nftables の影響を受けません。 |
||
+ | # nft list table inet filter |
||
− | ===表示=== |
||
− | {{ic|nft list table foo}} コマンドは foo テーブルの全てのチェインを表示します。個々のチェインからルールを一覧することもできます。 |
||
− | # nft list chain ''foo'' ''bar'' |
||
− | # nft list chain ''ip6 foo bar'' |
||
− | 上記コマンドは ip と ip6 の {{ic|foo}} テーブルの {{ic|bar}} チェインを表示します。 |
||
+ | ==== テーブルの削除 ==== |
||
− | ===作成=== |
||
− | テーブルがファイル定義や {{ic|nft add chain}} コマンドによって作成されたら、チェインを追加することができます。 |
||
− | # nft add chain ''foo'' ''bar'' |
||
− | # nft add chain ''ip6 foo bar'' |
||
− | 上記コマンドは {{ic|bar}} という名前のチェインを ip と ip6 の {{ic|foo}} テーブルに追加します。 |
||
+ | テーブルを削除するには: |
||
− | ====プロパティ==== |
||
− | nftables には組み込みチェインが存在しないため、チェインは netfilter フレームワークの特定の機能にアクセスすることができます。 |
||
− | # nft add chain filter input \{ type filter hook input priority 0\; \} |
||
− | 上記コマンドは nftables に {{ic|input}} という名前のチェインを {{ic|filter}} テーブルに追加させ、そのタイプ・フック・プライオリティを定義します。これらのプロパティは基本的に iptables で組み込まれているテーブルやチェインを置き換えるものです。 |
||
+ | # nft delete table ''family'' ''table'' |
||
− | =====タイプ===== |
||
− | チェインには3つのタイプがあり、iptables で使われているテーブルと対応しています: |
||
− | *filter |
||
− | *nat |
||
− | *route (mangle) |
||
+ | テーブルはチェインが全く存在しない場合にのみ削除できます。 |
||
− | =====フック===== |
||
− | チェインは6つのフックを使うことができ、ingress 以外は iptables で使われているチェインと対応しています: |
||
− | *ingress |
||
− | *input |
||
− | *output |
||
− | *forward |
||
− | *prerouting |
||
− | *postrouting |
||
+ | ==== テーブルのクリア ==== |
||
− | ingress フックは既存の {{ic|tc}} ユーティリティを置き換えます。 |
||
+ | テーブルから全てのルールを消去するには: |
||
− | =====プライオリティ===== |
||
− | {{Note| |
||
− | * パケットが先に来るチェインにはプライオリティの効果はありません。 |
||
− | * プライオリティは符号なしの整数として設定するようになっているため、負のプライオリティを設定した場合、優先度は逆に高くなります。}} |
||
− | プライオリティは nftables がどのパケットを初めに通過させるかを示します。整数で指定し、高い値を与えるほど優先されます。 |
||
+ | # nft flush table ''family'' ''table'' |
||
− | === 編集 === |
||
+ | ===チェイン=== |
||
− | チェインを編集するには、以下のようにコマンドを実行してください: |
||
+ | |||
+ | チェインの用途は[[#ルール|ルール]]を保持することです。iptables のチェインと違って、nftables には初めから組み込まれているチェインはありません。そのためチェインが netfilter フレームワークにあるタイプやフックをどれも使わない場合、iptables とは異なりチェインを通り抜けるパケットは nftables の影響を受けません。 |
||
+ | |||
+ | チェインには2つのタイプがあります。''base'' チェインはネットワークスタックからのパケットのエントリポイントとなります。フックの値を指定することができます。''regular'' チェインはジャンプターゲットとして使用することができます。 |
||
+ | |||
+ | 以下のコマンドで使っている {{ic|''family''}} は全て任意であり、指定しなかった場合は {{ic|ip}} が使われます。 |
||
+ | |||
+ | ==== チェインの作成 ==== |
||
+ | |||
+ | ===== Regular チェイン ===== |
||
+ | |||
+ | 以下のコマンドは {{ic|''table''}} という名前のテーブルに {{ic|''chain''}} という名前のレギュラーチェインを追加します: |
||
+ | |||
+ | # nft add chain ''family'' ''table'' ''chain'' |
||
+ | |||
+ | 例えば、{{ic|inet}} アドレスファミリーの {{ic|filter}} テーブルに {{ic|tcpchain}} という名前のレギュラーチェインを追加するには: |
||
+ | |||
+ | # nft add chain inet filter tcpchain |
||
+ | |||
+ | ===== Base チェイン ===== |
||
+ | |||
+ | ベースチェインを追加するにはフックとプライオリティの値を指定します: |
||
+ | |||
+ | # nft add chain ''family'' ''table'' ''chain'' { type ''type'' hook ''hook'' priority ''priority'' \; } |
||
+ | |||
+ | {{ic|''type''}} は {{ic|filter}}, {{ic|route}}, {{ic|nat}} のどれかから選ぶことができます。 |
||
+ | |||
+ | IPv4/IPv6/Inet アドレスファミリーでは {{ic|''hook''}} は {{ic|prerouting}}, {{ic|input}}, {{ic|forward}}, {{ic|output}}, {{ic|postrouting}} のどれかになります。他のファミリーのフックについては {{man|8|nft}} を参照してください。 |
||
+ | |||
+ | {{ic|''priority''}} には整数値を指定します。低い値のチェインが先に処理され、負の値を指定することもできます [https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_types]。 |
||
+ | |||
+ | 例えば、input パケットをフィルタリングするベースチェインを追加するには: |
||
+ | |||
+ | # nft add chain inet filter input { type filter hook input priority 0\; } |
||
+ | |||
+ | {{ic|add}} を {{ic|create}} に置き換えると、チェインが既に存在するときにエラーが返ってくるようになります。 |
||
+ | |||
+ | ==== ルールの表示 ==== |
||
+ | |||
+ | 以下のコマンドでチェインの全てのルールを表示できます: |
||
+ | |||
+ | # nft list chain ''family'' ''table'' ''chain'' |
||
+ | |||
+ | 例えば、{{ic|filter}} という名前の {{ic|inet}} テーブルに存在する {{ic|output}} という名前のチェインのルールを表示するには: |
||
+ | |||
+ | # nft list chain inet filter output |
||
+ | |||
+ | ==== チェインの編集 ==== |
||
+ | |||
+ | チェインを編集したいときは、チェインの名前を指定して変更したいルールを定義します: |
||
# <nowiki>nft chain <table> <family> <chain> { [ type <type> hook <hook> device <device> priority <priority> \; policy <policy> \; ] }</nowiki> |
# <nowiki>nft chain <table> <family> <chain> { [ type <type> hook <hook> device <device> priority <priority> \; policy <policy> \; ] }</nowiki> |
||
− | 例えば、デフォルトテーブルの input チェイン |
+ | 例えば、デフォルトテーブルの input チェインポリシーを "accept" から "drop" に変更したい場合: |
# nft chain inet filter input { policy drop \; } |
# nft chain inet filter input { policy drop \; } |
||
− | ===削除=== |
+ | ==== チェインの削除 ==== |
+ | |||
− | チェインはルールが存在しない場合にのみ削除することができます。 |
||
+ | チェインを削除するには: |
||
− | # nft delete chain ''foo bar'' |
||
+ | |||
− | # nft delete chain ''ip6 foo bar'' |
||
+ | # nft delete chain ''family'' ''table'' ''chain'' |
||
− | 以上のコマンドは ip と ip6 の {{ic|foo}} テーブルから {{ic|bar}} チェインを削除します。 |
||
+ | |||
+ | 削除するチェインにはルールやジャンプターゲットが含まれていてはいけません。 |
||
+ | |||
+ | ==== チェインのルールを消去 ==== |
||
+ | |||
+ | チェインからルールを消去するには: |
||
+ | |||
+ | # nft flush chain ''family'' ''table'' ''chain'' |
||
+ | |||
+ | === ルール === |
||
+ | |||
+ | ルールは表現または宣言から構成され、チェインの中に格納されます。 |
||
+ | |||
+ | ==== ルールの追加 ==== |
||
+ | |||
+ | {{Tip|''iptables-translate'' ユーティリティを使うことで [[iptables]] のルールを nftables フォーマットに変換できます。}} |
||
+ | |||
+ | チェインにルールを追加するには: |
||
+ | |||
+ | # nft add rule ''family'' ''table'' ''chain'' ''position'' ''statement'' |
||
+ | |||
+ | ルールは {{ic|''position''}} に追加されます。位置は指定しなくてもかまいません。指定しなかった場合、ルールはチェインの末尾に追加されます。 |
||
+ | |||
+ | 特定の位置の前にルールを追加するには: |
||
+ | |||
+ | # nft insert rule ''family'' ''table'' ''chain'' ''position'' ''statement'' |
||
+ | {{ic|''position''}} を指定しなかった場合、ルールはチェインの一番前に追加されます。 |
||
− | ==ルール== |
||
− | ルールの用途はパケットを識別(マッチ)して処理を実行(ジャンプ)することです。iptables と同じように、様々なマッチやジャンプが利用できますが、nftables には欠けている機能も存在します。 |
||
− | ===表 |
+ | ===== 表現 ===== |
− | テーブルを表示するのと同じ方法を使って、{{ic|nft list}} コマンドでテーブルの中の現在のルールを表示することができます。個別のチェインからルールを表示することも可能です。 |
||
− | # nft list chain ''foo bar'' |
||
− | # nft list chain ''ip6 foo bar'' |
||
− | 上記のコマンドで、ip と ip6 の {{ic|foo}} テーブルの {{ic|bar}} チェインのルールが表示されます。 |
||
+ | {{ic|''statement''}} にはマッチする表現と判断宣言が入ります。判断宣言には {{ic|accept}}, {{ic|drop}}, {{ic|queue}}, {{ic|continue}}, {{ic|return}}, {{ic|jump ''chain''}}, {{ic|goto ''chain''}} などが存在します。判断宣言以外の宣言も指定できます。詳しくは {{man|8|nft}} を参照してください。 |
||
− | ===作成=== |
||
− | テーブルがファイル定義や {{ic|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 の {{ic|foo}} テーブルの {{ic|bar}} チェインにルールが追加され、{{ic|saddr}} (ソースアドレス) が 127.0.0.1 (IPv4) や ::1 (IPv6) の場合に {{ic|ip}} パケットにマッチして、パケットを許可します。 |
||
+ | nftables では様々な表現を使うことができ、ほとんどは、iptables と対応するようになっています。一番大きな違いは汎用的なマッチと暗黙的なマッチが存在しないことです。汎用的なマッチとは、{{ic|--protocol}} や {{ic|--source}} のように、いつでも使うことができるマッチで、暗黙的なマッチとは、{{ic|--sport}} のように、特定のプロトコルでしか使えないマッチのことです。 |
||
− | ====マッチ==== |
||
− | nftables では様々なマッチを使うことができ、ほとんどは、iptables と対応するようになっています。一番大きな違いは汎用的なマッチと暗黙的なマッチが存在しないことです。汎用的なマッチとは、{{ic|--protocol}} や {{ic|--source}} のように、いつでも使うことができるマッチで、暗黙的なマッチとは、{{ic|--sport}} のように、特定のプロトコルでしか使えないマッチのことです。 |
||
以下は利用できるマッチの一部です: |
以下は利用できるマッチの一部です: |
||
204行目: | 226行目: | ||
* ct (接続のトラッキング) |
* ct (接続のトラッキング) |
||
− | 以下はマッチ引数の一部です (完全なリストは {{man|8|nft |
+ | 以下はマッチ引数の一部です (完全なリストは {{man|8|nft}} を見て下さい): |
<nowiki> |
<nowiki> |
||
meta: |
meta: |
||
245行目: | 267行目: | ||
state <new | established | related | invalid></nowiki> |
state <new | established | related | invalid></nowiki> |
||
− | ==== |
+ | ====削除==== |
− | ジャンプは iptables と同じように使うことができますが、ひとつのルールで複数のジャンプを使用できるようになっています。 |
||
− | # nft add rule filter input tcp dport 22 log accept |
||
− | |||
− | 以下はジャンプの未完成なリストです: |
||
− | *accept (パケットを許可) |
||
− | *reject (パケットを拒否) |
||
− | *drop (パケットを破棄) |
||
− | *snat (送信元 NAT を実行) |
||
− | *dnat (宛先 NAT を実行) |
||
− | *log (パケットを記録) |
||
− | *counter (パケットカウンタを保持、nftables ではカウンタはオプションです) |
||
− | *return (チェインの横断を停止) |
||
− | *jump <chain> (他のチェインにジャンプ) |
||
− | *goto <chain> (他のチェインにジャンプ、元のチェインに戻らない) |
||
− | |||
− | ===挿入=== |
||
− | |||
− | ====先頭に追加==== |
||
− | {{ic|nft insert rule}} コマンドでチェインにルールを挿入することができます。 |
||
− | # nft insert rule filter input ct state established,related accept |
||
− | |||
− | ==== 特定の場所に追加 ==== |
||
− | |||
− | Nftables はハンドルを使用してルールの位置を定義します。情報を取得するには、-a フラグを付けてルールセットを確認してください: |
||
− | |||
− | # nft list ruleset -a |
||
− | |||
− | 特定のハンドラが付いているルールの後にルールを追加するには: |
||
− | |||
− | # nft add rule ''table_name'' ''chain_name'' position ''handler_number'' ''[rule-definition]'' |
||
− | |||
− | ===削除=== |
||
個々のルールはハンドルを使わないと削除することができません。{{ic|nft --handle list}} コマンドを使うことでルールのハンドルを確認できます。{{ic|--handle}} スイッチを付けると、{{ic|nft}} はハンドルを出力するようになります。 |
個々のルールはハンドルを使わないと削除することができません。{{ic|nft --handle list}} コマンドを使うことでルールのハンドルを確認できます。{{ic|--handle}} スイッチを付けると、{{ic|nft}} はハンドルを出力するようになります。 |
||
307行目: | 297行目: | ||
# nft -f /tmp/nftables |
# nft -f /tmp/nftables |
||
− | == |
+ | == サンプル == |
− | {{ic|nft -f}} コマンドでファイル定義を利用することができます。このコマンドは {{ic|iptables-restore}} コマンドと同じように動作します。ただし、{{ic|iptables-restore}} と違って、既存のルールセットをフラッシュしないので、前もって flush コマンドを実行する必要があります。 |
||
− | {{hc|/etc/nftables/filter.rules|2= |
||
− | <nowiki> |
||
− | 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 |
||
− | } |
||
− | } |
||
− | </nowiki> |
||
− | }} |
||
+ | === ワークステーション === |
||
− | ルールを ({{ic|iptables-save}} のように) エクスポートするには: |
||
− | # nft list ruleset |
||
+ | {{hc|/etc/nftables.conf|2=<nowiki> |
||
− | ==基本的なファイアウォール== |
||
+ | flush ruleset |
||
− | 以下の例は ''nft'' コマンドを使ってベーシックな ''IPv4'' ファイアウォールを設定する方法を示しています。IPv4 と IPv6 の両方をフィルタリングしたい場合、{{ic|/usr/share/nftables}} にある他のサンプルを見たり、{{ic|/etc/nftables.conf}} のデフォルト (IPv4/IPv6 で動作するように設定済みです) を使うようにしてください。 |
||
+ | table inet filter { |
||
− | [[iptables]] のようなチェインを設定するには、まず備え付けの IPv4 フィルターファイルを使う必要があります: |
||
+ | chain input { |
||
+ | type filter hook input priority 0; |
||
+ | # accept any localhost traffic |
||
− | # nft -f /usr/share/nftables/ipv4-filter |
||
+ | iif lo accept |
||
+ | # accept traffic originated from us |
||
− | 作成されたチェインを表示するには: |
||
+ | ct state established,related accept |
||
+ | # activate the following line to accept common local services |
||
− | # nft list table filter |
||
+ | #tcp dport { 22, 80, 443 } ct state new accept |
||
+ | # accept neighbour discovery otherwise IPv6 connectivity breaks. |
||
− | 特定の宛先への出力を破棄: |
||
+ | ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept |
||
+ | # count and drop any other traffic |
||
− | # nft add rule ip filter output ip daddr 1.2.3.4 drop |
||
+ | counter drop |
||
− | |||
+ | } |
||
− | 宛先がローカルのポート 80 のパケットを破棄: |
||
+ | } |
||
− | |||
+ | </nowiki>}} |
||
− | # nft add rule ip filter input tcp dport 80 drop |
||
− | |||
− | チェインの全てのルールを削除: |
||
− | |||
− | # nft delete rule filter output |
||
− | == |
+ | === シンプルな IPv4/IPv6 ファイアウォール === |
− | ===シンプルな IP/IPv6 ファイアウォール=== |
||
{{hc|firewall.rules|2=<nowiki> |
{{hc|firewall.rules|2=<nowiki> |
||
382行目: | 357行目: | ||
tcp dport { http, https } accept |
tcp dport { http, https } accept |
||
} |
} |
||
− | }</nowiki>}} |
||
+ | chain forward { |
||
− | ===Limit rate IP/IPv6 ファイアウォール=== |
||
+ | type filter hook forward priority 0; policy drop; |
||
+ | } |
||
+ | |||
+ | chain output { |
||
+ | type filter hook output priority 0; policy accept; |
||
+ | } |
||
+ | |||
+ | } |
||
+ | </nowiki>}} |
||
+ | |||
+ | ===レート制限 IPv4/IPv6 ファイアウォール=== |
||
{{hc|firewall.2.rules|2=<nowiki> |
{{hc|firewall.2.rules|2=<nowiki> |
||
398行目: | 383行目: | ||
ct state invalid drop |
ct state invalid drop |
||
− | + | iif lo accept |
|
# avoid brute force on ssh: |
# avoid brute force on ssh: |
||
404行目: | 389行目: | ||
} |
} |
||
+ | |||
+ | chain forward { |
||
+ | type filter hook forward priority 0; policy drop; |
||
+ | } |
||
+ | |||
+ | chain output { |
||
+ | type filter hook output priority 0; policy accept; |
||
+ | } |
||
+ | |||
} |
} |
||
</nowiki>}} |
</nowiki>}} |
||
===ジャンプ=== |
===ジャンプ=== |
||
+ | |||
設定ファイルでジャンプを使うときは、先にターゲットチェインを定義する必要があります。そうしないと {{ic|Error: Could not process rule: No such file or directory}} というエラーが発生します。 |
設定ファイルでジャンプを使うときは、先にターゲットチェインを定義する必要があります。そうしないと {{ic|Error: Could not process rule: No such file or directory}} というエラーが発生します。 |
||
{{hc|jump.rules|2= |
{{hc|jump.rules|2= |
||
424行目: | 419行目: | ||
</nowiki> |
</nowiki> |
||
}} |
}} |
||
− | |||
− | == 実践的なサンプル == |
||
=== インターフェイスによってルールを変える === |
=== インターフェイスによってルールを変える === |
||
435行目: | 428行目: | ||
type filter hook input priority 0; |
type filter hook input priority 0; |
||
− | + | iif lo accept # always accept loopback |
|
iifname enp2s0 jump input_enp2s0 |
iifname enp2s0 jump input_enp2s0 |
||
iifname enp3s0 jump input_enp3s0 |
iifname enp3s0 jump input_enp3s0 |
||
471行目: | 464行目: | ||
{{ic|masquerade}} を使用するには: |
{{ic|masquerade}} を使用するには: |
||
− | * カーネルのバージョンが 3.18 以上である必要があります。 |
||
* カーネルコンフィグで以下のマスカレード設定が有効になっている必要があります。 |
* カーネルコンフィグで以下のマスカレード設定が有効になっている必要があります。 |
||
491行目: | 483行目: | ||
}</nowiki> |
}</nowiki> |
||
+ | == ヒントとテクニック == |
||
− | ==Syslog にログを出力する== |
||
+ | |||
+ | === シンプルなステートフルファイアウォール === |
||
+ | |||
+ | [[シンプルなステートフルファイアウォール]]の記事も参照してください。 |
||
+ | |||
+ | ==== シングルマシン ==== |
||
+ | |||
+ | 現在のルールセットを消去: |
||
+ | |||
+ | # nft flush ruleset |
||
+ | |||
+ | テーブルを追加: |
||
+ | |||
+ | # nft add table inet filter |
||
+ | |||
+ | input, forward, output ベースチェインを追加。input と forward のポリシーは破棄にして、output のポリシーは許可にする: |
||
+ | |||
+ | # nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; } |
||
+ | # nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; } |
||
+ | # nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; } |
||
+ | |||
+ | レギュラーチェインを追加して tcp と udp に関連付ける: |
||
+ | |||
+ | # nft add chain inet filter TCP |
||
+ | # nft add chain inet filter UDP |
||
+ | |||
+ | 関連・確立済みトラフィックは許可する: |
||
+ | |||
+ | # nft add rule inet filter input ct state related,established accept |
||
+ | |||
+ | ループバックインターフェイスのトラフィックは全て許可する: |
||
+ | |||
+ | # nft add rule inet filter input iif lo accept |
||
+ | |||
+ | 不正なトラフィックは全て破棄する: |
||
+ | |||
+ | # nft add rule inet filter input ct state invalid drop |
||
+ | |||
+ | 新しいエコー要求 (ping) は許可する: |
||
+ | |||
+ | # nft add rule inet filter input ip protocol icmp icmp type echo-request ct state new accept |
||
+ | |||
+ | 新しい udp トラフィックは UDP チェインにジャンプする: |
||
+ | |||
+ | # nft add rule inet filter input ip protocol udp ct state new jump UDP |
||
+ | |||
+ | 新しい tcp トラフィックは TCP チェインにジャンプする: |
||
+ | |||
+ | # nft add rule inet filter input ip protocol tcp tcp flags \& \(fin\|syn\|rst\|ack\) == syn ct state new jump TCP |
||
+ | |||
+ | 他のルールによって処理されなかったトラフィックは全て拒否する: |
||
+ | |||
+ | # nft add rule inet filter input ip protocol udp reject |
||
+ | # nft add rule inet filter input ip protocol tcp reject with tcp reset |
||
+ | # nft add rule inet filter input counter reject with icmp type prot-unreachable |
||
+ | |||
+ | ここから TCP と UDP チェインで処理する接続で開きたいポートを決めます。例えばウェブサーバーの接続を開くには: |
||
+ | |||
+ | # nft add rule inet filter TCP tcp dport 80 accept |
||
+ | |||
+ | ポート 443 からのウェブサーバーの HTTPS 接続を許可するには: |
||
+ | |||
+ | # nft add rule inet filter TCP tcp dport 443 accept |
||
+ | |||
+ | ポート 22 の SSH 接続を許可するには: |
||
+ | |||
+ | # nft add rule inet filter TCP tcp dport 22 accept |
||
+ | |||
+ | DNS リクエストを許可するには: |
||
+ | |||
+ | # nft add rule inet filter TCP tcp dport 53 accept |
||
+ | # nft add rule inet filter UDP tcp dport 53 accept |
||
+ | |||
+ | 設定に満足したら変更を保存して永続化させてください。 |
||
+ | |||
+ | === ブルートフォース攻撃の対策 === |
||
+ | |||
+ | [[Sshguard]] はブルートフォース攻撃を検出して一時的に IP アドレスに基づきブロックするようにファイアウォールを編集します。Sshguard で nftables を使うように設定する方法は [[Sshguard#nftables]] を見てください。 |
||
+ | |||
+ | == トラブルシューティング == |
||
+ | |||
+ | === Docker と共に使う === |
||
+ | |||
+ | {{Note| |
||
+ | * 次のセットアップでは、{{ic|--net host --privileged}} を使用してもコンテナ内で {{ic|AF_BLUETOOTH}} などのプロトコルを利用できなくなります。 |
||
+ | * Rootless Dockerコンテナはすでに別のネットワーク名前空間で実行されています。何もする必要がないかもしれません。 |
||
+ | }} |
||
+ | |||
+ | nftables を使用すると、[[Docker]] のネットワーク (おそらく他のコンテナランタイムも同様) に干渉する可能性があります。 |
||
+ | iptables ルールにパッチを適用して定義されたサービス開始順序を確保するか、docker の使用が非常に制限される dockerのiptablesの管理を完全に無効にするなど、さまざまな回避策がインターネット上で見つかります。 |
||
+ | (ポートフォワーディングや docker-compose を考えてください) |
||
+ | |||
+ | 信頼できる方法は、docker を別のネットワーク名前空間で実行させ、そこで任意の処理を実行できるようにすることです。 |
||
+ | Docker が nftables と iptables ルールを混在させないように、{{Pkg|iptables-nft}} を'''使用しない'''方が良いでしょう。 |
||
+ | |||
+ | 以下の docker サービス [[ドロップインファイル]] を使用してください: |
||
+ | |||
+ | {{hc|/etc/systemd/system/docker.service.d/netns.conf|2= |
||
+ | [Service] |
||
+ | PrivateNetwork=yes |
||
+ | |||
+ | # cleanup |
||
+ | ExecStartPre=-nsenter -t 1 -n -- ip link delete docker0 |
||
+ | |||
+ | # add veth |
||
+ | ExecStartPre=nsenter -t 1 -n -- ip link add docker0 type veth peer name docker0_ns |
||
+ | ExecStartPre=sh -c 'nsenter -t 1 -n -- ip link set docker0_ns netns "$$BASHPID" && true' |
||
+ | ExecStartPre=ip link set docker0_ns name eth0 |
||
+ | |||
+ | # bring host online |
||
+ | ExecStartPre=nsenter -t 1 -n -- ip addr add 10.0.0.1/24 dev docker0 |
||
+ | ExecStartPre=nsenter -t 1 -n -- ip link set docker0 up |
||
+ | |||
+ | # bring ns online |
||
+ | ExecStartPre=ip addr add 10.0.0.100/24 dev eth0 |
||
+ | ExecStartPre=ip link set eth0 up |
||
+ | ExecStartPre=ip route add default via 10.0.0.1 dev eth0 |
||
+ | }} |
||
+ | |||
+ | セットアップにおいてIPアドレス {{ic|10.0.0.*}} が適切でない場合は、調整してください。 |
||
+ | |||
+ | 以下のポストルーティングルールで、{{ic|docker0}} のIPフォワーディングを有効にし、NATを設定します: |
||
+ | |||
+ | iifname docker0 oifname eth0 masquerade |
||
+ | |||
+ | 次に、[[インターネット共有#パケット転送の有効化|kernel IP forwarding]] が有効になっていることを確認します。 |
||
+ | |||
+ | これで、nftables を使用して {{ic|docker0}} インターフェイスのファイアウォールとポートフォワーディングを干渉することなくセットアップできるようになります。 |
||
− | Linux カーネル 3.17 未満を使っている場合、ログ出力を有効にするには {{ic|xt_LOG}} を modprobe する必要があります。 |
||
==参照== |
==参照== |
||
500行目: | 619行目: | ||
* [https://home.regit.org/netfilter-en/nftables-quick-howto/ nftables クイックハウツー] |
* [https://home.regit.org/netfilter-en/nftables-quick-howto/ nftables クイックハウツー] |
||
* [https://lwn.net/Articles/564095/ nftables の帰還] |
* [https://lwn.net/Articles/564095/ nftables の帰還] |
||
− | * [ |
+ | * [https://developers.redhat.com/blog/2016/10/28/what-comes-after-iptables-its-successor-of-course-nftables/ What comes after ‘iptables’? It’s successor, of course: `nftables`] |
2023年9月20日 (水) 15:51時点における最新版
nftables は既存の ip-, ip6-, arp-, ebtables フレームワークを置き換える netfilter のプロジェクトです。新しいパケットフィルタリングフレームワーク、新しいユーザースペースユーティリティ (nft)、そして ip- と ip6tables の互換レイヤーを提供します。現行のフック、接続追跡システム、ユーザースペースのキューイングコンポーネント、そして netfilter のログサブシステムを使っています。
nftables は3つのメインコンポーネントから構成されています: カーネルの実装、libnl netlink communication そして nftables ユーザースペースフロントエンド。カーネルは netlink の設定インターフェイスだけでなく、小さなクラス言語インタプリタを使用するランタイムのルールセットの評価も提供します。libnl にはカーネルと通信するためのローレベルな関数が含まれています。nftables フロントエンドはユーザーが対話するものです。
nftables の公式 wiki には詳しい情報が載っています。
インストール
nftables のユーザーランドユーティリティは nftables パッケージで利用できます。開発版の nftables-gitAUR パッケージも存在します。
使用方法
nftables ではコマンドラインで作成される一時的なルールと、ファイルに保存して読み込まれる永続的なルールを区別していません。デフォルトファイルの /etc/nftables.conf
には "inet filter" という名前のシンプルな ipv4/ipv6 ファイアウォールテーブルが既に記述されています。
nftables.service
を起動・有効化してください。
以下のコマンドでルールセットを確認できます:
# nft list ruleset
シンプルなファイアウォール
nftables には、/etc/nftables.conf
ファイルに保存されたシンプルで安全なファイアウォール設定が付属しています。
nftables.service
は、起動または有効化時に、このファイルからルールを読み込みます。
設定
nftables のユーザースペースユーティリティ nft
は現在カーネルのためにルールセットを処理する前にほとんどのルールセットの評価を行います。ルールはチェインに保存され、チェインはテーブルに保存されます。下のセクションではルールを作成・編集する方法を説明します。
下のセクションで行った変更は全て一時的なものになります。変更を永続化するにはルールセットを /etc/nftables.conf
に保存してください (ルールセットは nftables.service
によって読み込まれます):
# nft list ruleset > /etc/nftables.conf
ファイルから入力するには -f
フラグを使用します:
# nft -f filename
ロード済みのルールは自動的に消去されることはないので注意してください。
利用可能なコマンドの一覧は nft(8) を参照してください。
テーブル
テーブルはチェインを保持します。iptables のテーブルと違って、nftables には初めから組み込まれているテーブルはありません。テーブルの数や名前はユーザーが自由に決めることができますが、各テーブルにはアドレスファミリーをひとつしか保持することができません。5つのファミリーのうち指定したファミリーのパケットにだけ適用されます:
nftables ファミリー | iptables ユーティリティ |
---|---|
ip | iptables |
ip6 | ip6tables |
inet | iptables と ip6tables |
arp | arptables |
bridge | ebtables |
ip
(IPv4) がデフォルトのファミリーです。特に指定がなければ ip
が使われます。
IPv4 と IPv6 の両方に適用されるルールを作成するには inet
を使います。inet
を使うには Linux 3.15 以上が必要で、ip
と ip6
ファミリーを統一してルールを簡単に定義できます。
アドレスフファミリーの完全な定義は nft(8) の ADDRESS FAMILIES
セクションを参照してください。
以下で例示しているコマンドの family
は全て任意であり、指定しなかった場合は ip
が使われます。
テーブルの作成
以下のコマンドで新しいテーブルが追加されます:
# nft add table family table
テーブルの表示
全てのテーブルを表示するには:
# nft list tables
テーブル内のチェインとルールの表示
指定したテーブルの全てのチェインとルールを表示するには:
# nft list table family table
例えば inet
ファミリーの filter
テーブルのルールを全て表示するには:
# nft list table inet filter
テーブルの削除
テーブルを削除するには:
# nft delete table family table
テーブルはチェインが全く存在しない場合にのみ削除できます。
テーブルのクリア
テーブルから全てのルールを消去するには:
# nft flush table family table
チェイン
チェインの用途はルールを保持することです。iptables のチェインと違って、nftables には初めから組み込まれているチェインはありません。そのためチェインが netfilter フレームワークにあるタイプやフックをどれも使わない場合、iptables とは異なりチェインを通り抜けるパケットは nftables の影響を受けません。
チェインには2つのタイプがあります。base チェインはネットワークスタックからのパケットのエントリポイントとなります。フックの値を指定することができます。regular チェインはジャンプターゲットとして使用することができます。
以下のコマンドで使っている family
は全て任意であり、指定しなかった場合は ip
が使われます。
チェインの作成
Regular チェイン
以下のコマンドは table
という名前のテーブルに chain
という名前のレギュラーチェインを追加します:
# nft add chain family table chain
例えば、inet
アドレスファミリーの filter
テーブルに tcpchain
という名前のレギュラーチェインを追加するには:
# nft add chain inet filter tcpchain
Base チェイン
ベースチェインを追加するにはフックとプライオリティの値を指定します:
# nft add chain family table chain { type type hook hook priority priority \; }
type
は filter
, route
, nat
のどれかから選ぶことができます。
IPv4/IPv6/Inet アドレスファミリーでは hook
は prerouting
, input
, forward
, output
, postrouting
のどれかになります。他のファミリーのフックについては nft(8) を参照してください。
priority
には整数値を指定します。低い値のチェインが先に処理され、負の値を指定することもできます [3]。
例えば、input パケットをフィルタリングするベースチェインを追加するには:
# nft add chain inet filter input { type filter hook input priority 0\; }
add
を create
に置き換えると、チェインが既に存在するときにエラーが返ってくるようになります。
ルールの表示
以下のコマンドでチェインの全てのルールを表示できます:
# nft list chain family table chain
例えば、filter
という名前の inet
テーブルに存在する output
という名前のチェインのルールを表示するには:
# nft list chain inet filter output
チェインの編集
チェインを編集したいときは、チェインの名前を指定して変更したいルールを定義します:
# nft chain <table> <family> <chain> { [ type <type> hook <hook> device <device> priority <priority> \; policy <policy> \; ] }
例えば、デフォルトテーブルの input チェインポリシーを "accept" から "drop" に変更したい場合:
# nft chain inet filter input { policy drop \; }
チェインの削除
チェインを削除するには:
# nft delete chain family table chain
削除するチェインにはルールやジャンプターゲットが含まれていてはいけません。
チェインのルールを消去
チェインからルールを消去するには:
# nft flush chain family table chain
ルール
ルールは表現または宣言から構成され、チェインの中に格納されます。
ルールの追加
チェインにルールを追加するには:
# nft add rule family table chain position statement
ルールは position
に追加されます。位置は指定しなくてもかまいません。指定しなかった場合、ルールはチェインの末尾に追加されます。
特定の位置の前にルールを追加するには:
# nft insert rule family table chain position statement
position
を指定しなかった場合、ルールはチェインの一番前に追加されます。
表現
statement
にはマッチする表現と判断宣言が入ります。判断宣言には accept
, drop
, queue
, continue
, return
, jump chain
, goto chain
などが存在します。判断宣言以外の宣言も指定できます。詳しくは nft(8) を参照してください。
nftables では様々な表現を使うことができ、ほとんどは、iptables と対応するようになっています。一番大きな違いは汎用的なマッチと暗黙的なマッチが存在しないことです。汎用的なマッチとは、--protocol
や --source
のように、いつでも使うことができるマッチで、暗黙的なマッチとは、--sport
のように、特定のプロトコルでしか使えないマッチのことです。
以下は利用できるマッチの一部です:
- meta (メタプロパティ。例: インターフェイス)
- icmp (ICMP プロトコル)
- icmpv6 (ICMPv6 プロトコル)
- ip (IP プロトコル)
- ip6 (IPv6 プロトコル)
- tcp (TCP プロトコル)
- udp (UDP プロトコル)
- sctp (SCTP プロトコル)
- ct (接続のトラッキング)
以下はマッチ引数の一部です (完全なリストは nft(8) を見て下さい):
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>
削除
個々のルールはハンドルを使わないと削除することができません。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
サンプル
ワークステーション
/etc/nftables.conf
flush ruleset table inet filter { chain input { type filter hook input priority 0; # accept any localhost traffic iif lo accept # accept traffic originated from us ct state established,related accept # activate the following line to accept common local services #tcp dport { 22, 80, 443 } ct state new accept # accept neighbour discovery otherwise IPv6 connectivity breaks. ip6 nexthdr icmpv6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept # count and drop any other traffic counter drop } }
シンプルな IPv4/IPv6 ファイアウォール
firewall.rules
# A simple firewall flush ruleset table inet filter { chain input { type filter hook input priority 0; policy drop; # established/related connections ct state established,related accept # invalid connections ct state invalid drop # loopback interface iif lo accept # ICMP # routers may also want: mld-listener-query, nd-router-solicit ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept # SSH (port 22) tcp dport ssh accept # HTTP (ports 80 & 443) tcp dport { http, https } accept } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }
レート制限 IPv4/IPv6 ファイアウォール
firewall.2.rules
table inet filter { chain input { type filter hook input priority 0; policy drop; # no ping floods: ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 10/second accept ip protocol icmp icmp type echo-request limit rate 10/second accept ct state established,related accept ct state invalid drop iif lo accept # avoid brute force on ssh: tcp dport ssh limit rate 15/minute accept } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; } }
ジャンプ
設定ファイルでジャンプを使うときは、先にターゲットチェインを定義する必要があります。そうしないと 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 } }
インターフェイスによってルールを変える
複数のネットワークインターフェイスが存在する場合、それぞれのインターフェイスごとに別々のフィルターチェインを設定したい場合があるかもしれません。例えば、ホームルーターを構築するとき、LAN 上でアクセスできるウェブサーバーを実行しつつ (nsp3s0
インターフェイス)、インターネットからはアクセスできないようにしたい場合 (enp2s0
インターフェイス) などは以下のように設定します:
table inet filter { chain input { # this chain serves as a dispatcher type filter hook input priority 0; iif lo accept # always accept loopback iifname enp2s0 jump input_enp2s0 iifname enp3s0 jump input_enp3s0 reject with icmp type port-unreachable # refuse traffic from all other interfaces } chain input_enp2s0 { # rules applicable to public interface interface ct state {established,related} accept ct state invalid drop udp dport bootpc accept tcp dport bootpc accept reject with icmp type port-unreachable # all other traffic } chain input_enp3s0 { ct state {established,related} accept ct state invalid drop udp dport bootpc accept tcp dport bootpc accept tcp port http accept tcp port https accept reject with icmp type port-unreachable # all other traffic } chain ouput { # we let everything out type filter hook output priority 0; accept } }
もしくは iifname
ステートメントを特定のインターフェイスで使用して、他のインターフェイスについてはデフォルトルールを設定するという方法もあります。
マスカレード
nftables には特殊なキーワード masquerade
が存在し、送信元アドレスが自動的に出力インターフェイスのアドレスに設定されます (ソース)。ルーターのインターフェイスが多数の ISP に接続されているときなど、インターフェイスの IP アドレスが一定でない場合に有用です。通常は、インターフェイスの IP アドレスが変わるたびにネットワークアドレス変換 (NAT) のルールを更新する必要があります。
masquerade
を使用するには:
- カーネルコンフィグで以下のマスカレード設定が有効になっている必要があります。
CONFIG_NFT_MASQ=m
masquerade
キーワードはnat
タイプのチェインでのみ使うことができ、inet
ファミリーのテーブルでは利用できません。ip
ファミリーやip6
ファミリーのテーブルを使ってください。- マスカレードは一種のソース NAT であり、出力パスでのみ機能します。
2つのインターフェイスが存在し nsp3s0
が LAN に接続され、enp2s0
がインターネットに接続されているマシンでの設定例:
table ip nat { chain prerouting { type nat hook prerouting priority 0; } chain postrouting { type nat hook postrouting priority 0; oifname "enp0s2" masquerade } }
ヒントとテクニック
シンプルなステートフルファイアウォール
シンプルなステートフルファイアウォールの記事も参照してください。
シングルマシン
現在のルールセットを消去:
# nft flush ruleset
テーブルを追加:
# nft add table inet filter
input, forward, output ベースチェインを追加。input と forward のポリシーは破棄にして、output のポリシーは許可にする:
# nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; } # nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; } # nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
レギュラーチェインを追加して tcp と udp に関連付ける:
# nft add chain inet filter TCP # nft add chain inet filter UDP
関連・確立済みトラフィックは許可する:
# nft add rule inet filter input ct state related,established accept
ループバックインターフェイスのトラフィックは全て許可する:
# nft add rule inet filter input iif lo accept
不正なトラフィックは全て破棄する:
# nft add rule inet filter input ct state invalid drop
新しいエコー要求 (ping) は許可する:
# nft add rule inet filter input ip protocol icmp icmp type echo-request ct state new accept
新しい udp トラフィックは UDP チェインにジャンプする:
# nft add rule inet filter input ip protocol udp ct state new jump UDP
新しい tcp トラフィックは TCP チェインにジャンプする:
# nft add rule inet filter input ip protocol tcp tcp flags \& \(fin\|syn\|rst\|ack\) == syn ct state new jump TCP
他のルールによって処理されなかったトラフィックは全て拒否する:
# nft add rule inet filter input ip protocol udp reject # nft add rule inet filter input ip protocol tcp reject with tcp reset # nft add rule inet filter input counter reject with icmp type prot-unreachable
ここから TCP と UDP チェインで処理する接続で開きたいポートを決めます。例えばウェブサーバーの接続を開くには:
# nft add rule inet filter TCP tcp dport 80 accept
ポート 443 からのウェブサーバーの HTTPS 接続を許可するには:
# nft add rule inet filter TCP tcp dport 443 accept
ポート 22 の SSH 接続を許可するには:
# nft add rule inet filter TCP tcp dport 22 accept
DNS リクエストを許可するには:
# nft add rule inet filter TCP tcp dport 53 accept # nft add rule inet filter UDP tcp dport 53 accept
設定に満足したら変更を保存して永続化させてください。
ブルートフォース攻撃の対策
Sshguard はブルートフォース攻撃を検出して一時的に IP アドレスに基づきブロックするようにファイアウォールを編集します。Sshguard で nftables を使うように設定する方法は Sshguard#nftables を見てください。
トラブルシューティング
Docker と共に使う
nftables を使用すると、Docker のネットワーク (おそらく他のコンテナランタイムも同様) に干渉する可能性があります。 iptables ルールにパッチを適用して定義されたサービス開始順序を確保するか、docker の使用が非常に制限される dockerのiptablesの管理を完全に無効にするなど、さまざまな回避策がインターネット上で見つかります。 (ポートフォワーディングや docker-compose を考えてください)
信頼できる方法は、docker を別のネットワーク名前空間で実行させ、そこで任意の処理を実行できるようにすることです。 Docker が nftables と iptables ルールを混在させないように、iptables-nft を使用しない方が良いでしょう。
以下の docker サービス ドロップインファイル を使用してください:
/etc/systemd/system/docker.service.d/netns.conf
[Service] PrivateNetwork=yes # cleanup ExecStartPre=-nsenter -t 1 -n -- ip link delete docker0 # add veth ExecStartPre=nsenter -t 1 -n -- ip link add docker0 type veth peer name docker0_ns ExecStartPre=sh -c 'nsenter -t 1 -n -- ip link set docker0_ns netns "$$BASHPID" && true' ExecStartPre=ip link set docker0_ns name eth0 # bring host online ExecStartPre=nsenter -t 1 -n -- ip addr add 10.0.0.1/24 dev docker0 ExecStartPre=nsenter -t 1 -n -- ip link set docker0 up # bring ns online ExecStartPre=ip addr add 10.0.0.100/24 dev eth0 ExecStartPre=ip link set eth0 up ExecStartPre=ip route add default via 10.0.0.1 dev eth0
セットアップにおいてIPアドレス 10.0.0.*
が適切でない場合は、調整してください。
以下のポストルーティングルールで、docker0
のIPフォワーディングを有効にし、NATを設定します:
iifname docker0 oifname eth0 masquerade
次に、kernel IP forwarding が有効になっていることを確認します。
これで、nftables を使用して docker0
インターフェイスのファイアウォールとポートフォワーディングを干渉することなくセットアップできるようになります。