Product SiteDocumentation Site

14.2. ファイアウォールとパケットフィルタリング

ファイアウォールはネットワークゲートウェイをフィルタするもので、ゲートウェイを通過しなければいけないパケットだけに有効です。それ故、フィルタしたいパケットをファイアウォール以外の経路で宛先に配送することが可能な場合、ファイアウォールは無意味です。
標準的な設定が存在しないということは (そして「過程であって、成果ではない」モットーに従うということは) ややこしい初期設定の不要な解決策が存在しないということを意味します。しかしながら、netfilter ファイアウォールの設定を簡単に行うためのツールが存在し、ツールはフィルタリングルールをグラフィカルに表現する機能を備えています。fwbuilder がこの種のツールの中で最良のツールであることは疑いありません。
Linux カーネルには netfilter ファイアウォールが組み込まれています。iptablesip6tables コマンドを使うことで、netfilter ファイアウォールをユーザ空間から制御することが可能です。iptablesip6tables コマンドの違いは、iptables が IPv4 ネットワークを取り扱うのに対し、ip6tables は IPv6 ネットワークを取り扱うという点です。おそらく IPv4 と IPv6 のネットワークプロトコルスタックは長きにわたり共存するでしょうから、両方のツールを並行して実行する必要があります。

14.2.1. netfilter の挙動

netfilter は以下に示す 4 種類の異なるテーブルを使います。テーブルには、パケットに対する 3 種類の操作を規制するためのルールを保存します。
  • filter。フィルタリングルール (パケットを受け入れる、拒否する、無視するなど) に関係します。
  • nat。パケットの送信元や宛先アドレスおよびポート番号の変換に関係します。
  • mangle。IP パケットに対するその他の変換に関係します (ToS すなわち Type of Service フィールドやオプションの変換も含まれます)。
  • raw。パケットが接続追跡システムに到達する前にパケットを手作業で別の変更を加えることが可能です。
それぞれのテーブルには、チェインと呼ばれるルールのリストが含まれます。ファイアウォールは事前に定義された状況に基づいてパケットを取り扱うために標準的なチェインを使います。管理者は他のチェインを作成することが可能です。このチェインを使うには、標準的なチェインの 1 つから (直接的か間接的かのいずれか一方の方法で) このチェインを参照します。
filter テーブルは以下に示す 3 種類の標準的なチェインを備えています。
  • INPUT。宛先がファイアウォール自身のパケットに関係します。
  • OUTPUT。ファイアウォールから送信されたパケットに関係します。
  • FORWARD。ファイアウォールを通過するパケット (送信元や宛先がファイアウォールでないパケット) に関係します。
nat テーブルは以下に示す 3 種類の標準的なチェインを備えています。
  • PREROUTING。パケットの到着直後にパケットを修正します。
  • POSTROUTING。パケットを宛先に送信する準備が完了した時にパケットを修正します。
  • OUTPUT。ファイアウォールそれ自身によって生成されたパケットを修正します。
netfilter チェインの呼び出される方法

図 14.1 netfilter チェインの呼び出される方法

各チェインはルールのリストです。そして各ルールは一連の条件とその条件に一致する場合に実行される動作です。パケットを処理する場合、ファイアウォールは適切なチェインを 1 つずつ検査します。そしてあるルールの条件に一致したら、処理を続けるために特定の動作に「ジャンプ」します (このためコマンドには -j オプションが存在します)。最も一般的な挙動は標準化されており、それぞれの挙動に対する専用の動作が存在します。以下に示す標準的な動作が選択されると、チェインの処理は中止されます。なぜなら、パケットの運命は既に決まっているからです (以下で言及されている除外に一致する場合を除きます)。
  • ACCEPT。対象のパケットの通過を許可します。
  • REJECT。対象のパケットを拒否して ICMP エラーを返答します (iptables--reject-with type オプションを使えば返答するエラーの種類を選ぶことが可能です)。
  • DROP。対象のパケットを削除 (無視) します。
  • LOG。(syslogd を使って) 対象のパケットの説明とメッセージをログに記録します。ログ記録が選択された場合、チェインの処理は中止されず続行されて次のルールに進む点に注意してください。このため、拒否されたパケットをログに記録するには LOG と REJECT/DROP ルールの両方が必要です。
  • ULOGulogd を介してメッセージをログに記録します。ulogd は大量のメッセージを処理する場合に syslogd よりも効率が良いです。LOG と同様、この場合も処理は呼び出されたチェインの次のルールに進む点に注意してください。
  • chain_name。指定したチェインに飛んで、そのチェインのルールを評価します。
  • RETURN。現在のチェインの処理を中止し、呼び出し元のチェインに戻ります。現在のチェインが標準的なチェインの場合、呼び出し元のチェインは存在しませんから、代わりにデフォルト動作 (iptables-P オプションで定義された動作) が実行されます。
  • SNAT (nat テーブルの中だけでのみ使うことが可能です)。Source NAT を適用します (追加オプションを使って適用する正確な変更を設定します)。
  • DNAT (nat テーブルの中だけでのみ使うことが可能です)。Destination NAT を適用します (追加オプションを使って適用する正確な変更を設定します)。
  • MASQUERADE (nat テーブルの中だけでのみ使うことが可能です)。マスカレードを適用します (マスカレードSource NAT の特別な場合です)。
  • REDIRECT (nat テーブルの中だけでのみ使うことが可能です)。ファイアウォールの指定したポートに対象のパケットを転送します。さらにこれを使って、クライアント側に特別な設定をせずとも動作する透過的なウェブプロキシをセットアップすることが可能です。なぜなら、クライアントは宛先に接続していると思っていても、実際の通信はプロキシを通過しているからです。
その他の動作 (特に mangle テーブルに関する動作) は本書の範囲を超えています。iptables(8)ip6tables(8) には包括的なリストが含まれています。

14.2.2. iptablesip6tables の構文

iptablesip6tables コマンドを使って、テーブル、チェイン、ルールを操作することが可能です。-t table オプションで操作対象のテーブルを指定します (デフォルトの場合、filter テーブルを操作します)。

14.2.2.1. コマンド

-N chain オプションは新しいチェインを作成します。-X chain は空で使われていないチェインを削除します。-A chain rule はチェインの最後にルールを追加します。-I chain rule_num rule オプションは指定したルール番号 rule_num の前にルールを挿入します。-D chain rule_num (または -D chain rule) オプションはチェインからルールを削除します。ここで rule_num を使う構文はルール番号を指定してルールを削除し、rule を使う構文はルール内容を指定してルールを削除します。-F chain オプションはチェインをクリアします (チェインに含まれるすべてのルールを削除します)。ここでチェインを指定しなかった場合、テーブルに含まれるすべてのルールを削除します。-L chain オプションはチェインに含まれるルールを表示します。最後に、-P chain action オプションは指定したチェインのデフォルト動作を意味する「ポリシー」を定義します。ここでポリシーを設定できるのは標準的なチェインだけという点に注意してください。

14.2.2.2. ルール

それぞれのルールは conditions -j action action_options の形で指定します。1 つのルールに複数の条件を指定する場合、複数の条件は結合 (論理 and) されます。つまり、各条件の結果をさらに限定することを意味します。
-p protocol は指定されたプロトコルフィールドに一致する IP パケットを選択する条件です。protocol で最もよく使われる値は tcpudpicmpicmpv6 です。この条件の前に感嘆符を付けることで、この条件を否定することになります。つまり「protocol で指定されたプロトコル以外のすべてのプロトコルを使ったパケット」を選択する条件になります。条件否定の方法は -p オプションに限らず、以降で紹介する他のすべての条件にも適用することが可能です。
-s address または -s network/mask は指定された送信元アドレスに一致するパケットを選択する条件です。同様に、-d address または -d network/mask は指定された宛先アドレスに一致するパケットを選択する条件です。
-i interface は指定されたネットワークインターフェースを通じて受信したパケットを選択する条件です。-o interface は指定されたインターフェースを通じて送信されるパケットを選択する条件です。
上で説明した一般的な条件ごとに、さらに条件の範囲を狭めるためのオプションが数多く存在します。たとえば -p tcp 条件に加えて TCP ポート番号を指定することで、選択するパケットをさらに絞り込むことが可能です。これを行うには、--source-port port--destination-port port を使います。
--state state は指定されたパケット状態に一致するパケットを選択する条件です (接続追跡を行うための ipt_conntrack カーネルモジュールが必要です)。NEW 状態は新しい接続を開始するパケット、ESTABLISHED 状態は既に存在する接続に関連するパケットを意味します。RELATED 状態は既存の接続に関連した新しい接続を開始するパケットを意味します (これは FTP プロトコルの「アクティブ」モードを使った ftp-data 接続の際に有益です)。
前節では利用できる標準的な動作を説明しましたが、その動作に対するオプションを説明していませんでした。たとえば、LOG 動作は以下のオプションを取ることが可能です。
  • --log-level は記録する syslog メッセージの重要度を指定します。デフォルトの場合 warning 以上の重要度を持つメッセージが記録されます。
  • --log-prefix はログに記録するメッセージを特徴づけるために行の先頭に付けるテキストを指定します。
  • --log-tcp-sequence--log-tcp-options--log-ip-options はログメッセージに含める追加的なデータを指定します。具体的に言えば、それぞれ TCP シーケンス番号、TCP オプション、IP オプションをログメッセージに含めます。
DNAT 動作は以下のオプションを取ることが可能です。--to-destination address:port は新しい宛先 IP アドレスおよびポート番号を指定します。同様に、SNAT 動作は以下のオプションを取ることが可能です。--to-source address:port は新しい送信元 IP アドレスおよびポート番号を指定します。
REDIRECT 動作は以下のオプションを取ることが可能です。--to-ports port(s) はパケットの転送先ポート番号またはポート番号範囲を指定します (REDIRECT 動作は NAT を有効化している場合にのみ使うことが可能です)。

14.2.3. ルールの作成

1 つのルールを作成するには、iptables/ip6tables を 1 回実行する必要があります。これらのコマンドを手作業で実行することは退屈なので、通常スクリプトの形で保存しておきます。こうすることで、マシンの起動時に同じ設定を自動的に適用することが可能です。このスクリプトは手作業で書かなければいけませんが、fwbuilder などの高レベルツールを使ってスクリプトを準備しても良いでしょう。
# apt install fwbuilder
fwbuilder の原理は簡単です。最初に、以下のような実際のルールに関連するすべての要素を宣言する必要があります。
  • ネットワークインターフェースとそれを使うファイアウォール自身。
  • 対応する IP アドレス範囲とそれを使うネットワーク。
  • サーバ。
  • サーバでホストされているサービスに対応するポート番号。
これらの要素に対する単純なドラッグアンドドロップ動作を使ってルールを作成します。いくつかのコンテキストメニューを使ってルールの条件を変更する (たとえば条件を否定する) ことが可能です。その後、動作を選んで設定する必要があります。
IPv6 に関心があるなら、IPv4 と IPv6 で別々のルールセットを作成するか、片方のルールセットだけを作成して要素に割り当てられたアドレスに応じて fwbuilder にそのルールを変換してもらうかのどちらか一方を行うことが可能です。
fwbuilder のメインウィンドウ

図 14.2 fwbuilder のメインウィンドウ

これで fwbuilder は定義されたルールに従ってファイアウォールを設定するためのスクリプトを生成することが可能になりました。モジュール式のアーキテクチャのおかげで、fwbuilder はさまざまなファイアウォールシステム (Linux の iptables、FreeBSD の ipf、OpenBSD の pf) を設定するためのスクリプトを生成することが可能です。

14.2.4. 起動時にルールを適用する

設定スクリプトを /etc/network/interfaces ファイルの up 指示文に登録する方法を推奨します。以下の例では、設定スクリプトは /usr/local/etc/arrakis.fw に保存されています。

例 14.1 ファイアウォールスクリプトを呼び出す interfaces ファイル

auto eth0
iface eth0 inet static
    address 192.168.0.1
    network 192.168.0.0
    netmask 255.255.255.0
    broadcast 192.168.0.255
    up /usr/local/etc/arrakis.fw
見ての通りこの例ではネットワークインターフェースを設定するために ifupdown を使っています。他の方法 (たとえば NetworkManagersystemd-networkd など) を使ってネットワークインターフェースを設定している場合、それぞれの文書を参照して、インターフェースを起動した後にスクリプトを実行する方法を見つけてください。