FreeBSD ハンドブック
Prev | Chapter 14. セキュリティ | Next

# 14.7. ファイアウォール

寄稿: Gary Palmer and Alex Nash.

訳: 佐伯 隆司 `<saeki@jp.FreeBSD.org>`. 11 November 1996.

ファイアウォールは、 インターネットに参加している人はもちろんのこと、 プライベートネットワークのセキュリティ向上のための アプリケーションを 探している人にとっても、 ますます興味深くなりつつある分野です。 このセクションではファイアウォールとは何か、 ファイアウォールの使用法、 そしてファイアウォールを構築するために FreeBSD のカーネルで 提供されているファシリティ (機能) の使用法について説明したいと思います。

> Note: 社内のネットワークと “巨大かつ信頼のおけない インターネット”との間にファイアウォールを構築することで セキュリティ上のすべての問題が解決できると考える人がいます。 ファイアウォールはセキュリティ上の問題を 解決する助けになる場合もありますが、 充分な設定がなされていないファイアウォールは、 まったくファイアウォールを 持たない場合よりもセキュリティ上の危険を増大させてしまいます。 ファイアウォールにできることは、 あなたのシステムにもう一つのセキュリティ層を 追加することだけで、 本気でアタックをしかけてくるクラッカーが内部ネットワークに 侵入するのを妨げることはできません。 ファイアウォールを侵入不可能と過信して 内部のセキュリティをおろそかにすることは、 単にクラッカーの仕事を少し簡単にするだけでしか ありません。

## 14.7.1. ファイアウォールとは何か ?

現在インターネットで普通に使用されている ファイアウォールには 二つの異なるタイプがあります。一つは、 厳密には パケットフィルタリングルータ と 呼ばれるタイプのものです。これはマルチホームのホストマシン (複数の ネットワークに接続されているマシン) のカーネルが、 ある規則にしたがって パケットを転送したりブロックしたりするものです。もう一つは、 proxy (代理) サーバ として知られているタイプのものです。これは、 おそらくはマルチホームのホストマシン上で、 カーネルによるパケット転送を 禁止して、 デーモンにより認証の提供とパケットの転送とを おこなうものです。

二つのタイプのファイアウォールを組み合わせて使用して、 特定のマシン (要塞ホスト と呼ばれる) だけが パケットフィルタリングルータを通して内部ネットワークへ パケットを送ることができるよう設定している サイトがしばしば存在します。proxy (代理) サービスは通常の認証機構よりもセキュリティを 強化してある 要塞ホストで動作させます。

FreeBSD は (IPFW として知られる) カーネルパケットフィルタ込みで 提供されています。このセクションの後の方では、 このフィルタについての 説明を集中しておこないます。 サードパーティから提供されるソフトウェアを使用することにより、 Proxy サーバを FreeBSD 上に構築することができます。しかし、 現在入手可能な proxy サーバは たいへんバラエティに富んでいるので、 この節でそれらすべてをカバーすることはできないでしょう。

### 14.7.1.1. パケットフィルタリングルータ

ルータとは、二つまたはそれ以上のネットワークの間で パケットの転送をおこなう マシンのことです。 パケットフィルタリングルータは、そのカーネルの内部に、 一つ一つのパケットをルールリストと比較して 転送するかしないかを決める 特別なコードを持っています。 最近の IP ルーティングソフトウェアのほとんどは、内部に パケットのフィルタリングをおこなうためのコードを持っていて、 デフォルトでは すべてのパケットを転送するようになっています。 このフィルタを有効にするためには、 パケットの通過を許すべきかどうかを決める ルールを自分で定義する必要があります。

パケットを通すべきか通すべきでないかを決めるために、 パケットヘッダの内容にマッチするものが ルールリストから探されます。マッチするルールが見つかると、 ルールアクションが実行されます。ルールアクションには、 パケットを捨てる、パケットを転送する、 またはパケットの発信元に ICMP メッセージを送り返すというものがあります。 ルールの検索は先頭から順番におこなわれ、 通常は最初にマッチしたものだけが 適用されます。そのため、 このルールリストは“ルールチェーン” と呼ばれることもあります。

パケットマッチングの基準は使用するソフトウェアに よって異なりますが、通常はパケットの発信元 IP アドレス、 宛先 IP アドレス、発信元ポート番号、宛先ポート番号 (ポート番号はポートをサポートするプロトコルの場合のみ)、 パケットタイプ (UDP, TCP, ICMP など) に基づくルールを指定することができます。

### 14.7.1.2. Proxy サーバ

Proxy サーバとは通常のシステムデーモン (telnetd, ftpd など) を 特別なサーバで置き換えたマシンのことです。 これらのサーバは、 通常は中継をおこなって特定方向への接続だけを許すため、 proxy サーバ と呼ばれます。(たとえば) proxy telnet サーバをファイアウォールホストで走らせておきます。 外部からユーザがファイアウォールに対して telnet を実行すると、proxy telnet サーバが応答して、 何らかの認証機構を実行します。これを通過した後で、 内部ネットワークへのアクセスがおこなえるように なるのです。 (内部ネットワークからの信号は proxy サーバがかわりに受け取り、外へ向けて送り出します)。

Proxy サーバは通常、 普通のサーバより堅固に構築されていて、しばしば “使い捨て”パスワードシステムなどを含む、 多様な認証機構を持っています。 “使い捨て”パスワードシステムとは、 どういうものなのでしょうか。仮に誰かが何らかの方法で、 あなたが使用したパスワードを手に入れたとします。しかし、 一度使用したことで、 そのパスワードは既に無効になっているのです。ですから、 そのパスワードをもう一度使用したとしても、あなたのシステムへ アクセスすることはできないというわけです。 これらのサーバは中継をおこなうだけで、 実際のところサーバホスト自身への アクセスをユーザに許してはいません。そのため、 何者かがセキュリティシステムに 侵入用の裏口を取り付けることは、 より困難になっています。

proxy サーバはアクセス制限の方法をいくつも持っていて、 特定のホスト だけがサーバへのアクセス権を得ることができるように なっていることがあります。 そして目的のマシンと通信できるユーザを制限するように 設定することもできます。もう一度言いますが、 どんなファシリティ (機能) が使えるかは、どんな proxy サービスをおこなうソフトウェアを選ぶかに大きく 依存します。

## 14.7.2. IPFW で何ができるか

FreeBSD とともに配布されている `IPFW` は、カーネル内部にあって パケットのフィルタリングとアカウンティングを おこなうシステムであり、 ユーザ側のコントロールユーティリティである ipfw(8) を 含んでいます。ルーティングの決定をおこなう際に、 これらは互いに協力して、 カーネルで使用されるルールを定義したり、 現在使用されているルールを 問い合わせたりすることができます。

IPFW は互いに関連する二つの部分からなっています。 ファイアウォールセクションは パケットフィルタリングをおこないます。また、IP アカウンティングセクションはファイアウォールセクションのものと 似たルールに基づいてルータの使用を追跡します。これにより、 (たとえば) 特定のマシンからルータへのトラフィックがどのくらい 発生しているか調べたり、どれだけの WWW (World Wide Web) トラフィックが フォワードされているかを知ることができます。

IPFW は、 ルータではないマシンにおいても入出力コネクションの パケットフィルタリングのために 使用することができるように設計されています。これは一般的な IPFW の使用法とは異なる特別な使い方ですが、 こういった状況でも同じコマンドと テクニックが使用されます。

## 14.7.3. FreeBSD で IPFW を有効にする

IPFW システムの中心となる部分はカーネル内部にあります。そのため、 どのファシリティ (機能) を必要とするかによって、一つまたは それ以上のオプションをカーネルコンフィグレーション ファイルに追加し、 カーネルを再コンパイルする必要があるでしょう。 カーネルの再コンパイル方法の詳細については、カーネルコンフィグレーション を参照してください。

現在、IPFW に関係するカーネルコンフィグレーションオプションは 三つあります。

`options IPFIREWALL`

  パケットフィルタリングのためのコードを カーネルに組み込みます。

`options IPFIREWALL_VERBOSE`

  syslogd(8) を通じて パケットのログを取るためのコードを有効にします。 フィルタルールでパケットのログを取るように指定しても、 このオプションが指定されていなければ、 ログを取ることはできません。

`options IPFIREWALL_VERBOSE_LIMIT=10`

  syslogd(8) を通じて ログを取るパケットの数をエントリ毎に制限します。 敵対的な環境においてファイアウォールの 動作のログを取りたいけれど、 syslog の洪水によるサービス拒絶攻撃に対し 無防備でありたくないという場合に、 このオプションを使用したいと思うことが あるかもしれません。

  チェーンエントリのログが指定された制限数に達すると、 そのエントリに関するログ取りは停止されます。 ログ取りを再開するには、ipfw(8) ユーティリティを使用して 関連するカウンタをリセットする必要があります。

      # ipfw zero 4500

  4500 とは、 ログ取りを続行したいチェーンエントリの番号です。

> Note: 以前のバージョンの FreeBSD は `IPFIREWALL_ACCT` というオプションを 持っていました。しかし、 ファイアウォールコードがアカウンティングファシリティ (機能) を 自動的に含むようになったため、 現在では使用されることはなくなっています。

## 14.7.4. IPFW の設定

IPFW ソフトウェアの設定は ipfw(8) ユーティリティを 通じておこないます。このコマンドの構文は非常に 複雑に見えますが、 一旦その構造を理解すれば比較的単純です。

このユーティリティでは今のところ四つの異なる コマンドカテゴリが 使用されています: それは追加 / 削除、表示、 フラッシュ、およびクリアです。追加 / 削除はパケットの受け入れ、拒絶、ログ取りをどのようにおこなうか というルールを構築するのに使用します。表示はルールリスト (またはチェーン) と (アカウンティング用) パケットカウンタの 内容を調べるのに使用します。 フラッシュはチェーンからすべてのエントリを 取り除くのに使用します。 クリアは一つまたはそれ以上のアカウンティングエントリを ゼロにするのに 使用します。

### 14.7.4.1. IPFW ルールの変更

この形式での使用法は:

`ipfw` [-N] コマンド [index] アクション [log] プロトコル アドレス [オプション]

この形式で使用する際に有効なフラグは一つだけです。

-N

  アドレスやサービス名を 文字列に変換して表示します。

コマンド は一意である限り短縮可能です。有効な コマンド は

add

  ファイアウォール / アカウンティングルールリストに エントリを追加します。

delete

  ファイアウォール / アカウンティングルールリストから エントリを削除します。

以前のバージョンの IPFW では、 ファイアウォールエントリと パケットアカウンティングエントリが別々に利用されていました。 現在のバージョンでは、それぞれのファイアウォールエントリ毎に パケットアカウンティングエントリが備えられています。

index 値が指定されていると、 エントリはチェーン中の指示された位置に置かれます。 index 値が指定されて いなければ、 エントリは (65535 番のデフォルトルールである パケット拒絶を別にして) 最後のチェーンエントリの index に 100 を足した 位置 (チェーンの最後) に置かれます。

カーネルが `IPFIREWALL_VERBOSE` つきでコンパイルされている場合、`log` オプションはマッチしたルールを システムコンソールに出力させます。

有効な アクション は:

reject

  パケットを捨てます。ICMP ホスト / ポート到達不能パケットを (適切な方を) 発信元へ送ります。

allow

  通常通りパケットを通過させます。(別名: `pass` および `accept`)

deny

  パケットを捨てます。発信元は ICMP メッセージによる 通知を受けません (そのためパケットが 宛先に到達しなかったように見えます)。

count

  このルールはパケットカウンタを更新するだけで、 パケットを 通過させたり拒絶したりしません。 検索は次のチェーンエントリから続けられます。

それぞれの アクション は一意な先頭部分だけでも認識されます。

指定可能な プロトコル は以下の通りです。

all

  任意の IP パケットにマッチします。

icmp

  ICMP パケットにマッチします。

tcp

  TCP パケットにマッチします。

udp

  UDP パケットにマッチします。

アドレス の指定は:

from `address/mask` [`port`] to `address/mask` [`port`] [via `interface`]

`port` はポートをサポートする プロトコル (UDP と TCP) の 場合にだけ指定可能です。

`via` は必須ではなく、 特定のインタフェースを通ってきたパケット だけにマッチするように、IP アドレスまたはローカル IP インタフェースの ドメイン名、またはインタフェース名 (たとえば `ed0`) を 指定することができます。 インタフェースユニット番号はオプションで、 ワイルドカードで指定することが できます。たとえば、 `ppp*` はすべてのカーネル PPP インタフェースに マッチします。

`address/mask` の指定は:

    address

または

    address/mask-bits

または

    address:mask-pattern

IP アドレスのかわりに有効なホスト名を指定することも可能です。 ``mask-bits`` はアドレスマスクで上位何ビットを１にするべきかを 示す十進数値です。たとえば次の指定、 `192.216.222.1/24` はクラス C のサブネット (この場合 192.216.222) の任意のアドレスにマッチする マスクを作成します。 ``mask-pattern`` は与えられたアドレスと 論理 AND される IP アドレスです。 キーワード `any` は“任意の IP アドレス”を指定するために 使用することができます。

ブロックするポート番号は以下のように指定します:

`port` [, `port` [, `port` [... ]]]

のように単独のポートまたはポートのリストを指定します。 または

`port`- `port`

のようにポートの範囲を指定します。 単独のポートとポートのリストを 組み合わせて指定することも可能ですが、 その場合は常に範囲の方を 最初に指定しなければなりません。

使用可能な オプション は:

frag

  データグラムの最初の フラグメントでなければマッチします。

in

  入力途中のパケットであればマッチします。

out

  出力途中のパケットであればマッチします。

ipoptions `spec`

  IP ヘッダが `spec` に指定された カンマで区切られた オプションのリストを含んでいればマッチします。 サポートされている IP オプションのリストは: `ssrr` (ストリクトソースルート)、 `lsrr` (ルーズソースルート)、 `rr` (レコードパケットルート)、 そして `ts` (タイムスタンプ) です。 特定のオプションを含まないことを指定するには `!` を先頭につけます。

established

  パケットが既に確立されている TCP コネクションの一部であれば (つまり RST または ACK ビットがセットされていれば) マッチします。 established ルールをチェーンの最初の方に置くことで、 ファイアウォールのパフォーマンスを向上させることが できます。

setup

  パケットが TCP コネクションを確立しようとするものであれば (SYN ビットがセットされ ACK ビットはセットされていなければ) マッチします。

tcpflags `flags`

  TCP ヘッダが `flags` に指定された カンマで区切られたフラグの リストを含んでいればマッチします。 サポートされているフラグは、`fin`, `syn`, `rst`, `psh`, `ack` と `urg` です。 特定のフラグを含まないことを指定するには `!` を先頭につけます。

icmptypes `types`

  ICMP タイプが `types` リストに 存在していればマッチします。 リストはタイプの範囲または個々のタイプを カンマで区切った任意の組合せで指定できます。 一般的に使用されている ICMP タイプは: `0` エコーリプライ (ping リプライ)、 `3` 相手先到達不可能、 `5` リダイレクト、 `8` エコーリクエスト (ping リクエスト)、そして `11` 時間超過 (traceroute(8) で使用されているように、TTL 満了を示すのに使用されます) です。

### 14.7.4.2. IPFW ルールリストの表示

この形式での使用法は:

`ipfw` [-a] [-t] [-N] l

この形式で使用する際に有効なフラグは三つあります。

-a

  リスト表示の際にカウンタの値も表示します。 このオプションは アカウンティングカウンタの 内容を見る唯一の手段です。

-t

  各チェーンエントリが最後に マッチした時刻を表示します。この時刻表示は ipfw(8) ユーティリティで使用される入力形式と 互換性がありません。

-N

  (可能であれば) アドレスやサービス名を文字列に変換して表示します。

### 14.7.4.3. IPFW ルールのフラッシュ

チェーンをフラッシュするには:

`ipfw` flush

カーネルに固定されているデフォルトルール (インデックス 65535 番) 以外の、 ファイアウォールチェーンの中のすべてのエントリを削除します。 デフォルトではすべてのパケットが拒絶されるので、 一旦これを実行すると、 パケットを許可するエントリがチェーンに追加されるまで、 あなたのシステムがネットワークから切り放されてしまいます。 そのため、 ルールのフラッシュをおこなうときは注意が必要です。

### 14.7.4.4. IPFW パケットカウンタのクリア

一つまたはそれ以上のパケットカウンタをクリアするためには:

`ipfw` zero [`index`]

`index` が指定されていなければ、 すべてのパケットカウンタが クリアされます。 `index` が指定されていれば、 特定のチェーンエントリだけが クリアされます。

## 14.7.5. ipfw に対するコマンドの例

このコマンドは、ホスト `evil.crackers.org` から ホスト `nice.people.org` の telnet ポートへの すべてのパケットを拒絶します。

    # ipfw add deny tcp from evil.crackers.org to nice.people.org 23

次の例は、ネットワーク `crackers.org` (クラス C) 全体から マシン `nice.people.org` (の任意のポート) への 任意の TCP トラフィックを拒絶し、 ログを取ります。

    # ipfw add deny log tcp from evil.crackers.org/24 to nice.people.org

あなたの内部ネットワーク (クラス C のサブネット) に対する X セッションを 張れないようにする場合、 以下のコマンドで必要なフィルタリングがおこなえます。

    # ipfw add deny tcp from any to my.org/28 6000 setup

アカウンティングレコードを見るには:

    # ipfw -a list

または短縮形式で

    # ipfw -a l

最後にチェーンエントリがマッチした 時刻を見ることもできます。

    # ipfw -at l

## 14.7.6. パケットフィルタリングファイアウォールの構築

> Note: 以下の提案は、ただの提案にすぎません: 必要な処理はそれぞれのファイアウォールで異なるため、 あなた独自の要求にあったファイアウォールを構築する方法を ここで述べることはできないのです。

最初にファイアウォールをセットアップするとき、 コントロールされた環境でファイアウォールホストの 設定がおこなえるような テストベンチセットアップが用意できない場合には、 カーネルのログ取りを 有効にしてログ取り版のコマンドを使用することを 強くおすすめします。そうすることで、 大した混乱や中断なしに問題となる範囲の特定と処置を 素早くおこなうことができます。 初期セットアップフェーズが完了してからであっても、 アタックの可能性のあるアクセスをトレースしたり、 要求の変化に応じてファイアウォールルールを 変更したりできるので、`deny' に対するログ取りをおこなうことをおすすめします。

> Note: `accept` コマンドのログ取りをおこなっていると、 ファイアウォールをパケットが一つ通過する毎に 1 行のログが生成されるため 大量の ログデータが発生します。そのため、大規模な FTP/HTTP 転送などをおこなうと、システムが非常に 遅くなってしまいます。 また、パケットが通過するまでにカーネルにより 多くの仕事を要求するため、パケットのレイテンシ (latency) を増加させてしまいます。syslogd もログをディスクに記録するなど、より多くの CPU タイムを 使用し始め、実に容易に `/var/log` が置かれているパーティションを パンクさせてしまう可能性があります。

ファイアウォールは、 `/etc/rc.conf.local` か、もしくは `/etc/rc.conf` によって有効化されるべきです。 関連マニュアルページには、どのドアノブ (訳注: ポートや IP アドレスなど、 ネットワークからの入口を示すもののこと) に手をつければ良いのかに ついての説明と、ファイアウォール設定の既定値のリストがあります。 もし、設定の既定値を使わない場合には、 `ipfw list` とすることで、 現在のルールセットを `rc.conf` から読み込める形で ファイルに出力することができます。 また、`/etc/rc.conf.local` や `/etc/rc.conf` によってファイアウォールを 有効化しない場合には、ファイアウォールの有効化がすべての IP インタフェイス設定より先に行なわれるように確認することが重要です。

次の問題は、ファイアウォールが実際には何を する べきかです ! これは外部からそのネットワークへのどんなアクセスを許したいか、 また内部から外界へのアクセスを どのくらい許したいかに大きく依存します。 いくつか一般的なルールを挙げると:

- 1024 番以下のポートへのすべての TCP 入力アクセスをブロックします。ここは finger, SMTP (mail) そして telnet など、最もセキュリティに敏感な サービスが存在する場所だからです。

- すべての 入力 UDP トラフィックをブロックします。これは UDP を使用しているサービスで有用なものは極めて少ないうえ、 (Sun の RPC と NFS プロトコルのように) 有用なトラフィックであったとしても、 通常セキュリティに対する脅威となるためです。UDP はコネクションレスプロトコルであるため、入力 UDP トラフィックを拒絶することは すなわち出力 UDP トラフィックに対する返答をも ブロックすることになるので、 このことはそれなりの不利益をもたらします。たとえば外部の archie (prospero) サーバを使用している (内部の) ユーザに とって問題となる可能性があります。もし archie へのアクセスを許したければ、191 番と 1525 番のポートから 任意の UDP ポートへ来るパケットがファイアウォールを通過することを 許可しなければなりません。123 番のポートから来るパケットは ntp パケットで、 これも通過の許可を考慮する必要がある もう一つのサービスです。

- 外部から 6000 番のポートへのトラフィックをブロックします。6000 番のポートは X11 サーバへのアクセスに使用されるポートで、 セキュリティに対する脅威となりえます。 (特に自分のワークステーションで `xhost +` をおこなう癖を持っている人がいればなおさらです)。X11 は実際に 6000 番以降のポートを使用する可能性があるため、 通過許可に 上限を定めると、 そのマシンで走らせることのできる X ディスプレイの 個数が制限されます。RFC 1700 (Assigned Numbers) で定義されているように、上限は 6063 です。

- 内部のサーバ (たとえば SQL サーバなど) がどのポートを使用するかを チェックします。 それらのポートは通常、上で指定した 1-1024 番の範囲から外れていますので、 これらも同様にブロックしておくことは おそらく良い考えです。

これとは別のファイアウォール設定に 関するチェックリストが CERT から 入手可能です。http://www.cert.org/tech_tips/packet_filtering.html

前にも述べたように、これはただの ガイドライン にすぎません。 ファイアウォールでどのようなフィルタルールを使用するかは、 あなた自身が 決めなければなりません。 これまでのアドバイスにしたがったにも関わらず、 誰かがあなたのネットワークに 侵入してきたとしても、 わたしたちは「いかなる」責任もとることはできません。

Prev | Home | Next
Kerberos | Up | OpenSSL