23.6. nftables の使用
シナリオが、firewalld でカバーされる一般的なパケットフィルタリングのケースに該当しない場合、またはルールを完全に制御したい場合は、nftables フレームワークを使用できます。
nftables フレームワークは、パケットを分類機能を提供し、iptables、ip6tables、arptables、ebtables、および ipset ユーティリティーの後継となります。利便性、機能、パフォーマンスにおいて、以前のパケットフィルタリングツールに多くの改良が追加されました。以下に例を示します。
- 線形処理の代わりに組み込みルックアップテーブルを使用
-
IPv4プロトコルおよびIPv6プロトコルに対する 1 つのフレームワーク - ルールセット全体を取得、更新、保存するのではなく、トランザクションを通じてカーネルルールセットをその場で更新する
-
ルールセットにおけるデバッグおよびトレースへの対応 (
nftrace) およびトレースイベントの監視 (nftツール) - より統一されたコンパクトな構文、プロトコル固有の拡張なし
- サードパーティーのアプリケーション用 Netlink API
nftables フレームワークは、テーブルを使用してチェーンを保存します。このチェーンには、アクションを実行する個々のルールが含まれます。nft ユーティリティーは、以前のパケットフィルタリングフレームワークのツールをすべて置き換えます。libnftnl ライブラリーを介して、nftables Netlink API との低レベルの対話に libnftables ライブラリーを使用できます。
ルールセット変更が適用されていることを表示するには、nft list ruleset コマンドを使用します。カーネルルールセットをクリアするには、nft flush ruleset コマンドを使用します。同じカーネルインフラストラクチャーを使用するため、iptables-nft コマンドでインストールされたルールセットにも影響する可能性があることに注意してください。
23.6.1. nftables テーブル、チェーン、およびルールの作成および管理 リンクのコピーリンクがクリップボードにコピーされました!
nftables ルールセットを表示して管理できます。
23.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>
23.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
23.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コマンドを使用します。
23.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コマンドを使用します。
23.6.2. iptables から nftables への移行 リンクのコピーリンクがクリップボードにコピーされました!
ファイアウォール設定が依然として iptables ルールを使用している場合は、iptables ルールを nftables に移行できます。
23.6.2.1. firewalld、nftables、または iptables を使用する場合 リンクのコピーリンクがクリップボードにコピーされました!
RHEL 8 では、シナリオに応じて次のパケットフィルタリングユーティリティーを使用できます。
-
firewalld:firewalldユーティリティーは、一般的な使用例のファイアウォール設定を簡素化します。 -
nftables:nftablesユーティリティーを使用して、ネットワーク全体など、複雑なパフォーマンスに関する重要なファイアウォールを設定します。 -
iptables:Red Hat Enterprise Linux のiptablesユーティリティーは、legacyバックエンドの代わりにnf_tablesカーネル API を使用します。nf_tablesAPI は、iptablesコマンドを使用するスクリプトが、Red Hat Enterprise Linux で引き続き動作するように、後方互換性を提供します。新しいファイアウォールスクリプトの場合は、nftablesを使用します。
さまざまなファイアウォール関連サービス (firewalld、nftables、または iptables) が相互に影響を与えないようにするには、RHEL ホストでそのうち 1 つだけを実行し、他のサービスを無効にします。
23.6.2.2. nftables フレームワークの概念 リンクのコピーリンクがクリップボードにコピーされました!
iptables フレームワークと比較すると、nftables はより最新で効率的かつ柔軟な代替手段を提供します。nftables フレームワークは、iptables よりも高度な機能と改善を提供し、ルール管理を簡素化し、パフォーマンスを向上させます。これにより、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などの非ターミナルアクションは、特定のタスク (パケットのカウント、ログ記録、マークの設定など) を実行しますが、後続のルールを評価できます。
23.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 アドレス、ポート番号、その他のネットワーク関連要素のコレクションを作成します。これらのセットにより、ファイアウォールルールの作成と管理のプロセスが大幅に合理化、最適化、高速化されます。
23.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
23.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
23.6.2.6. 一般的な iptables コマンドと nftables コマンドの比較 リンクのコピーリンクがクリップボードにコピーされました!
以下は、一般的な iptables コマンドと nftables コマンドの比較です。
すべてのルールをリスト表示します。
Expand iptables nftables iptables-savenft list ruleset特定のテーブルおよびチェーンをリスト表示します。
Expand iptables nftables iptables -Lnft list table ip filteriptables -L INPUTnft list chain ip filter INPUTiptables -t nat -L PREROUTINGnft list chain ip nat PREROUTINGnftコマンドは、テーブルおよびチェーンを事前に作成しません。これらは、ユーザーが手動で作成した場合にのみ存在します。firewalld によって生成されたルールの一覧表示:
# nft list table inet firewalld # nft list table ip firewalld # nft list table ip6 firewalld
23.6.3. nftables を使用した NAT の設定 リンクのコピーリンクがクリップボードにコピーされました!
nftables を使用すると、以下のネットワークアドレス変換 (NAT) タイプを設定できます。
- マスカレーディング
- ソース NAT (SNAT)
- 宛先 NAT (DNAT)
- リダイレクト
iifname パラメーターおよび oifname パラメーターでは実インターフェイス名のみを使用でき、代替名 (altname) には対応していません。
23.6.3.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 の特殊なケースです。たとえば、サービスが標準ポートとは異なるポートで実行する場合は、標準ポートからこの特定のポートに着信トラフィックをリダイレクトすることができます。
23.6.3.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
23.6.3.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
23.6.3.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" masqueradeens3インターフェイスが静的 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
23.6.3.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
23.6.4. nftables スクリプトの作成および実行 リンクのコピーリンクがクリップボードにコピーされました!
nftables フレームワークを使用する主な利点は、スクリプトの実行がアトミックであることです。つまり、システムがスクリプト全体を適用するか、エラーが発生した場合には実行を阻止することを意味します。これにより、ファイアウォールは常に一貫した状態になります。
さらに、nftables スクリプト環境を使用すると、次のことができます。
- コメントの追加
- 変数の定義
- 他のルールセットファイルの組み込み
nftables パッケージをインストールすると、Red Hat Enterprise Linux が自動的に *.nft スクリプトを /etc/nftables/ ディレクトリーに作成します。このスクリプトには、さまざまな目的でテーブルと空のチェーンを作成するコマンドが含まれます。
23.6.4.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
23.6.4.2. nftables スクリプトの実行 リンクのコピーリンクがクリップボードにコピーされました!
nftables スクリプトは、nft ユーティリティーに渡すか、スクリプトを直接実行することで実行できます。
手順
nftablesスクリプトをnftユーティリティーに渡して実行するには、次のコマンドを実行します。# nft -f /etc/nftables/<example_firewall_script>.nftnftablesスクリプトを直接実行するには、次のコマンドを実行します。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 はスクリプトを正常に実行しますが、ルールの配置やパラメーター不足、またはスクリプト内のその他の問題により、ファイアウォールが期待通りの動作を起こさない可能性があります。
23.6.4.3. nftables スクリプトでコメントの使用 リンクのコピーリンクがクリップボードにコピーされました!
nftables スクリプト環境は、# 文字の右側から行末までのすべてをコメントとして解釈します。
コメントは、行の先頭またはコマンドの横から開始できます。
...
# Flush the rule set
flush ruleset
add table inet example_table # Create a table
...
23.6.4.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注記中括弧は、変数がセットを表していることを示すため、ルールで使用する場合は、特別なセマンティクスを持ちます。
23.6.4.5. nftables スクリプトへのファイルの追加 リンクのコピーリンクがクリップボードにコピーされました!
nftables スクリプト環境では、include ステートメントを使用して他のスクリプトを含めることができます。
絶対パスまたは相対パスのないファイル名のみを指定すると、nftables には、デフォルトの検索パスのファイルが含まれます。これは、Red Hat Enterprise Linux では /etc に設定されています。
例23.1 デフォルト検索ディレクトリーからのファイルを含む
デフォルトの検索ディレクトリーからファイルを指定するには、次のコマンドを実行します。
include "example.nft"
例23.2 ディレクトリーの *.nft ファイルをすべて含む
*.nft で終わるすべてのファイルを /etc/nftables/rulesets/ ディレクトリーに保存するには、次のコマンドを実行します。
include "/etc/nftables/rulesets/*.nft"
include ステートメントは、ドットで始まるファイルに一致しないことに注意してください。
23.6.4.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 nftablesnftablesサービスを有効にします。# systemctl enable nftables
23.6.5. nftables コマンドでのセットの使用 リンクのコピーリンクがクリップボードにコピーされました!
nftables フレームワークは、セットをネイティブに対応します。たとえば、ルールが複数の IP アドレス、ポート番号、インターフェイス、またはその他の一致基準に一致する必要がある場合など、セットを使用できます。
23.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 } }
23.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 dropexample_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) 表記を使用することもできます。
23.6.5.3. 動的セットを使用してパケットパスからエントリーを追加する リンクのコピーリンクがクリップボードにコピーされました!
nftables フレームワークの動的セットにより、パケットデータから要素を自動的に追加できます。たとえば、IP アドレス、宛先ポート、MAC アドレスなどです。この機能により、これらの要素をリアルタイムで収集し、それらを使用して拒否リスト、禁止リストなどを作成し、セキュリティーの脅威に即座に対応できるようになります。
前提条件
-
inetファミリーの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 \; }重要シェルがセミコロンをコマンドの終わりとして解釈しないようにするには、バックスラッシュでセミコロンをエスケープする必要があります。
着信パケットの送信元 IPv4 アドレスを
example_setセットに動的に追加するためのルールを作成します。# nft add rule inet example_table example_chain set add ip saddr @example_setこのコマンドは、
example_chainルールチェーンとexample_table内に新しいルールを作成し、パケットの送信元 IPv4 アドレスをexample_setに動的に追加します。
検証
ルールが追加されたことを確認します。
# nft list ruleset ... table ip example_table { set example_set { type ipv4_addr elements = { 192.0.2.250, 192.0.2.251 } } chain example_chain { type filter hook input priority 0 add @example_set { ip saddr } } }このコマンドは、現在
nftablesにロードされているルールセット全体を表示します。これは、IP がルールをアクティブにトリガーしており、example_set が関連するアドレスで更新されていることを示しています。
次のステップ
動的な IP セットを取得すると、さまざまなセキュリティー、フィルタリング、トラフィック制御の目的に使用できます。以下に例を示します。
- ネットワークトラフィックをブロック、制限、またはログに記録する
- 許可リストと組み合わせて、信頼できるユーザーのアクセスを禁止しないようにする
- 過剰なブロックを防ぐために自動タイムアウトを使用する
23.6.6. nftables コマンドにおける決定マップの使用 リンクのコピーリンクがクリップボードにコピーされました!
ディクショナリーとしても知られている決定マップにより、nft は一致基準をアクションにマッピングすることで、パケット情報に基づいてアクションを実行できます。
23.6.6.1. nftables での匿名マップの使用 リンクのコピーリンクがクリップボードにコピーされました!
匿名マップは、ルールで直接使用する { match_criteria : action } ステートメントです。ステートメントには、複数のコンマ区切りマッピングを含めることができます。
匿名マップの欠点は、マップを変更する場合には、ルールを置き換える必要があることです。動的なソリューションの場合は、nftables での名前付きマップの使用 で説明されているように名前付きマップを使用します。
たとえば、匿名マップを使用して、IPv4 プロトコルおよび IPv6 プロトコルの TCP パケットと UDP パケットの両方を異なるチェーンにルーティングし、着信 TCP パケットと UDP パケットを個別にカウントできます。
手順
新しいテーブルを作成します。
# nft add table inet example_tableexample_tableにtcp_packetsチェーンを作成します。# nft add chain inet example_table tcp_packetsこのチェーンのトラフィックをカウントする
tcp_packetsにルールを追加します。# nft add rule inet example_table tcp_packets counterexample_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チェーンのカウンターは、受信パケットとバイトの両方を表示します。
23.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_mapIPv4 アドレスと対応するアクションを
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 } }
23.6.7. 以下に例を示します。nftables スクリプトを使用した LAN および DMZ の保護 リンクのコピーリンクがクリップボードにコピーされました!
RHEL ルーターで nftables フレームワークを使用して、内部 LAN 内のネットワーククライアントと DMZ の Web サーバーを、インターネットやその他のネットワークからの不正アクセスから保護するファイアウォールスクリプトを作成およびインストールします。
この例はデモ目的専用で、特定の要件があるシナリオを説明しています。
ファイアウォールスクリプトは、ネットワークインフラストラクチャーとセキュリティー要件に大きく依存します。この例を使用して、独自の環境用のスクリプトを作成する際に nftables ファイアウォールの概念を理解してください。
23.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 サーバーとして機能します。
23.6.7.2. ファイアウォールスクリプトのセキュリティー要件 リンクのコピーリンクがクリップボードにコピーされました!
以下は、サンプルネットワークにおける nftables ファイアウォールの要件です。
ルーターは以下を実行できる必要があります。
- DNS クエリーを再帰的に解決します。
- ループバックインターフェイスですべての接続を実行します。
内部 LAN のクライアントは以下を実行できる必要があります。
- ルーターで実行しているキャッシング DNS サーバーをクエリーします。
- DMZ の HTTPS サーバーにアクセスします。
- インターネット上の任意の HTTPS サーバーにアクセスします。
- 管理者用の PC は、SSH を使用してルーターと DMZ 内のすべてのサーバーにアクセスできる必要があります。
DMZ の Web サーバーは以下を実行できる必要があります。
- ルーターで実行しているキャッシング DNS サーバーをクエリーします。
- インターネット上の HTTPS サーバーにアクセスして更新をダウンロードします。
インターネット上のホストは以下を実行できる必要があります。
- DMZ の HTTPS サーバーにアクセスします。
さらに、以下のセキュリティー要件が存在します。
- 明示的に許可されていない接続の試行はドロップする必要があります。
- ドロップされたパケットはログに記録する必要があります。
23.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 日経過したローテーション済みログを削除することを定義します。
23.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.confnftablesサービスを有効にして起動します。# 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 ...
23.6.8. nftables を使用した接続の量の制限 リンクのコピーリンクがクリップボードにコピーされました!
nftables を使用して、接続の数を制限したり、一定の数の接続の確立を試みる IP アドレスをブロックして、システムリソースを過剰に使用されないようにします。
23.6.8.1. nftables を使用した接続数の制限 リンクのコピーリンクがクリップボードにコピーされました!
nft ユーティリティーの ct count パラメーターを使用すると、IP アドレスごとの同時接続数を制限できます。たとえば、この機能を使用すると、各送信元 IP アドレスがホストへの並列 SSH 接続を 2 つだけ確立できるように設定できます。
手順
inetアドレスファミリーを使用してfilterテーブルを作成します。# nft add table inet filterinputチェーンを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 アドレスを一覧表示します。出力には、アクティブな接続の数を表示しないため、接続が拒否された場合は表示されないことに注意してください。
23.6.8.2. 1 分以内に新しい着信 TCP 接続を 11 個以上試行する IP アドレスのブロック リンクのコピーリンクがクリップボードにコピーされました!
1 分以内に 11 個以上の IPv4 TCP 接続を確立しているホストを一時的にブロックできます。
手順
ipアドレスファミリーを使用してfilterテーブルを作成します。# nft add table ip filterinputチェーンを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 } droptimeout 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 } } }
23.6.9. nftables ルールのデバッグ リンクのコピーリンクがクリップボードにコピーされました!
nftables フレームワークは、管理者がルールをデバッグし、パケットがそれに一致するかどうかを確認するためのさまざまなオプションを提供します。
23.6.9.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 } }
23.6.9.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 } }
23.6.9.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 acceptnft 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などのユーティリティーを使用して出力をフィルタリングします。
23.6.10. nftables ルールセットのバックアップおよび復元 リンクのコピーリンクがクリップボードにコピーされました!
nftables ルールをファイルにバックアップし、後で復元できます。また、管理者はルールが含まれるファイルを使用して、たとえばルールを別のサーバーに転送できます。
23.6.10.1. ファイルへの nftables ルールセットのバックアップ リンクのコピーリンクがクリップボードにコピーされました!
nft ユーティリティーを使用して、nftables ルールセットをファイルにバックアップできます。
手順
nftablesルールのバックアップを作成するには、次のコマンドを実行します。nft list ruleset形式で生成された形式の場合:# nft list ruleset > file.nftJSON 形式の場合は、以下のようになります。
# nft -j list ruleset > file.json
23.6.10.2. ファイルからの nftables ルールセットの復元 リンクのコピーリンクがクリップボードにコピーされました!
ファイルから nftables ルールセットを復元できます。
手順
nftablesルールを復元するには、以下を行います。復元するファイルが、
nft list rulesetが生成した形式であるか、nftコマンドを直接含んでいる場合は、以下のコマンドを実行します。# nft -f file.nft復元するファイルが JSON 形式の場合は、次のコマンドを実行します。
# nft -j -f file.json