iptablesとNetfilterアーキテクチャの深い探索
紹介
ファイアウォールは、サーバーやインフラを保護するために設定できる重要なツールです。Linuxのエコシステムでは、iptablesはカーネルのnetfilterパケットフィルタリングフレームワークと連携して動作する広く使用されているファイアウォールツールです。信頼性のあるファイアウォールポリシーを作成することは、複雑な構文や相互に関連する部品の数のために daunting になることがあります。
このガイドでは、独自のファイアウォールポリシーを構築する必要があるユーザーにとって、iptablesのアーキテクチャをより理解しやすくすることを目的としています。iptablesがnetfilterとどのように相互作用し、さまざまなコンポーネントがどのように組み合わさって包括的なフィルタリングシステムを提供するかについて議論します。
IPTablesとNetfilterとは何ですか?
長年にわたり、Linuxで最も一般的に使用されていたファイアウォールソフトウェアはiptablesと呼ばれていました。一部のディストリビューションでは、nftablesという新しいツールに置き換えられましたが、iptablesの構文はまだベースラインとして一般的に使用されています。iptablesファイアウォールは、Linuxカーネルのネットワーキングスタック内のパケットフィルタリングフックと相互作用することで機能します。これらのカーネルフックは、netfilterフレームワークとして知られています。
ネットワーキング層を通過するすべてのパケット(受信または送信)は、これらのフックをトリガーし、プログラムが重要なポイントでトラフィックと対話できるようにします。iptables に関連するカーネルモジュールは、トラフィックがファイアウォールルールによって定められた条件に準拠することを保証するために、これらのフックに登録します。
ネットフィルターフック
プログラムが登録できるnetfilterフックは5つあります。パケットがスタックを進むにつれて、それらのフックに登録されているカーネルモジュールがトリガーされます。パケットがトリガーするフックは、パケットが受信か送信か、パケットの宛先、そして前の時点でパケットがドロップまたは拒否されたかどうかに依存します。
以下のフックは、ネットワーキングスタックにおけるこれらの明確に定義されたポイントを表しています。
NF_IP_PRE_ROUTING: このフックは、ネットワークスタックに入った直後に、すべての受信トラフィックによってトリガーされます。このフックは、パケットをどこに送信するかに関するルーティング決定が行われる前に処理されます。NF_IP_LOCAL_IN: このフックは、パケットがローカルシステムに到達するためにルーティングされた後にトリガーされます。NF_IP_FORWARD: このフックは、受信したパケットがルーティングされた後にトリガーされます。パケットが別のホストに転送される場合に適用されます。NF_IP_LOCAL_OUT: このフックは、ローカルに作成されたアウトバウンドトラフィックがネットワークスタックに到達するとすぐにトリガーされます。NF_IP_POST_ROUTING: このフックは、ルーティングが行われた後、送信または転送されるトラフィックのいずれかによってトリガーされ、ワイヤーに送信される直前に発生します。
これらのフックで登録する必要のあるカーネルモジュールは、フックがトリガーされた時に呼び出される順序を決定するための優先順位番号も提供する必要があります。これにより、複数のモジュール(または同じモジュールの複数のインスタンス)が決定論的な順序で各フックに接続できる手段が提供されます。各モジュールは順番に呼び出され、処理後にパケットに対して何をすべきかを示す決定をnetfilterフレームワークに返します。
IPTables テーブルとチェーン
iptablesファイアウォールは、そのルールを整理するためにテーブルを使用します。これらのテーブルは、ルールが使用される意思決定の種類に基づいて分類されます。たとえば、ルールがネットワークアドレス変換に関係する場合、それはnatテーブルに入れられます。パケットがその宛先に進むことを許可するかどうかを決定するためにルールが使用される場合、それはおそらくfilterテーブルに追加されるでしょう。
iptablesの各テーブル内では、ルールはさらに別の「チェーン」に整理されます。テーブルは保持するルールの一般的な目的によって定義されますが、組み込みのチェーンはそれらをトリガーするnetfilterフックを表します。チェーンはルールが評価されるタイミングを決定します。
組み込みチェーンの名前は、それに関連するnetfilterフックの名前を反映しています:
PREROUTING:NF_IP_PRE_ROUTINGフックによってトリガーされます。INPUT:NF_IP_LOCAL_INフックによってトリガーされました。FORWARD:NF_IP_FORWARDフックによってトリガーされました。OUTPUT:NF_IP_LOCAL_OUTフックによってトリガーされました。POSTROUTING:NF_IP_POST_ROUTINGフックによってトリガーされます。
チェーンは、管理者がパケットの配信経路のどこでルールを評価するかを制御できるようにします。各テーブルには複数のチェーンがあるため、テーブルの影響は処理の複数のポイントで行使される可能性があります。特定のタイプの決定はネットワークスタックの特定のポイントでのみ意味を持つため、すべてのテーブルがすべてのカーネルフックに登録されたチェーンを持っているわけではありません。
ネットフィルタのカーネルフックは5つしかないため、複数のテーブルからのチェーンが各フックに登録されます。たとえば、3つのテーブルにはPREROUTINGチェーンがあります。これらのチェーンが関連するNF_IP_PRE_ROUTINGフックに登録されると、各テーブルのPREROUTINGチェーンが呼び出される順序を規定する優先度を指定します。最も高い優先度のPREROUTINGチェーン内のルールは、次のPREROUTINGチェーンに移る前に順次評価されます。それぞれのチェーンの具体的な順序については、すぐに見ていきます。
どのテーブルが利用可能ですか?
少し立ち止まって、iptables が提供するさまざまなテーブルを見てみましょう。これらは、パケットを評価するための関心のある領域ごとに整理された、異なるルールのセットを表しています。
フィルターテーブル
フィルターテーブルは、iptablesで最も広く使用されているテーブルの1つです。フィルターテーブルは、パケットがその目的地へ進むのを許可するか、リクエストを拒否するかの判断を行うために使用されます。ファイアウォールの用語で言うと、これは「パケットをフィルタリングする」として知られています。このテーブルは、人々がファイアウォールについて話すときに考える主要な機能を提供します。
NATテーブル
nat テーブルは、ネットワークアドレス変換ルールを実装するために使用されます。パケットがネットワークスタックに入ると、このテーブルのルールによって、パケットの送信元または宛先アドレスをどのように変更するか、または変更しないかが決定され、パケットとその応答トラフィックがルーティングされる方法に影響を与えます。これは、直接アクセスが不可能な場合にパケットをネットワークにルーティングするために頻繁に使用されます。
ザ・マンブルテーブル
このmangleテーブルは、パケットのIPヘッダーをさまざまな方法で変更するために使用されます。例えば、パケットのTTL(生存時間)値を調整することができ、パケットが耐えられる有効なネットワークホップの数を長くしたり短くしたりできます。他のIPヘッダーも同様の方法で変更できます。
このテーブルは、他のテーブルや他のネットワークツールによるさらなる処理のために、パケットに内部カーネル「マーク」を付加することもできます。このマークは実際のパケットに触れることはなく、パケットのカーネルによる表現にマークを追加します。
生のテーブル
iptablesファイアウォールはステートフルであり、パケットが以前のパケットとの関係に基づいて評価されることを意味します。netfilterフレームワークの上に構築された接続追跡機能により、iptablesはパケットを無関係な離散パケットのストリームではなく、進行中の接続またはセッションの一部として見ることができます。接続追跡ロジックは、パケットがネットワークインターフェースに到達した後、非常に早い段階で適用されることが通常です。
rawテーブルは、非常に狭く定義された機能を持っています。その唯一の目的は、接続トラッキングをオプトアウトするためにパケットにマークを付けるメカニズムを提供することです。
セキュリティテーブル
セキュリティテーブルは、パケットに内部SELinuxセキュリティコンテキストマークを設定するために使用され、これによりSELinuxやSELinuxセキュリティコンテキストを解釈できる他のシステムがパケットをどのように処理するかに影響します。これらのマークは、パケットごとまたは接続ごとに適用できます。
チェーンとテーブルの関係
三つのテーブルにPREROUTINGチェーンがある場合、それらはどの順序で評価されますか?
以下の表は、左から右に読んだときに各iptablesテーブル内で使用可能なチェーンを示しています。例えば、rawテーブルにはPREROUTINGとOUTPUTの両方のチェーンがあることがわかります。また、上から下に読んだ場合、関連するnetfilterフックがトリガーされたときに各チェーンが呼び出される順序も表示されています。
いくつかの点に留意する必要があります。以下の表では、natテーブルが、パケットの宛先アドレスを変更するDNAT操作と、ソースアドレスを変更するSNAT操作に分割されており、彼らの順序をより明確に表示しています。また、ルーティング決定が行われるポイントや接続追跡が有効になるポイントを示す行も含めており、行われているプロセスの全体的な視点を提供しています。
| テーブル↓/チェーン→ | PREROUTING | 入力 | 前進 | 出力 | ポストルーティング |
|---|---|---|---|---|---|
| (ルーティング決定) | ✓ | ||||
| 生 | ✓ | ✓ | |||
| (接続追跡が有効) | ✓ | ✓ | |||
| マングル | ✓ | ✓ | ✓ | ✓ | ✓ |
| nat (DNAT) | ✓ | ✓ | |||
| (ルーティング決定) | ✓ | ✓ | |||
| フィルター | ✓ | ✓ | ✓ | ||
| 安全 | ✓ | ✓ | ✓ | ||
| nat (SNAT) | ✓ | ✓ |
パケットがnetfilterフックをトリガーすると、関連するチェーンは上記の表でリストされた通りに、上から下へと処理されます。パケットがトリガーするフック(列)は、受信パケットか送信パケットか、下されるルーティングの決定、およびパケットがフィルタリング基準を通過するかどうかによって異なります。
特定のイベントが発生すると、処理中にテーブルのチェーンがスキップされます。例えば、接続内の最初のパケットのみがNATルールに基づいて評価されます。最初のパケットに対して行われたnatの決定は、その後の接続内のすべてのパケットに追加の評価なしで適用されます。NATされた接続に対する応答には、自動的に正しくルートするために逆NATルールが適用されます。
チェーントラバーサル順序
サーバーがパケットをルーティングする方法を知っていて、ファイアウォールのルールがその送信を許可していると仮定すると、以下のフローは異なる状況で通過するパスを示しています:
- ローカルシステムに向けての受信パケット:
PREROUTING->INPUT - 別のホストに到着するパケット:
PREROUTING->FORWARD->POSTROUTING - ローカルに生成されたパケット:
OUTPUT->POSTROUTING
上記の情報を前の表に示された順序と組み合わせると、ローカルシステムに送信される着信パケットが最初にraw、mangle、およびnatテーブルのPREROUTINGチェーンに対して評価されることがわかります。その後、mangle、filter、security、およびnatテーブルのINPUTチェーンを通過し、最後にローカルソケットに配信されます。
IPTables ルール
ルールは特定のテーブルの特定のチェーン内に配置されています。各チェーンが呼び出されると、対象のパケットはチェーン内の各ルールに対して順番にチェックされます。各ルールには、一致するコンポーネントとアクションコンポーネントがあります。
マッチング
ルールの一致部分は、関連するアクション(または「ターゲット」)が実行されるためにパケットが満たす必要のある基準を指定します。
マッチングシステムは非常に柔軟であり、追加の iptables 拡張機能を使って大幅に拡張可能です。ルールは、プロトコルタイプ、宛先または送信元アドレス、宛先または送信元ポート、宛先または送信元ネットワーク、入力または出力インターフェース、ヘッダー、接続状態などの基準に基づいて構築できます。これらは組み合わせて、異なるトラフィックを区別するための複雑なルールセットを作成できます。
ターゲット
「ターゲット」とは、パケットがルールの一致基準を満たしたときにトリガーされるアクションを指します。ターゲットは一般的に2つのカテゴリに分けられます:
- ターゲットの終了: ターゲットの終了は、チェーン内の評価を終了させるアクションを実行し、制御を
netfilterフックに戻します。提供された戻り値に応じて、フックはパケットをドロップするか、パケットが処理の次の段階に進むことを許可します。 - 非終了ターゲット: 非終了ターゲットはアクションを実行し、チェーン内の評価を続行します。各チェーンは最終的に終了する決定を返さなければなりませんが、任意の数の非終了ターゲットを事前に実行することができます。
ルール内の各ターゲットの利用可能性は、文脈によって異なります。たとえば、テーブルとチェーンタイプが利用可能なターゲットを決定する場合があります。また、ルールでアクティブになっている拡張機能や一致する条項もターゲットの利用可能性に影響を与えることがあります。
ユーザー定義チェーンへのジャンプ
終了しないターゲットの特別なクラスとして、ジャンプターゲットもあります。ジャンプターゲットは、評価が追加処理のために別のチェーンに移動することを結果とするアクションです。私たちは、呼び出すnetfilterフックに関連付けられた組み込みチェーンについて説明しました。しかし、iptablesは、管理者が組織化の目的で独自のチェーンを作成することも許可しています。
ルールは、組み込みのチェーンに配置できるのと同じ方法で、ユーザー定義のチェーンにも配置できます。違いは、ユーザー定義のチェーンはルールから「ジャンプ」してのみアクセスできることです(それ自体はnetfilterフックには登録されません)。
ユーザー定義のチェーンは、それらを呼び出したチェーンの拡張として機能します。たとえば、ユーザー定義のチェーンでは、ルールリストの最後に達した場合や、一致するルールによって RETURN ターゲットがアクティブ化された場合に評価が呼び出しているチェーンに戻ります。また、評価は追加のユーザー定義チェーンにジャンプすることもできます。
この構造は、より高い組織化を可能にし、より強力な分岐のために必要な枠組みを提供します。
IPTablesと接続追跡
私たちは、raw テーブルと接続状態マッチング基準について議論した際に、netfilter フレームワークの上に実装された接続追跡システムを紹介しました。接続追跡は、iptables が進行中の接続の文脈で見たパケットに基づいて決定を下すことを可能にします。接続追跡システムは、iptables に「ステートフル」な操作を実行するために必要な機能を提供します。
接続トラッキングは、パケットがネットワークスタックに入った後すぐに適用されます。raw テーブルチェーンといくつかの基本的なチェックのみが、パケットを接続に関連付ける前にパケットに対して実行されるロジックです。
システムは各パケットを既存の接続のセットと照合します。必要に応じて、接続の状態をストア内で更新し、必要な場合には新しい接続をシステムに追加します。一つの raw チェーンで NOTRACK ターゲットとしてマークされたパケットは、接続追跡ルーチンをバイパスします。
利用可能な州
接続追跡システムによって追跡される接続は、以下のいずれかの状態になります:
- パケットが到着し、既存の接続に関連付けられていないが、最初のパケットとして無効ではない場合、新しい接続がこのラベルでシステムに追加されます。これは、TCPのような接続指向プロトコルと、UDPのような接続レスプロトコルの両方に該当します。
ESTABLISHED: 接続は、反対方向からの有効な応答を受信したときに、NEWからESTABLISHEDに変更されます。TCP接続では、これはSYN/ACKを意味し、UDPおよびICMPトラフィックでは、これは元のパケットの送信元と宛先が入れ替わった応答を意味します。RELATED: 既存の接続の一部ではないが、システム内の既存の接続に関連するパケットは、RELATEDとラベル付けされます。これは、FTPデータ転送接続のようなヘルパー接続を意味するか、または他のプロトコルによる接続試行に対するICMPレスポンスである可能性があります。INVALID: パケットは、既存の接続に関連付けられておらず、新しい接続を開くのに適していない場合、識別できない場合、または他の理由のために送信できない場合にINVALIDとしてマークされることがあります。UNTRACKED: パケットは、追跡を回避するために、rawテーブルチェーンでターゲットにされた場合、UNTRACKEDとしてマークすることができます。SNAT: これは、NAT操作によって送信元アドレスが変更されたときに設定される仮想状態です。これは接続トラッキングシステムによって使用され、応答パケットの送信元アドレスを元に戻すことを知るために使用されます。DNAT: これは、宛先アドレスがNAT操作によって変更されたときに設定される仮想状態です。接続トラッキングシステムによって使用され、応答パケットのルーティング時に宛先アドレスを元に戻す必要があることを知るために使用されます。
接続追跡システムで追跡される状態は、管理者が接続の寿命の特定のポイントをターゲットにしたルールを作成できるようにします。これにより、より徹底的で安全なルールを作成するために必要な機能が提供されます。
結論
netfilter パケットフィルタリングフレームワークと iptables ファイアウォールは、Linuxサーバー上のほとんどのファイアウォールソリューションの基盤です。 netfilter カーネルフックは、ネットワークスタックに非常に近いため、システムによってパケットが処理される際に強力な制御を提供します。 iptables ファイアウォールは、これらの機能を活用して、ポリシー要件をカーネルに通信するための柔軟で拡張可能な方法を提供します。 これらの要素がどのように組み合わさるかを学ぶことで、サーバー環境を制御し、安全に保つためにそれらをより良く活用することができます。
効果的なiptablesポリシーを選択する方法についてさらに知りたい場合は、このガイドを確認してください。
これらのガイドは、iptablesファイアウォールルールの実装を始めるのに役立ちます:
- iptablesを使用してファイアウォールを設定する方法
- iptablesの基本: 一般的なファイアウォールルールとコマンド
- Ubuntu 22.04でUFWを使ってファイアウォールを設定する方法
- Rocky Linux 8でfirewalldを使用してファイアウォールを設定する方法
- サーバー間のトラフィックを保護するためにIptablesファイアウォールを設定する方法
