14.6. nftables の使用
nftables
フレームワークはパケットを分類し、iptables
、ip6tables
、arptables
、ebtables
、および ipset
ユーティリティーの後継です。利便性、機能、パフォーマンスにおいて、以前のパケットフィルタリングツールに多くの改良が追加されました。以下に例を示します。
- 線形処理の代わりに組み込みルックアップテーブルを使用
-
IPv4
プロトコルおよびIPv6
プロトコルに対する 1 つのフレームワーク - 完全ルールセットのフェッチ、更新、および保存を行わず、すべてアトミックに適用されるルール
-
ルールセットにおけるデバッグおよびトレースへの対応 (
nftrace
) およびトレースイベントの監視 (nft
ツール) - より統一されたコンパクトな構文、プロトコル固有の拡張なし
- サードパーティーのアプリケーション用 Netlink API
nftables
フレームワークは、テーブルを使用してチェーンを保存します。このチェーンには、アクションを実行する個々のルールが含まれます。nft
ユーティリティーは、以前のパケットフィルタリングフレームワークのツールをすべて置き換えます。libmnl
ライブラリーを介して、nftables
Netlink API との低レベルの対話に libnftnl
ライブラリーを使用できます。
ルールセット変更が適用されていることを表示するには、nft list ruleset
コマンドを使用します。これらのユーティリティーはテーブル、チェーン、ルール、セット、およびその他のオブジェクトを nftables
ルールセットに追加するため、nft flush ruleset
コマンドなどの nftables
ルールセット操作は、iptables
コマンドを使用してインストールされたルールセットに影響を与える可能性があることに注意してください。
14.6.1. nftables テーブル、チェーン、およびルールの作成および管理
nftables
ルールセットを表示して管理できます。
14.6.1.1. nftables テーブルの基本
nftables
のテーブルは、チェーン、ルール、セットなどのオブジェクトを含む名前空間です。
各テーブルにはアドレスファミリーが割り当てられている必要があります。アドレスファミリーは、このテーブルが処理するパケットタイプを定義します。テーブルを作成する際に、以下のいずれかのアドレスファミリーを設定できます。
-
ip
:IPv4 パケットだけに一致します。アドレスファミリーを指定しないと、これがデフォルトになります。 -
ip6
:IPv6 パケットだけに一致します。 -
inet
:IPv4 パケットと IPv6 パケットの両方に一致します。 -
arp
:IPv4 アドレス解決プロトコル (ARP) パケットに一致します。 -
bridge
:ブリッジデバイスを通過するパケットに一致します。 -
netdev
:ingress からのパケットに一致します。
テーブルを追加する場合、使用する形式はファイアウォールスクリプトにより異なります。
ネイティブ構文のスクリプトでは、以下を使用します。
table <table_address_family> <table_name> { }
シェルスクリプトで、以下を使用します。
nft add table <table_address_family> <table_name>
14.6.1.2. nftables チェーンの基本
テーブルは、ルールのコンテナーであるチェーンで構成されます。次の 2 つのルールタイプが存在します。
- ベースチェーン:ネットワークスタックからのパケットのエントリーポイントとしてベースチェーンを使用できます。
-
通常のチェーン:
jump
ターゲットとして通常のチェーンを使用し、ルールをより適切に整理できます。
ベースチェーンをテーブルに追加する場合に使用する形式は、ファイアウォールスクリプトにより異なります。
ネイティブ構文のスクリプトでは、以下を使用します。
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> policy <policy> ; } }
シェルスクリプトで、以下を使用します。
nft add chain <table_address_family> <table_name> <chain_name> { type <type> hook <hook> priority <priority> \; policy <policy> \; }
シェルがセミコロンをコマンドの最後として解釈しないようにするには、セミコロンの前にエスケープ文字
\
を配置します。
どちらの例でも、ベースチェーン を作成します。通常のチェーン を作成する場合、中括弧内にパラメーターを設定しないでください。
チェーンタイプ
チェーンタイプとそれらを使用できるアドレスファミリーとフックの概要を以下に示します。
型 | アドレスファミリー | フック | 説明 |
---|---|---|---|
| all | all | 標準のチェーンタイプ |
|
|
| このタイプのチェーンは、接続追跡エントリーに基づいてネイティブアドレス変換を実行します。最初のパケットのみがこのチェーンタイプをトラバースします。 |
|
|
| このチェーンタイプを通過する許可済みパケットは、IP ヘッダーの関連部分が変更された場合に、新しいルートルックアップを引き起こします。 |
チェーンの優先度
priority パラメーターは、パケットが同じフック値を持つチェーンを通過する順序を指定します。このパラメーターは、整数値に設定することも、標準の priority 名を使用することもできます。
以下のマトリックスは、標準的な priority 名とその数値の概要、それらを使用できるファミリーおよびフックの概要です。
テキストの値 | 数値 | アドレスファミリー | フック |
---|---|---|---|
|
|
| all |
|
|
| all |
|
|
|
|
|
|
| |
|
|
| all |
|
| all | |
|
|
| all |
|
|
|
|
|
|
| |
|
|
|
|
チェーンポリシー
チェーンポリシーは、このチェーンのルールでアクションが指定されていない場合に、nftables
がパケットを受け入れるかドロップするかを定義します。チェーンには、以下のいずれかのポリシーを設定できます。
-
accept
(デフォルト) -
drop
14.6.1.3. nftables ルールの基本
ルールは、このルールを含むチェーンを渡すパケットに対して実行するアクションを定義します。ルールに一致する式も含まれる場合、nftables
は、以前の式がすべて適用されている場合にのみアクションを実行します。
チェーンにルールを追加する場合、使用する形式はファイアウォールスクリプトにより異なります。
ネイティブ構文のスクリプトでは、以下を使用します。
table <table_address_family> <table_name> { chain <chain_name> { type <type> hook <hook> priority <priority> ; policy <policy> ; <rule> } }
シェルスクリプトで、以下を使用します。
nft add rule <table_address_family> <table_name> <chain_name> <rule>
このシェルコマンドは、チェーンの最後に新しいルールを追加します。チェーンの先頭にルールを追加する場合は、
nft add
の代わりにnft insert
コマンドを使用します。
14.6.1.4. nft コマンドを使用したテーブル、チェーン、ルールの管理
コマンドラインまたはシェルスクリプトで nftables
ファイアウォールを管理するには、nft
ユーティリティーを使用します。
この手順のコマンドは通常のワークフローを表しておらず、最適化されていません。この手順では、nft
コマンドを使用して、一般的なテーブル、チェーン、およびルールを管理する方法を説明します。
手順
テーブルが IPv4 パケットと IPv6 パケットの両方を処理できるように、
inet
アドレスファミリーを使用してnftables_svc
という名前のテーブルを作成します。# nft add table inet nftables_svc
受信ネットワークトラフィックを処理する
INPUT
という名前のベースチェーンをinet nftables_svc
テーブルに追加します。# nft add chain inet nftables_svc INPUT { type filter hook input priority filter \; policy accept \; }
シェルがセミコロンをコマンドの最後として解釈しないようにするには、
\
文字を使用してセミコロンをエスケープします。INPUT
チェーンにルールを追加します。たとえば、INPUT
チェーンの最後のルールとして、ポート 22 および 443 で着信 TCP トラフィックを許可し、他の着信トラフィックを、Internet Control Message Protocol (ICMP) ポートに到達できないというメッセージで拒否します。# nft add rule inet nftables_svc INPUT tcp dport 22 accept # nft add rule inet nftables_svc INPUT tcp dport 443 accept # nft add rule inet nftables_svc INPUT reject with icmpx type port-unreachable
ここで示されたように
nft add rule
コマンドを実行すると、nft
はコマンド実行と同じ順序でルールをチェーンに追加します。ハンドルを含む現在のルールセットを表示します。
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 443 accept # handle 3 reject # handle 4 } }
ハンドル 3 で既存ルールの前にルールを挿入します。たとえば、ポート 636 で TCP トラフィックを許可するルールを挿入するには、以下を入力します。
# nft insert rule inet nftables_svc INPUT position 3 tcp dport 636 accept
ハンドル 3 で、既存ルールの後ろにルールを追加します。たとえば、ポート 80 で TCP トラフィックを許可するルールを追加するには、以下を入力します。
# nft add rule inet nftables_svc INPUT position 3 tcp dport 80 accept
ハンドルでルールセットを再表示します。後で追加したルールが指定の位置に追加されていることを確認します。
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 636 accept # handle 5 tcp dport 443 accept # handle 3 tcp dport 80 accept # handle 6 reject # handle 4 } }
ハンドル 6 でルールを削除します。
# nft delete rule inet nftables_svc INPUT handle 6
ルールを削除するには、ハンドルを指定する必要があります。
ルールセットを表示し、削除されたルールがもう存在しないことを確認します。
# nft -a list table inet nftables_svc table inet nftables_svc { # handle 13 chain INPUT { # handle 1 type filter hook input priority filter; policy accept; tcp dport 22 accept # handle 2 tcp dport 636 accept # handle 5 tcp dport 443 accept # handle 3 reject # handle 4 } }
INPUT
チェーンから残りのルールをすべて削除します。# nft flush chain inet nftables_svc INPUT
ルールセットを表示し、
INPUT
チェーンが空であることを確認します。# nft list table inet nftables_svc table inet nftables_svc { chain INPUT { type filter hook input priority filter; policy accept } }
INPUT
チェーンを削除します。# nft delete chain inet nftables_svc INPUT
このコマンドを使用して、まだルールが含まれているチェーンを削除することもできます。
ルールセットを表示し、
INPUT
チェーンが削除されたことを確認します。# nft list table inet nftables_svc table inet nftables_svc { }
nftables_svc
テーブルを削除します。# nft delete table inet nftables_svc
このコマンドを使用して、まだルールが含まれているテーブルを削除することもできます。
注記ルールセット全体を削除するには、個別のコマンドですべてのルール、チェーン、およびテーブルを手動で削除するのではなく、
nft flush ruleset
コマンドを使用します。
関連情報
システム上の nft(8)
man ページ
14.6.2. iptables から nftables への移行
ファイアウォール設定が依然として iptables
ルールを使用している場合は、iptables
ルールを nftables
に移行できます。
14.6.2.1. firewalld、nftables、または iptables を使用する場合
以下は、次のユーティリティーのいずれかを使用する必要があるシナリオの概要です。
-
firewalld
:簡単なファイアウォールのユースケースには、firewalld
ユーティリティーを使用します。このユーティリティーは、使いやすく、このようなシナリオの一般的な使用例に対応しています。 -
nftables
:nftables
ユーティリティーを使用して、ネットワーク全体など、複雑なパフォーマンスに関する重要なファイアウォールを設定します。 -
iptables
:Red Hat Enterprise Linux のiptables
ユーティリティーは、legacy
バックエンドの代わりにnf_tables
カーネル API を使用します。nf_tables
API は、iptables
コマンドを使用するスクリプトが、Red Hat Enterprise Linux で引き続き動作するように、後方互換性を提供します。新しいファイアウォールスクリプトの場合には、Red Hat はnftables
を使用することを推奨します。
さまざまなファイアウォール関連サービス (firewalld
、nftables
、または iptables
) が相互に影響を与えないようにするには、RHEL ホストでそのうち 1 つだけを実行し、他のサービスを無効にします。
14.6.2.2. nftables フレームワークの概念
iptables
フレームワークと比較すると、nftables
はより最新で効率的かつ柔軟な代替手段を提供します。iptables
よりも高度な機能と改善を提供する概念と機能がいくつかあります。これらの機能強化により、ルール管理が簡素化され、パフォーマンスが向上し、nftables
は複雑で高性能なネットワーク環境の最新の代替手段になります。
nftables
フレームワークには次のコンポーネントが含まれています。
- テーブルと名前空間
-
nftables
では、テーブルは、関連するファイアウォールチェーン、セット、フローテーブル、およびその他のオブジェクトをグループ化する組織単位または名前空間を表します。nftables
では、テーブルによってファイアウォールルールと関連コンポーネントをより柔軟に構造化できます。一方、iptables
では、テーブルは特定の目的に合わせてより厳密に定義されていました。 - テーブルファミリー
-
nftables
内の各テーブルは、特定のファミリー (ip
、ip6
、inet
、arp
、bridge
、またはnetdev
) に関連付けられています。この関連付けによって、テーブルが処理できるパケットが決まります。たとえば、ip
ファミリーのテーブルは IPv4 パケットのみを処理します。一方、inet
はテーブルファミリーの特殊なケースです。IPv4 パケットと IPv6 パケットの両方を処理できるため、プロトコル全体で統一されたアプローチを提供します。特殊なテーブルファミリーのもう 1 つの例はnetdev
です。これは、ネットワークデバイスに直接適用されるルールに使用され、デバイスレベルでのフィルタリングを可能にするためです。 - ベースチェーン
nftables
のベースチェーンは、パケット処理パイプライン内の高度に設定可能なエントリーポイントであり、ユーザーは次の内容を指定できます。- チェーンのタイプ (例: フィルター)
- パケット処理パスのフックポイント (例: 入力、出力、転送)
- チェーンの優先順位
この柔軟性により、パケットがネットワークスタックを通過するときにルールが適用されるタイミングと方法を正確に制御できます。チェーンの特殊なケースは
ルート
チェーンであり、パケットヘッダーに基づいてカーネルによって行われるルーティングの決定に影響を与えるために使用されます。- ルール処理用の仮想マシン
-
nftables
フレームワークは、ルールを処理するために内部仮想マシンを使用します。この仮想マシンは、アセンブリ言語の操作 (レジスターへのデータのロード、比較の実行など) に似た命令を実行します。このようなメカニズムにより、非常に柔軟かつ効率的なルール処理が可能になります。
nftables
の機能強化は、その仮想マシンの新しい命令として導入できます。これには通常、新しいカーネルモジュールと、libnftnl
ライブラリーおよび nft
コマンドラインユーティリティーの更新が必要です。
または、カーネルを変更することなく、既存の命令を革新的な方法で組み合わせることで、新しい機能を導入することもできます。nftables
ルールの構文は、基盤となる仮想マシンの柔軟性を反映しています。たとえば、ルールメタマークセット tcp dport マップ{22: 1, 80:2 }
TCP 宛先ポートが 22 の場合はパケットのファイアウォールマークを 1 に設定し、ポートが 80 の場合は 2 に設定します。これは、複雑なロジックを簡潔に表現できることを示しています。
- 学んだ教訓と改善点
-
nftables
フレームワークは、iptables
で IP アドレス、ポート、その他のデータタイプ、そして最も重要なそれらの組み合わせの一括マッチングに使用されるipset
ユーティリティーの機能を統合および拡張します。この統合により、大規模で動的なデータセットをnftables
内で直接管理することが容易になります。次に、nftables は、
任意のデータタイプに対して複数の値または範囲に基づいてパケットを照合することをネイティブにサポートしているため、複雑なフィルタリング要件を処理する機能が強化されます。nftables を
使用すると、パケット内の任意のフィールドを操作できます。
nftables
では、セットは名前付きまたは匿名のいずれかになります。名前付きセットは複数のルールによって参照され、動的に変更することができます。匿名セットはルール内でインラインで定義され、不変です。セットには、IP アドレスとポート番号のペアなど、異なるタイプの組み合わせである要素を含めることができます。この機能により、複雑な条件の一致における柔軟性が向上します。セットを管理するために、カーネルは特定の要件 (パフォーマンス、メモリー効率など) に基づいて最も適切なバックエンドを選択できます。セットは、キーと値のペアを持つマップとしても機能できます。値の部分は、データポイント (パケットヘッダーに書き込む値) として、または判定やジャンプ先のチェーンとして使用できます。これにより、判定マップと呼ばれる複雑で動的なルール動作が可能になります。
- 柔軟なルール形式
-
nftables
ルールの構造は簡単です。条件とアクションは左から右に順に適用されます。この直感的な形式により、ルールの作成とトラブルシューティングが簡素化されます。
ルール内の条件は論理的に (ANDOperator を使用して) 結合されており、ルールが一致するにはすべての条件が true と評価される必要があります。いずれかの条件が失敗した場合、評価は次のルールに進みます。
nftables
内のアクションは、drop
や accept
など、パケットに対するそれ以上のルール処理を停止する最終的なものになることがあります。counter log meta mark set 0x3
などの非ターミナルアクションは、特定のタスク (パケットのカウント、ログ記録、マークの設定など) を実行しますが、後続のルールを評価できます。
関連情報
14.6.2.3. 廃止された iptables フレームワークの概念
積極的にメンテナンスされている nftables
フレームワークと同様に、非推奨の iptables
フレームワークを使用すると、さまざまなパケットフィルタリングタスク、ログ記録と監査、NAT 関連の設定タスクなどを実行できます。
iptables
フレームワークは複数のテーブルに構造化されており、各テーブルは特定の目的のために設計されています。
filter
- デフォルトのテーブルは、一般的なパケットフィルタリングを保証します
nat
- ネットワークアドレス変換 (NAT) の場合、パケットの送信元アドレスと宛先アドレスの変更が含まれます。
mangle
- 特定のパケット変更では、高度なルーティング決定のためにパケットヘッダーの変更を行うことができます。
raw
- 接続追跡の前に必要な設定
これらのテーブルは個別のカーネルモジュールとして実装されており、各テーブルは INPUT
、OUTPUT
、FORWARD
などの組み込みチェーンの固定セットを提供します。チェーンは、パケットが評価される一連のルールです。これらのチェーンは、カーネル内のパケット処理フローの特定のポイントにフックします。チェーンは異なるテーブル間で同じ名前を持ちますが、実行順序はそれぞれのフックの優先順位によって決まります。ルールが正しい順序で適用されるように、優先順位はカーネルによって内部的に管理されます。
もともと、iptables は
IPv4 トラフィックを処理するために設計されました。しかし、IPv6 プロトコルの開始に伴い、iptables
と同等の機能を提供し、ユーザーが IPv6 パケットのファイアウォールルールを作成および管理できるようにするために、ip6tables
ユーティリティーを導入する必要がありました。同じロジックで、Address Resolution Protocol (ARP) を処理するために arptables
ユーティリティーが作成され、イーサネットブリッジフレームを処理するために ebtables
ユーティリティーが開発されました。これらのツールを使用すると、さまざまなネットワークプロトコルにわたって iptables
のパケットフィルタリング機能を適用し、包括的なネットワークカバレッジを提供できるようになります。
iptables
の機能を強化するために、拡張機能の開発が開始されました。機能拡張は通常、ユーザー空間の動的共有オブジェクト (DSO) とペアになったカーネルモジュールとして実装されます。拡張機能により、ファイアウォールルールで使用してより高度な操作を実行できる一致とターゲットが導入されます。拡張機能により、複雑な一致とターゲットが可能になります。たとえば、特定のレイヤー 4 プロトコルヘッダー値を一致させたり操作したり、レート制限を実行したり、クォータを適用したりすることができます。一部の拡張機能は、デフォルトの iptables
構文の制限に対処するように設計されています (例: マルチポート一致拡張機能)。この拡張機能により、単一のルールを複数の非連続ポートに一致させることができるため、ルール定義が簡素化され、必要な個別のルールの数を減らすことができます。
ipset は
、iptables
に対する特別な種類の機能拡張です。これはカーネルレベルのデータ構造であり、iptables
と一緒に使用して、パケットと照合できる IP アドレス、ポート番号、その他のネットワーク関連要素のコレクションを作成します。これらのセットにより、ファイアウォールルールの作成と管理のプロセスが大幅に合理化、最適化、高速化されます。
関連情報
-
iptables (8)
man ページ
14.6.2.4. iptables および ip6tables ルールセットの nftables への変換
iptables-restore-translate
ユーティリティーおよび ip6tables-restore-translate
ユーティリティーを使用して、iptables
および ip6tables
ルールセットを nftables
に変換します。
前提条件
-
nftables
パッケージおよびiptables
パッケージがインストールされている。 -
システムに
iptables
ルールおよびip6tables
ルールが設定されている。
手順
iptables
ルールおよびip6tables
ルールをファイルに書き込みます。# iptables-save >/root/iptables.dump # ip6tables-save >/root/ip6tables.dump
ダンプファイルを
nftables
命令に変換します。# iptables-restore-translate -f /root/iptables.dump > /etc/nftables/ruleset-migrated-from-iptables.nft # ip6tables-restore-translate -f /root/ip6tables.dump > /etc/nftables/ruleset-migrated-from-ip6tables.nft
-
必要に応じて、生成された
nftables
ルールを手動で更新して、確認します。 nftables
サービスが生成されたファイルをロードできるようにするには、以下を/etc/sysconfig/nftables.conf
ファイルに追加します。include "/etc/nftables/ruleset-migrated-from-iptables.nft" include "/etc/nftables/ruleset-migrated-from-ip6tables.nft"
iptables
サービスを停止し、無効にします。# systemctl disable --now iptables
カスタムスクリプトを使用して
iptables
ルールを読み込んだ場合は、スクリプトが自動的に開始されなくなったことを確認し、再起動してすべてのテーブルをフラッシュします。nftables
サービスを有効にして起動します。# systemctl enable --now nftables
検証
nftables
ルールセットを表示します。# nft list ruleset
14.6.2.5. 単一の iptables および ip6tables ルールセットの nftables への変換
Red Hat Enterprise Linux は、iptables
ルールまたは ip6tables
ルールを、nftables
で同等のルールに変換する iptables-translate
ユーティリティーおよび ip6tables-translate
ユーティリティーを提供します。
前提条件
-
nftables
パッケージがインストールされている。
手順
以下のように、
iptables
またはip6tables
の代わりにiptables-translate
ユーティリティーまたはip6tables-translate
ユーティリティーを使用して、対応するnftables
ルールを表示します。# iptables-translate -A INPUT -s 192.0.2.0/24 -j ACCEPT nft add rule ip filter INPUT ip saddr 192.0.2.0/24 counter accept
拡張機能によっては変換機能がない場合もあります。このような場合には、ユーティリティーは、以下のように、前に
#
記号が付いた未変換ルールを出力します。# iptables-translate -A INPUT -j CHECKSUM --checksum-fill nft # -A INPUT -j CHECKSUM --checksum-fill
関連情報
-
iptables-translate --help
14.6.2.6. 一般的な iptables コマンドと nftables コマンドの比較
以下は、一般的な iptables
コマンドと nftables
コマンドの比較です。
すべてのルールをリスト表示します。
iptables nftables iptables-save
nft list ruleset
特定のテーブルおよびチェーンをリスト表示します。
iptables nftables iptables -L
nft list table ip filter
iptables -L INPUT
nft list chain ip filter INPUT
iptables -t nat -L PREROUTING
nft list chain ip nat PREROUTING
nft
コマンドは、テーブルおよびチェーンを事前に作成しません。これらは、ユーザーが手動で作成した場合にのみ存在します。firewalld によって生成されたルールの一覧表示:
# nft list table inet firewalld # nft list table ip firewalld # nft list table ip6 firewalld
14.6.3. nftables スクリプトの作成および実行
nftables
フレームワークを使用する主な利点は、スクリプトの実行がアトミックであることです。つまり、システムがスクリプト全体を適用するか、エラーが発生した場合には実行を阻止することを意味します。これにより、ファイアウォールは常に一貫した状態になります。
さらに、nftables
スクリプト環境を使用すると、次のことができます。
- コメントの追加
- 変数の定義
- 他のルールセットファイルの組み込み
nftables
パッケージをインストールすると、Red Hat Enterprise Linux が自動的に *.nft
スクリプトを /etc/nftables/
ディレクトリーに作成します。このスクリプトには、さまざまな目的でテーブルと空のチェーンを作成するコマンドが含まれます。
14.6.3.1. 対応している nftables スクリプトの形式
nftables
スクリプト環境では、次の形式でスクリプトを記述できます。
nft list ruleset
コマンドと同じ形式でルールセットが表示されます。#!/usr/sbin/nft -f # Flush the rule set flush ruleset table inet example_table { chain example_chain { # Chain for incoming packets that drops all packets that # are not explicitly allowed by any rule in this chain type filter hook input priority 0; policy drop; # Accept connections to port 22 (ssh) tcp dport ssh accept } }
nft
コマンドと同じ構文:#!/usr/sbin/nft -f # Flush the rule set flush ruleset # Create a table add table inet example_table # Create a chain for incoming packets that drops all packets # that are not explicitly allowed by any rule in this chain add chain inet example_table example_chain { type filter hook input priority 0 ; policy drop ; } # Add a rule that accepts connections to port 22 (ssh) add rule inet example_table example_chain tcp dport ssh accept
14.6.3.2. nftables スクリプトの実行
nftables
スクリプトは、nft
ユーティリティーに渡すか、スクリプトを直接実行することで実行できます。
手順
nftables
スクリプトをnft
ユーティリティーに渡して実行するには、次のコマンドを実行します。# nft -f /etc/nftables/<example_firewall_script>.nft
nftables
スクリプトを直接実行するには、次のコマンドを実行します。1 回だけ実行する場合:
スクリプトが以下のシバンシーケンスで始まることを確認します。
#!/usr/sbin/nft -f
重要-f
パラメーターを省略すると、nft
ユーティリティーはスクリプトを読み込まず、Error: syntax error, unexpected newline, expecting string
のように表示されます。オプション: スクリプトの所有者を
root
に設定します。# chown root /etc/nftables/<example_firewall_script>.nft
所有者のスクリプトを実行ファイルに変更します。
# chmod u+x /etc/nftables/<example_firewall_script>.nft
スクリプトを実行します。
# /etc/nftables/<example_firewall_script>.nft
出力が表示されない場合は、システムがスクリプトを正常に実行します。
nft
はスクリプトを正常に実行しますが、ルールの配置やパラメーター不足、またはスクリプト内のその他の問題により、ファイアウォールが期待通りの動作を起こさない可能性があります。
関連情報
-
システム上の
chown (1)
およびchmod (1) の
man ページ - システムの起動時に nftables ルールの自動読み込み
14.6.3.3. nftables スクリプトでコメントの使用
nftables
スクリプト環境は、#
文字の右側から行末までのすべてをコメントとして解釈します。
コメントは、行の先頭またはコマンドの横から開始できます。
... # Flush the rule set flush ruleset add table inet example_table # Create a table ...
14.6.3.4. nftables スクリプトでの変数の使用
nftables
スクリプトで変数を定義するには、define
キーワードを使用します。シングル値および匿名セットを変数に保存できます。より複雑なシナリオの場合は、セットまたは決定マップを使用します。
- 値を 1 つ持つ変数
以下の例は、値が
enp1s0
のINET_DEV
という名前の変数を定義します。define INET_DEV = enp1s0
スクリプトで変数を使用するには、
$
記号と、それに続く変数名を指定します。... add rule inet example_table example_chain iifname $INET_DEV tcp dport ssh accept ...
- 匿名セットを含む変数
以下の例では、匿名セットを含む変数を定義します。
define DNS_SERVERS = { 192.0.2.1, 192.0.2.2 }
スクリプトで変数を使用するには、
$
記号と、それに続く変数名を指定します。add rule inet example_table example_chain ip daddr $DNS_SERVERS accept
注記中括弧は、変数がセットを表していることを示すため、ルールで使用する場合は、特別なセマンティクスを持ちます。
14.6.3.5. nftables スクリプトへのファイルの追加
nftables
スクリプト環境では、include
ステートメントを使用して他のスクリプトを含めることができます。
絶対パスまたは相対パスのないファイル名のみを指定すると、nftables
には、デフォルトの検索パスのファイルが含まれます。これは、Red Hat Enterprise Linux では /etc
に設定されています。
例14.1 デフォルト検索ディレクトリーからのファイルを含む
デフォルトの検索ディレクトリーからファイルを指定するには、次のコマンドを実行します。
include "example.nft"
例14.2 ディレクトリーの *.nft ファイルをすべて含む
*.nft
で終わるすべてのファイルを /etc/nftables/rulesets/
ディレクトリーに保存するには、次のコマンドを実行します。
include "/etc/nftables/rulesets/*.nft"
include
ステートメントは、ドットで始まるファイルに一致しないことに注意してください。
関連情報
-
システムの
nft (8)
man ページのインクルードファイル
セクション
14.6.3.6. システムの起動時に nftables ルールの自動読み込み
systemd サービス nftables
は、/etc/sysconfig/nftables.conf
ファイルに含まれるファイアウォールスクリプトを読み込みます。
前提条件
-
nftables
スクリプトは、/etc/nftables/
ディレクトリーに保存されます。
手順
/etc/sysconfig/nftables.conf
ファイルを編集します。-
nftables
パッケージのインストールで/etc/nftables/
に作成された*.nft
スクリプトを変更した場合は、これらのスクリプトのinclude
ステートメントのコメントを解除します。 新しいスクリプトを作成した場合は、
include
ステートメントを追加してこれらのスクリプトを含めます。たとえば、nftables
サービスの起動時に/etc/nftables/example.nft
スクリプトを読み込むには、以下を追加します。include "/etc/nftables/_example_.nft"
-
オプション:
nftables
サービスを開始して、システムを再起動せずにファイアウォールルールを読み込みます。# systemctl start nftables
nftables
サービスを有効にします。# systemctl enable nftables
14.6.4. nftables を使用した NAT の設定
nftables
を使用すると、以下のネットワークアドレス変換 (NAT) タイプを設定できます。
- マスカレーディング
- ソース NAT (SNAT)
- 宛先 NAT (DNAT)
- リダイレクト
iifname
パラメーターおよび oifname
パラメーターでは実インターフェイス名のみを使用でき、代替名 (altname
) には対応していません。
14.6.4.1. NAT タイプ
以下は、ネットワークアドレス変換 (NAT) タイプになります。
- マスカレードおよびソースの NAT (SNAT)
この NAT タイプのいずれかを使用して、パケットのソース IP アドレスを変更します。たとえば、インターネットサービスプロバイダー (ISP) は、プライベート IP 範囲 (
10.0.0.0/8
など) をルーティングしません。ネットワークでプライベート IP 範囲を使用し、ユーザーがインターネット上のサーバーにアクセスできるようにする必要がある場合は、この範囲のパケットのソース IP アドレスをパブリック IP アドレスにマップします。マスカレードと SNAT は互いに非常に似ています。相違点は次のとおりです。
- マスカレードは、出力インターフェイスの IP アドレスを自動的に使用します。したがって、出力インターフェイスが動的 IP アドレスを使用する場合は、マスカレードを使用します。
- SNAT は、パケットのソース IP アドレスを指定された IP に設定し、出力インターフェイスの IP アドレスを動的に検索しません。そのため、SNAT の方がマスカレードよりも高速です。出力インターフェイスが固定 IP アドレスを使用する場合は、SNAT を使用します。
- 宛先 NAT (DNAT)
- この NAT タイプを使用して、着信パケットの宛先アドレスとポートを書き換えます。たとえば、Web サーバーがプライベート IP 範囲の IP アドレスを使用しているため、インターネットから直接アクセスできない場合は、ルーターに DNAT ルールを設定し、着信トラフィックをこのサーバーにリダイレクトできます。
- リダイレクト
- このタイプは、チェーンフックに応じてパケットをローカルマシンにリダイレクトする DNAT の特殊なケースです。たとえば、サービスが標準ポートとは異なるポートで実行する場合は、標準ポートからこの特定のポートに着信トラフィックをリダイレクトすることができます。
14.6.4.2. nftables を使用したマスカレードの設定
マスカレードを使用すると、ルーターは、インターフェイスを介して送信されるパケットのソース IP を、インターフェイスの IP アドレスに動的に変更できます。これは、インターフェイスに新しい IP が割り当てられている場合に、nftables
はソース IP の置き換え時に新しい IP を自動的に使用することを意味します。
ens3
インターフェイスを介してホストから出るパケットの送信元 IP を、ens3
で設定された IP に置き換えます。
手順
テーブルを作成します。
# nft add table nat
テーブルに、
prerouting
チェーンおよびpostrouting
チェーンを追加します。# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
重要prerouting
チェーンにルールを追加しなくても、nftables
フレームワークでは、着信パケット返信に一致するようにこのチェーンが必要になります。--
オプションをnft
コマンドに渡して、シェルが負の priority 値をnft
コマンドのオプションとして解釈しないようにする必要があることに注意してください。postrouting
チェーンに、ens3
インターフェイスの出力パケットに一致するルールを追加します。# nft add rule nat postrouting oifname "ens3" masquerade
14.6.4.3. nftables を使用したソース NAT の設定
ルーターでは、ソース NAT (SNAT) を使用して、インターフェイスを介して特定の IP アドレスに送信するパケットの IP を変更できます。次に、ルーターは送信パケットのソース IP を置き換えます。
手順
テーブルを作成します。
# nft add table nat
テーブルに、
prerouting
チェーンおよびpostrouting
チェーンを追加します。# nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
重要postrouting
チェーンにルールを追加しなくても、nftables
フレームワークでは、このチェーンが発信パケット返信に一致するようにする必要があります。--
オプションをnft
コマンドに渡して、シェルが負の priority 値をnft
コマンドのオプションとして解釈しないようにする必要があることに注意してください。ens3
を介した発信パケットのソース IP を192.0.2.1
に置き換えるルールをpostrouting
チェーンに追加します。# nft add rule nat postrouting oifname "ens3" snat to 192.0.2.1
14.6.4.4. nftables を使用した宛先 NAT の設定
宛先 NAT (DNAT) を使用すると、ルーター上のトラフィックを、インターネットから直接アクセスできないホストにリダイレクトできます。
たとえば、DNAT を使用すると、ルーターはポート 80
および 443
に送信された受信トラフィックを、IP アドレス 192.0.2.1
の Web サーバーにリダイレクトします。
手順
テーブルを作成します。
# nft add table nat
テーブルに、
prerouting
チェーンおよびpostrouting
チェーンを追加します。# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; } # nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
重要postrouting
チェーンにルールを追加しなくても、nftables
フレームワークでは、このチェーンが発信パケット返信に一致するようにする必要があります。--
オプションをnft
コマンドに渡して、シェルが負の priority 値をnft
コマンドのオプションとして解釈しないようにする必要があることに注意してください。prerouting
チェーンに、ルーターのens3
インターフェイスのポート80
および443
への受信トラフィックを、IP アドレス192.0.2.1
の Web サーバーにリダイレクトするルールを追加します。# nft add rule nat prerouting iifname ens3 tcp dport { 80, 443 } dnat to 192.0.2.1
環境に応じて、SNAT ルールまたはマスカレードルールを追加して、Web サーバーから返されるパケットのソースアドレスを送信者に変更します。
ens3
インターフェイスが動的 IP アドレスを使用している場合は、マスカレードルールを追加します。# nft add rule nat postrouting oifname "ens3" masquerade
ens3
インターフェイスが静的 IP アドレスを使用する場合は、SNAT ルールを追加します。たとえば、ens3
が IP アドレス198.51.100.1
を使用している場合は、以下のようになります。# nft add rule nat postrouting oifname "ens3" snat to 198.51.100.1
パケット転送を有効にします。
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
関連情報
14.6.4.5. nftables を使用したリダイレクトの設定
redirect
機能は、チェーンフックに応じてパケットをローカルマシンにリダイレクトする宛先ネットワークアドレス変換 (DNAT) の特殊なケースです。
たとえば、ローカルホストのポート 22
に送信された着信および転送されたトラフィックを 2222
ポートにリダイレクトすることができます。
手順
テーブルを作成します。
# nft add table nat
テーブルに
prerouting
チェーンを追加します。# nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }
--
オプションをnft
コマンドに渡して、シェルが負の priority 値をnft
コマンドのオプションとして解釈しないようにする必要があることに注意してください。22
ポートの着信トラフィックを2222
ポートにリダイレクトするルールをprerouting
チェーンに追加します。# nft add rule nat prerouting tcp dport 22 redirect to 2222
関連情報
14.6.4.6. nftables を使用したフローテーブルの設定
nftables
ユーティリティーは、netfilter
フレームワークを使用してネットワークトラフィックにネットワークアドレス変換 (NAT) を提供し、高速パス機能ベースの flowtable
メカニズムを提供してパケット転送を高速化します。
フローテーブルメカニズムには次の機能があります。
- 接続追跡を使用して、従来のパケット転送パスをバイパスします。
- 従来のパケット処理をバイパスすることで、ルーティングテーブルの再参照を回避します。
- TCP および UDP プロトコルでのみ動作します。
- ハードウェアに依存しないソフトウェア高速パスです。
手順
inet
ファミリーのexample-table
テーブルを追加します。# nft add table inet <example-table>
優先度タイプとして
ingress
フックとfilter
を含むexample-flowtable
フローテーブルを追加します。# nft add flowtable inet <example-table> <example-flowtable> { hook ingress priority filter \; devices = { enp1s0, enp7s0 } \; }
example-forwardchain
フローをパケット処理テーブルからフローテーブルに追加します。# nft add chain inet <example-table> <example-forwardchain> { type filter hook forward priority filter \; }
このコマンドは、
forward
フックとfilter
優先度を備えたfilter
タイプのフローテーブルを追加します。established
接続追跡状態を含むルールを追加して、example-flowtable
フローをオフロードします。# nft add rule inet <example-table> <example-forwardchain> ct state established flow add @<example-flowtable>
検証
example-table
のプロパティーを確認します。# nft list table inet <example-table> table inet example-table { flowtable example-flowtable { hook ingress priority filter devices = { enp1s0, enp7s0 } } chain example-forwardchain { type filter hook forward priority filter; policy accept; ct state established flow add @example-flowtable } }
関連情報
-
システム上の
nft(8)
man ページ
14.6.5. nftables コマンドでのセットの使用
nftables
フレームワークは、セットをネイティブに対応します。たとえば、ルールが複数の IP アドレス、ポート番号、インターフェイス、またはその他の一致基準に一致する必要がある場合など、セットを使用できます。
14.6.5.1. nftables での匿名セットの使用
匿名セットには、ルールで直接使用する { 22, 80, 443 }
などの中括弧で囲まれたコンマ区切りの値が含まれます。IP アドレスやその他の一致基準にも匿名セットを使用できます。
匿名セットの欠点は、セットを変更する場合はルールを置き換える必要があることです。動的なソリューションの場合は、nftables で名前付きセットの使用 で説明されているように名前付きセットを使用します。
前提条件
-
inet
ファミリーにexample_chain
チェーンおよびexample_table
テーブルがある。
手順
たとえば、ポート
22
、80
、および443
に着信トラフィックを許可するルールを、example_table
のexample_chain
に追加するには、次のコマンドを実行します。# nft add rule inet example_table example_chain tcp dport { 22, 80, 443 } accept
オプション:
example_table
内のすべてのチェーンとそのルールを表示します。# nft list table inet example_table table inet example_table { chain example_chain { type filter hook input priority filter; policy accept; tcp dport { ssh, http, https } accept } }
14.6.5.2. nftables で名前付きセットの使用
nftables
フレームワークは、変更可能な名前付きセットに対応します。名前付きセットは、テーブル内の複数のルールで使用できる要素のリストまたは範囲です。匿名セットに対する別の利点として、セットを使用するルールを置き換えることなく、名前付きセットを更新できます。
名前付きセットを作成する場合は、セットに含まれる要素のタイプを指定する必要があります。以下のタイプを設定できます。
-
192.0.2.1
や192.0.2.0/24
など、IPv4 アドレスまたは範囲を含むセットの場合はipv4_addr
。 -
2001:db8:1::1
や2001:db8:1::1/64
など、IPv6 アドレスまたは範囲を含むセットの場合はipv6_addr
。 -
52:54:00:6b:66:42
など、メディアアクセス制御 (MAC) アドレスのリストを含むセットの場合はether_addr
。 -
tcp
など、インターネットプロトコルタイプの一覧が含まれるセットの場合はinet_proto
。 -
ssh
など、インターネットサービスの一覧を含むセットの場合はinet_service
。 -
パケットマークの一覧を含むセットの場合は
mark
。パケットマークは、任意の 32 ビットの正の整数値 (0
から2147483647
) にすることができます。
前提条件
-
example_chain
チェーンとexample_table
テーブルが存在する。
手順
空のファイルを作成します。以下の例では、IPv4 アドレスのセットを作成します。
複数の IPv4 アドレスを格納することができるセットを作成するには、次のコマンドを実行します。
# nft add set inet example_table example_set { type ipv4_addr \; }
IPv4 アドレス範囲を保存できるセットを作成するには、次のコマンドを実行します。
# nft add set inet example_table example_set { type ipv4_addr \; flags interval \; }
重要シェルがセミコロンをコマンドの終わりとして解釈しないようにするには、バックスラッシュでセミコロンをエスケープする必要があります。
オプション: セットを使用するルールを作成します。たとえば、次のコマンドは、
example_set
の IPv4 アドレスからのパケットをすべて破棄するルールを、example_table
のexample_chain
に追加します。# nft add rule inet example_table example_chain ip saddr @example_set drop
example_set
が空のままなので、ルールには現在影響がありません。IPv4 アドレスを
example_set
に追加します。個々の IPv4 アドレスを保存するセットを作成する場合は、次のコマンドを実行します。
# nft add element inet example_table example_set { 192.0.2.1, 192.0.2.2 }
IPv4 範囲を保存するセットを作成する場合は、次のコマンドを実行します。
# nft add element inet example_table example_set { 192.0.2.0-192.0.2.255 }
IP アドレス範囲を指定する場合は、上記の例の
192.0.2.0/24
のように、CIDR (Classless Inter-Domain Routing) 表記を使用することもできます。
14.6.5.3. 関連情報
-
システムの
nft (8)
man ページのSets
セクション
14.6.6. nftables コマンドにおける決定マップの使用
ディクショナリーとしても知られている決定マップにより、nft
は一致基準をアクションにマッピングすることで、パケット情報に基づいてアクションを実行できます。
14.6.6.1. nftables での匿名マップの使用
匿名マップは、ルールで直接使用する { match_criteria : action }
ステートメントです。ステートメントには、複数のコンマ区切りマッピングを含めることができます。
匿名マップの欠点は、マップを変更する場合には、ルールを置き換える必要があることです。動的なソリューションの場合は、nftables での名前付きマップの使用 で説明されているように名前付きマップを使用します。
たとえば、匿名マップを使用して、IPv4 プロトコルおよび IPv6 プロトコルの TCP パケットと UDP パケットの両方を異なるチェーンにルーティングし、着信 TCP パケットと UDP パケットを個別にカウントできます。
手順
新しいテーブルを作成します。
# nft add table inet example_table
example_table
にtcp_packets
チェーンを作成します。# nft add chain inet example_table tcp_packets
このチェーンのトラフィックをカウントする
tcp_packets
にルールを追加します。# nft add rule inet example_table tcp_packets counter
example_table
でudp_packets
チェーンを作成します。# nft add chain inet example_table udp_packets
このチェーンのトラフィックをカウントする
udp_packets
にルールを追加します。# nft add rule inet example_table udp_packets counter
着信トラフィックのチェーンを作成します。たとえば、
example_table
に、着信トラフィックをフィルタリングするincoming_traffic
という名前のチェーンを作成するには、次のコマンドを実行します。# nft add chain inet example_table incoming_traffic { type filter hook input priority 0 \; }
匿名マップを持つルールを
incoming_traffic
に追加します。# nft add rule inet example_table incoming_traffic ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets }
匿名マップはパケットを区別し、プロトコルに基づいて別のカウンターチェーンに送信します。
トラフィックカウンターの一覧を表示する場合は、
example_table
を表示します。# nft list table inet example_table table inet example_table { chain tcp_packets { counter packets 36379 bytes 2103816 } chain udp_packets { counter packets 10 bytes 1559 } chain incoming_traffic { type filter hook input priority filter; policy accept; ip protocol vmap { tcp : jump tcp_packets, udp : jump udp_packets } } }
tcp_packets
チェーンおよびudp_packets
チェーンのカウンターは、受信パケットとバイトの両方を表示します。
14.6.6.2. nftables での名前付きマップの使用
nftables
フレームワークは、名前付きマップに対応します。テーブルの複数のルールでこのマップを使用できます。匿名マップに対する別の利点は、名前付きマップを使用するルールを置き換えることなく、名前付きマップを更新できることです。
名前付きマップを作成する場合は、要素のタイプを指定する必要があります。
-
一致する部分に
192.0.2.1
などの IPv4 アドレスが含まれるマップの場合はipv4_addr
。 -
一致する部分に
2001:db8:1::1
などの IPv6 アドレスが含まれるマップの場合はipv6_addr
。 -
52:54:00:6b:66:42
などのメディアアクセス制御 (MAC) アドレスを含むマップの場合はether_addr
。 -
一致する部分に
tcp
などのインターネットプロトコルタイプが含まれるマップの場合はinet_proto
。 -
一致する部分に
ssh
や22
などのインターネットサービス名のポート番号が含まれるマップの場合はinet_service
。 -
一致する部分にパケットマークが含まれるマップの場合は
mark
。パケットマークは、任意の正の 32 ビットの整数値 (0
~2147483647
) にできます。 -
一致する部分にカウンターの値が含まれるマップの場合は
counter
。カウンター値は、正の値の 64 ビットであれば任意の値にすることができます。 -
一致する部分にクォータ値が含まれるマップの場合は
quota
。クォータの値は、64 ビットの整数値にできます。
たとえば、送信元 IP アドレスに基づいて着信パケットを許可または拒否できます。名前付きマップを使用すると、このシナリオを設定するのに必要なルールは 1 つだけで、IP アドレスとアクションがマップに動的に保存されます。
手順
テーブルを作成します。たとえば、IPv4 パケットを処理する
example_table
という名前のテーブルを作成するには、次のコマンドを実行します。# nft add table ip example_table
チェーンを作成します。たとえば、
example_table
に、example_chain
という名前のチェーンを作成するには、次のコマンドを実行します。# nft add chain ip example_table example_chain { type filter hook input priority 0 \; }
重要シェルがセミコロンをコマンドの終わりとして解釈しないようにするには、バックスラッシュでセミコロンをエスケープする必要があります。
空のマップを作成します。たとえば、IPv4 アドレスのマッピングを作成するには、次のコマンドを実行します。
# nft add map ip example_table example_map { type ipv4_addr : verdict \; }
マップを使用するルールを作成します。たとえば、次のコマンドは、両方とも
example_map
で定義されている IPv4 アドレスにアクションを適用するルールを、example_table
のexample_chain
に追加します。# nft add rule example_table example_chain ip saddr vmap @example_map
IPv4 アドレスと対応するアクションを
example_map
に追加します。# nft add element ip example_table example_map { 192.0.2.1 : accept, 192.0.2.2 : drop }
以下の例では、IPv4 アドレスのアクションへのマッピングを定義します。上記で作成したルールと組み合わせて、ファイアウォールは
192.0.2.1
からのパケットを許可し、192.0.2.2
からのパケットを破棄します。オプション: 別の IP アドレスおよび action ステートメントを追加してマップを拡張します。
# nft add element ip example_table example_map { 192.0.2.3 : accept }
オプション: マップからエントリーを削除します。
# nft delete element ip example_table example_map { 192.0.2.1 }
オプション: ルールセットを表示します。
# nft list ruleset table ip example_table { map example_map { type ipv4_addr : verdict elements = { 192.0.2.2 : drop, 192.0.2.3 : accept } } chain example_chain { type filter hook input priority filter; policy accept; ip saddr vmap @example_map } }
14.6.6.3. 関連情報
-
システムの
nft (8)
man ページのマップ
セクション
14.6.7. 以下に例を示します。nftables スクリプトを使用した LAN および DMZ の保護
RHEL ルーターで nftables
フレームワークを使用して、内部 LAN 内のネットワーククライアントと DMZ の Web サーバーを、インターネットやその他のネットワークからの不正アクセスから保護するファイアウォールスクリプトを作成およびインストールします。
この例はデモ目的専用で、特定の要件があるシナリオを説明しています。
ファイアウォールスクリプトは、ネットワークインフラストラクチャーとセキュリティー要件に大きく依存します。この例を使用して、独自の環境用のスクリプトを作成する際に nftables
ファイアウォールの概念を理解してください。
14.6.7.1. ネットワークの状態
この例のネットワークは、以下の条件下にあります。
ルーターは以下のネットワークに接続されています。
-
インターフェイス
enp1s0
を介したインターネット -
インターフェイス
enp7s0
を介した内部 LAN -
enp8s0
までの DMZ
-
インターフェイス
-
ルーターのインターネットインターフェイスには、静的 IPv4 アドレス (
203.0.113.1
) と IPv6 アドレス (2001:db8:a::1
) の両方が割り当てられています。 -
内部 LAN のクライアントは
10.0.0.0/24
の範囲のプライベート IPv4 アドレスのみを使用します。その結果、LAN からインターネットへのトラフィックには、送信元ネットワークアドレス変換 (SNAT) が必要です。 -
内部 LAN の管理者用 PC は、IP アドレス
10.0.0.100
および10.0.0.200
を使用します。 -
DMZ は、
198.51.100.0/24
および2001:db8:b::/56
の範囲のパブリック IP アドレスを使用します。 -
DMZ の Web サーバーは、IP アドレス
198.51.100.5
および2001:db8:b::5
を使用します。 - ルーターは、LAN および DMZ 内のホストのキャッシング DNS サーバーとして機能します。
14.6.7.2. ファイアウォールスクリプトのセキュリティー要件
以下は、サンプルネットワークにおける nftables
ファイアウォールの要件です。
ルーターは以下を実行できる必要があります。
- DNS クエリーを再帰的に解決します。
- ループバックインターフェイスですべての接続を実行します。
内部 LAN のクライアントは以下を実行できる必要があります。
- ルーターで実行しているキャッシング DNS サーバーをクエリーします。
- DMZ の HTTPS サーバーにアクセスします。
- インターネット上の任意の HTTPS サーバーにアクセスします。
- 管理者用の PC は、SSH を使用してルーターと DMZ 内のすべてのサーバーにアクセスできる必要があります。
DMZ の Web サーバーは以下を実行できる必要があります。
- ルーターで実行しているキャッシング DNS サーバーをクエリーします。
- インターネット上の HTTPS サーバーにアクセスして更新をダウンロードします。
インターネット上のホストは以下を実行できる必要があります。
- DMZ の HTTPS サーバーにアクセスします。
さらに、以下のセキュリティー要件が存在します。
- 明示的に許可されていない接続の試行はドロップする必要があります。
- ドロップされたパケットはログに記録する必要があります。
14.6.7.3. ドロップされたパケットをファイルにロギングするための設定
デフォルトでは、systemd
は、ドロップされたパケットなどのカーネルメッセージをジャーナルに記録します。さらに、このようなエントリーを別のファイルに記録するように rsyslog
サービスを設定することもできます。ログファイルが無限に大きくならないようにするために、ローテーションポリシーを設定します。
前提条件
-
rsyslog
パッケージがインストールされている。 -
rsyslog
サービスが実行されている。
手順
以下の内容で
/etc/rsyslog.d/nftables.conf
ファイルを作成します。:msg, startswith, "nft drop" -/var/log/nftables.log & stop
この設定を使用すると、
rsyslog
サービスはドロップされたパケットを/var/log/messages
ではなく/var/log/nftables.log
ファイルに記録します。rsyslog
サービスを再起動します。# systemctl restart rsyslog
サイズが 10 MB を超える場合は、以下の内容で
/etc/logrotate.d/nftables
ファイルを作成し、/var/log/nftables.log
をローテーションします。/var/log/nftables.log { size +10M maxage 30 sharedscripts postrotate /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true endscript }
maxage 30
設定は、次のローテーション操作中にlogrotate
が 30 日経過したローテーション済みログを削除することを定義します。
関連情報
-
システム上の
rsyslog.conf (5)
およびlogrotate (8) の
man ページ
14.6.7.4. nftables スクリプトの作成とアクティブ化
この例は、RHEL ルーターで実行され、DMZ の内部 LAN および Web サーバーのクライアントを保護する nftables
ファイアウォールスクリプトです。この例で使用されているネットワークとファイアウォールの要件の詳細は、ファイアウォールスクリプトの ネットワークの状態 および ファイアウォールスクリプトのセキュリティー要件 を参照してください。
この nftables
ファイアウォールスクリプトは、デモ専用です。お使いの環境やセキュリティー要件に適応させて使用してください。
前提条件
- ネットワークは、ネットワークの状態 で説明されているとおりに設定されます。
手順
以下の内容で
/etc/nftables/firewall.nft
スクリプトを作成します。# Remove all rules flush ruleset # Table for both IPv4 and IPv6 rules table inet nftables_svc { # Define variables for the interface name define INET_DEV = enp1s0 define LAN_DEV = enp7s0 define DMZ_DEV = enp8s0 # Set with the IPv4 addresses of admin PCs set admin_pc_ipv4 { type ipv4_addr elements = { 10.0.0.100, 10.0.0.200 } } # Chain for incoming trafic. Default policy: drop chain INPUT { type filter hook input priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # Accept incoming traffic on loopback interface iifname lo accept # Allow request from LAN and DMZ to local DNS server iifname { $LAN_DEV, $DMZ_DEV } meta l4proto { tcp, udp } th dport 53 accept # Allow admins PCs to access the router using SSH iifname $LAN_DEV ip saddr @admin_pc_ipv4 tcp dport 22 accept # Last action: Log blocked packets # (packets that were not accepted in previous rules in this chain) log prefix "nft drop IN : " } # Chain for outgoing traffic. Default policy: drop chain OUTPUT { type filter hook output priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # Accept outgoing traffic on loopback interface oifname lo accept # Allow local DNS server to recursively resolve queries oifname $INET_DEV meta l4proto { tcp, udp } th dport 53 accept # Last action: Log blocked packets log prefix "nft drop OUT: " } # Chain for forwarding traffic. Default policy: drop chain FORWARD { type filter hook forward priority filter policy drop # Accept packets in established and related state, drop invalid packets ct state vmap { established:accept, related:accept, invalid:drop } # IPv4 access from LAN and internet to the HTTPS server in the DMZ iifname { $LAN_DEV, $INET_DEV } oifname $DMZ_DEV ip daddr 198.51.100.5 tcp dport 443 accept # IPv6 access from internet to the HTTPS server in the DMZ iifname $INET_DEV oifname $DMZ_DEV ip6 daddr 2001:db8:b::5 tcp dport 443 accept # Access from LAN and DMZ to HTTPS servers on the internet iifname { $LAN_DEV, $DMZ_DEV } oifname $INET_DEV tcp dport 443 accept # Last action: Log blocked packets log prefix "nft drop FWD: " } # Postrouting chain to handle SNAT chain postrouting { type nat hook postrouting priority srcnat; policy accept; # SNAT for IPv4 traffic from LAN to internet iifname $LAN_DEV oifname $INET_DEV snat ip to 203.0.113.1 } }
/etc/nftables/firewall.nft
スクリプトを/etc/sysconfig/nftables.conf
ファイルに追加します。include "/etc/nftables/firewall.nft"
IPv4 転送を有効にします。
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
nftables
サービスを有効にして起動します。# systemctl enable --now nftables
検証
オプション:
nftables
ルールセットを確認します。# nft list ruleset ...
ファイアウォールが阻止するアクセスの実行を試みます。たとえば、DMZ から SSH を使用してルーターにアクセスします。
# ssh router.example.com ssh: connect to host router.example.com port 22: Network is unreachable
ロギング設定に応じて、以下を検索します。
ブロックされたパケットの
systemd
ジャーナル:# journalctl -k -g "nft drop" Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
ブロックされたパケットの
/var/log/nftables.log
ファイル:Oct 14 17:27:18 router kernel: nft drop IN : IN=enp8s0 OUT= MAC=... SRC=198.51.100.5 DST=198.51.100.1 ... PROTO=TCP SPT=40464 DPT=22 ... SYN ...
14.6.8. nftables を使用したポート転送の設定
ポート転送を使用すると、管理者は特定の宛先ポートに送信されたパケットを、別のローカルまたはリモートポートに転送できます。
たとえば、Web サーバーにパブリック IP アドレスがない場合は、ファイアウォールの 80
ポートおよび 443
ポートの着信パケットを Web サーバーに転送するファイアウォールのポート転送ルールを設定できます。このファイアウォールルールを使用すると、インターネットのユーザーは、ファイアウォールの IP またはホスト名を使用して Web サーバーにアクセスできます。
14.6.8.1. 着信パケットの別のローカルポートへの転送
nftables
を使用してパケットを転送できます。たとえば、ポート 8022
の着信 IPv4 パケットを、ローカルシステムのポート 22
に転送できます。
手順
ip
アドレスファミリーを使用して、nat
という名前のテーブルを作成します。# nft add table ip nat
テーブルに、
prerouting
チェーンおよびpostrouting
チェーンを追加します。# nft -- add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
注記--
オプションをnft
コマンドに渡して、シェルが負の priority 値をnft
コマンドのオプションとして解釈しないようにします。8022
ポートの着信パケットを、ローカルポート22
にリダイレクトするルールをprerouting
チェーンに追加します。# nft add rule ip nat prerouting tcp dport 8022 redirect to :22
14.6.8.2. 特定のローカルポートで着信パケットを別のホストに転送
宛先ネットワークアドレス変換 (DNAT) ルールを使用して、ローカルポートの着信パケットをリモートホストに転送できます。これにより、インターネット上のユーザーは、プライベート IP アドレスを持つホストで実行しているサービスにアクセスできるようになります。
たとえば、ローカルポート 443
の着信 IPv4 パケットを、IP アドレス 192.0.2.1
を持つリモートシステムの同じポート番号に転送できます。
前提条件
-
パケットを転送するシステムに
root
ユーザーとしてログインしている。
手順
ip
アドレスファミリーを使用して、nat
という名前のテーブルを作成します。# nft add table ip nat
テーブルに、
prerouting
チェーンおよびpostrouting
チェーンを追加します。# nft -- add chain ip nat prerouting { type nat hook prerouting priority -100 \; } # nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
注記--
オプションをnft
コマンドに渡して、シェルが負の priority 値をnft
コマンドのオプションとして解釈しないようにします。443
ポートの着信パケットを192.0.2.1
上の同じポートにリダイレクトするルールをprerouting
チェーンに追加します。# nft add rule ip nat prerouting tcp dport 443 dnat to 192.0.2.1
出力トラフィックをマスカレードするルールを
postrouting
チェーンに追加します。# nft add rule ip nat postrouting daddr 192.0.2.1 masquerade
パケット転送を有効にします。
# echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/95-IPv4-forwarding.conf # sysctl -p /etc/sysctl.d/95-IPv4-forwarding.conf
14.6.9. nftables を使用した接続の量の制限
nftables
を使用して、接続の数を制限したり、一定の数の接続の確立を試みる IP アドレスをブロックして、システムリソースを過剰に使用されないようにします。
14.6.9.1. nftables を使用した接続数の制限
nft
ユーティリティーの ct count
パラメーターを使用すると、IP アドレスごとの同時接続数を制限できます。たとえば、この機能を使用すると、各送信元 IP アドレスがホストへの並列 SSH 接続を 2 つだけ確立できるように設定できます。
手順
inet
アドレスファミリーを使用してfilter
テーブルを作成します。# nft add table inet filter
input
チェーンをinet filter
テーブルに追加します。# nft add chain inet filter input { type filter hook input priority 0 \; }
IPv4 アドレスの動的セットを作成します。
# nft add set inet filter limit-ssh { type ipv4_addr\; flags dynamic \;}
IPv4 アドレスからの SSH ポート (22) への同時着信接続を 2 つだけ許可し、同じ IP からのそれ以降の接続をすべて拒否するルールを、
input
チェーンに追加します。# nft add rule inet filter input tcp dport ssh ct state new add @limit-ssh { ip saddr ct count over 2 } counter reject
検証
- 同じ IP アドレスからホストへの新しい同時 SSH 接続を 2 つ以上確立します。すでに 2 つの接続が確立されている場合、Nftables が SSH ポートへの接続を拒否します。
limit-ssh
メーターを表示します。# nft list set inet filter limit-ssh table inet filter { set limit-ssh { type ipv4_addr size 65535 flags dynamic elements = { 192.0.2.1 ct count over 2 , 192.0.2.2 ct count over 2 } } }
elements
エントリーは、現時点でルールに一致するアドレスを表示します。この例では、elements
は、SSH ポートへのアクティブな接続がある IP アドレスを一覧表示します。出力には、アクティブな接続の数を表示しないため、接続が拒否された場合は表示されないことに注意してください。
14.6.9.2. 1 分以内に新しい着信 TCP 接続を 11 個以上試行する IP アドレスのブロック
1 分以内に 11 個以上の IPv4 TCP 接続を確立しているホストを一時的にブロックできます。
手順
ip
アドレスファミリーを使用してfilter
テーブルを作成します。# nft add table ip filter
input
チェーンをfilter
テーブルに追加します。# nft add chain ip filter input { type filter hook input priority 0 \; }
1 分以内に 10 を超える TCP 接続を確立しようとするソースアドレスからのすべてのパケットを破棄するルールを追加します。
# nft add rule ip filter input ip protocol tcp ct state new, untracked meter ratemeter { ip saddr timeout 5m limit rate over 10/minute } drop
timeout 5m
パラメーターは、nftables
が、メーターが古いエントリーで一杯にならないように、5 分後にエントリーを自動的に削除することを定義します。
検証
メーターのコンテンツを表示するには、以下のコマンドを実行します。
# nft list meter ip filter ratemeter table ip filter { meter ratemeter { type ipv4_addr size 65535 flags dynamic,timeout elements = { 192.0.2.1 limit rate over 10/minute timeout 5m expires 4m58s224ms } } }
14.6.10. nftables ルールのデバッグ
nftables
フレームワークは、管理者がルールをデバッグし、パケットがそれに一致するかどうかを確認するためのさまざまなオプションを提供します。
14.6.10.1. カウンターによるルールの作成
ルールが一致しているかどうかを確認するには、カウンターを使用できます。
-
既存のルールにカウンターを追加する手順の詳細は、
Configuring and managing networking
の Adding a counter to an existing rule を参照してください。
前提条件
- ルールを追加するチェーンが存在する。
手順
counter
パラメーターで新しいルールをチェーンに追加します。以下の例では、ポート 22 で TCP トラフィックを許可し、このルールに一致するパケットとトラフィックをカウントするカウンターを使用するルールを追加します。# nft add rule inet example_table example_chain tcp dport 22 counter accept
カウンター値を表示するには、次のコマンドを実行します。
# nft list ruleset table inet example_table { chain example_chain { type filter hook input priority filter; policy accept; tcp dport ssh counter packets 6872 bytes 105448565 accept } }
14.6.10.2. 既存のルールへのカウンターの追加
ルールが一致しているかどうかを確認するには、カウンターを使用できます。
-
カウンターで新しいルールを追加する手順の詳細は、
Configuring and managing networking
の Creating a rule with the counter を参照してください。
前提条件
- カウンターを追加するルールがある。
手順
チェーンのルール (ハンドルを含む) を表示します。
# nft --handle list chain inet example_table example_chain table inet example_table { chain example_chain { # handle 1 type filter hook input priority filter; policy accept; tcp dport ssh accept # handle 4 } }
ルールの代わりに、
counter
パラメーターを使用してカウンターを追加します。以下の例は、前の手順で表示したルールの代わりに、カウンターを追加します。# nft replace rule inet example_table example_chain handle 4 tcp dport 22 counter accept
カウンター値を表示するには、次のコマンドを実行します。
# nft list ruleset table inet example_table { chain example_chain { type filter hook input priority filter; policy accept; tcp dport ssh counter packets 6872 bytes 105448565 accept } }
14.6.10.3. 既存のルールに一致するパケットの監視
nftables
のトレース機能と、nft monitor
コマンドを組み合わせることにより、管理者はルールに一致するパケットを表示できます。このルールに一致するパケットを監視するために、ルールのトレースを有効にできます。
前提条件
- カウンターを追加するルールがある。
手順
チェーンのルール (ハンドルを含む) を表示します。
# nft --handle list chain inet example_table example_chain table inet example_table { chain example_chain { # handle 1 type filter hook input priority filter; policy accept; tcp dport ssh accept # handle 4 } }
ルールを置き換えてトレース機能を追加しますが、
meta nftrace set 1
パラメーターを使用します。以下の例は、前の手順で表示したルールの代わりに、トレースを有効にします。# nft replace rule inet example_table example_chain handle 4 tcp dport 22 meta nftrace set 1 accept
nft monitor
コマンドを使用して、トレースを表示します。以下の例は、コマンドの出力をフィルタリングして、inet example_table example_chain
が含まれるエントリーのみを表示します。# nft monitor | grep "inet example_table example_chain" trace id 3c5eb15e inet example_table example_chain packet: iif "enp1s0" ether saddr 52:54:00:17:ff:e4 ether daddr 52:54:00:72:2f:6e ip saddr 192.0.2.1 ip daddr 192.0.2.2 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49710 ip protocol tcp ip length 60 tcp sport 56728 tcp dport ssh tcp flags == syn tcp window 64240 trace id 3c5eb15e inet example_table example_chain rule tcp dport ssh nftrace set 1 accept (verdict accept) ...
警告nft monitor
コマンドは、トレースが有効になっているルールの数と、一致するトラフィックの量に応じて、大量の出力を表示できます。grep
などのユーティリティーを使用して出力をフィルタリングします。
14.6.11. nftables ルールセットのバックアップおよび復元
nftables
ルールをファイルにバックアップし、後で復元できます。また、管理者はルールが含まれるファイルを使用して、たとえばルールを別のサーバーに転送できます。
14.6.11.1. ファイルへの nftables ルールセットのバックアップ
nft
ユーティリティーを使用して、nftables
ルールセットをファイルにバックアップできます。
手順
nftables
ルールのバックアップを作成するには、次のコマンドを実行します。nft list ruleset
形式で生成された形式の場合:# nft list ruleset > file.nft
JSON 形式の場合は、以下のようになります。
# nft -j list ruleset > file.json
14.6.11.2. ファイルからの nftables ルールセットの復元
ファイルから nftables
ルールセットを復元できます。
手順
nftables
ルールを復元するには、以下を行います。復元するファイルが、
nft list ruleset
が生成した形式であるか、nft
コマンドを直接含んでいる場合は、以下のコマンドを実行します。# nft -f file.nft
復元するファイルが JSON 形式の場合は、次のコマンドを実行します。
# nft -j -f file.json