FreeBSD によるダイアルアップ式ファイアウォールの構築

$FreeBSD: doc/ja_JP.eucJP/articles/dialup-firewall/article.sgml,v 1.14 2004/10/28 18:37:18 rushani Exp $

FreeBSD は The FreeBSD Foundation の登録商標です。

製造者および販売者が製品を区別するのに 用いている表示の多くは、商標とされています。 この文書に登場する表示のうち FreeBSD Project がその商標を確認しているものには、その表示に続いて “™” または “®” 記号がおかれています。

この記事は FreeBSD の PPP ダイアルアップと IPFW を用いながらどのようにファイアウォールをセットアップするか、 特に動的に割り当てられた IP アドレスによるダイアルアップ上のファイアウォールについて、 事実を元に詳細に説明します。 なお、始めにしなければならない PPP 接続の設定については触れて いません。PPP 接続の設定について詳しいことは、ppp(8) のマ ニュアルを参考にしてください。


1. 序文

FreeBSD によるダイアルアップ式ファイアウォールの構築

この文書はあなたの ISP によって IP アドレスが動的に割り当てられる場合に、FreeBSD で ファイアウォールを設定するのに必要な手順の概略を述べるものです。 この文書を可能な限り有益で正確なものにするために努力しているので、 どうぞ修正、意見や提案を、 宛で著者に送って下さい。


2. カーネルオプション

IPFW を使うためには、それに対応するようにカーネルを コンパイルしなければなりません。 カーネルを再コンパイルする方法についてのさらなる情報は、 ハンドブックの カーネルのコンフィグレーションの節をご覧ください。 IPFW に対応するには、カーネルの設定ファイルに以下のオプションを 追加しなければなりません。

options IPFIREWALL

カーネルのファイアウォールのコードを有効にします。

Note: この文書では、FreeBSD 5.X を動かしていると仮定して います。FreeBSD 4.X を動かしているユーザーは、カーネルを IPFW2 に対応するよう 再コンパイルしなければなりません。FreeBSD 4.X のユーザーは、 システムで IPFW2 を利用するための詳細は ipfw(8) のマニュアルページを参考にしてください。特に、 USING IPFW2 IN FreeBSD-STABLE という節は注意深く読んでください。

options IPFIREWALL_VERBOSE

システムの logger へ記録されたパケットを送ります。

options IPFIREWALL_VERBOSE_LIMIT=500

当てはまるエントリが記録されうる数を制限します。 これは、サービス不能 (DoS) 攻撃が起きても、syslog が溢れる 危険を避けて、ファイアウォールの活動を記録できるようにします。 500 は妥当な数ですが、あなたの 要件に基づいて調整できます。

Warningカーネルの再コンパイルが完了しても、システムを 再起動しないで下さい。 そうしてしまうと、結果的にシステムから閉め出されてしまう 可能性があります。ルールセットを適切に配置し、関連する設定ファイルを すべて更新するまでは再起動してはいけません。


3. ファイアウォールを搭載するように /etc/rc.conf を変更する

システムでファイアウォールを有効にし、ルールファイルのありかを 指定するために /etc/rc.conf を若干変更する必要があります。 /etc/rc.conf に以下の行を加えてください。

firewall_enable="YES"
firewall_script="/etc/firewall/fwrules"

上記の設定に関するより詳しい情報は /etc/defaults/rc.conf を参照した上で、 rc.conf(5) を読んで下さい。


4. PPP のネットワークアドレス変換を有効にする

ネットワーク内のクライアントがゲートウェイ経由で接続できる ようにするには、PPP のネットワークアドレス変換 (NAT) を有効に しなければなりません。PPP の NAT 機能を利用するには、次の行を /etc/rc.conf に追加してください。

ppp_enable="YES"
ppp_mode="auto"
ppp_nat="YES"
ppp_profile="your_profile"

Note: your_profile をあなた自身のダイアル アッププロファイルに変更するようにしてください。


5. ファイアウォールへのルールセット

ここであなたのシステム用のファイアウォールルールを定義します。 私たちが記述するルールセットは、大部分のダイアルアップユーザ向けの 一般的な雛型です。ユーザ毎の要求にぴったり合わないでしょうが、IPFW の動作について基本的な理解を得られ、要求に合わせて設定を変更する のは結構簡単なはずです。

まずは、閉鎖的なファイアウォールの基礎から始めましょう。閉鎖的な ファイアウォールは、設定がない場合はすべて拒否するという考えに 基づいています。それから、管理者は許可したい通信用のルールを明示的に 追加できます。通信用のルールは、許可が先でそれから拒否という 順番であるべきです。許可したいものすべてについてルールを追加して、 それ以外はすべて自動的に拒否されることを前提とします。

それでは、ファイアウォールのルールを保存するディレクトリを 作成しましょう。この例では、 /etc/firewall を用います。 ディレクトリをそこへ変更し、 rc.conf で規定した fwrules ファイルを編集します。 このファイル名を自分が望む任意のものに変更できるということに気をつけてください。 この手引きはあなたが使おうとするかもしれないファイル名の一例を 与えるだけです。

それでは、きちんと注釈が施されたファイアウォールファイルの 例を見てみましょう。

# (/etc/rc.firewall にあるように) 参照を簡単にするためにファイアウォールの
# コマンドを定義します。読みやすくするのに役立ちます。
fwcmd="/sbin/ipfw"

# 外向けインタフェースを定義します。ユーザーランド ppp では、
# 何も設定しないと tun0 になります。
oif="tun0"

# 内向けインタフェースを定義します。通常はネットワークカードに
# なります。これを必ずあなたのネットワークインタフェースに
# 合わせて変更するようにしてください。
iif="fxp0"

# ルールを再読込みする前に、現在のルールを強制的に消去します。
$fwcmd -f flush

# すべてのパケットの状態を確認します。
$fwcmd add check-state

# 外向けインタフェース側でなりすましを防ぎます。
$fwcmd add deny ip from any to any in via $oif not verrevpath

# 私たちが開始した接続はすべて許可し、状態を保存します。
# しかし、動的なルールを持たない確立した接続は拒否します。
$fwcmd add allow ip from me to any out via $oif keep-state
$fwcmd add deny tcp from any to any established in via $oif

# ネットワーク内の接続はすべて許可します。
$fwcmd add allow ip from any to any via $iif

# ローカルな通信をすべて許可します。
$fwcmd add allow all from any to any via lo0
$fwcmd add deny all from any to 127.0.0.0/8
$fwcmd add deny ip from 127.0.0.0/8 to any

# インターネット側のユーザに 22 番と 80 番ポートへ接続することを
# 許可します。この例では、sshd とウェブサーバへの接続を特に許可しています。
$fwcmd add allow tcp from any to me dst-port 22,80 in via $oif setup keep-state

# ICMP パケットを許可します。ホストを ping(8) に応答させたくなければ、
# icmptypes から 8 を削除してください。
$fwcmd add allow icmp from any to any via $oif icmptypes 0,3,8,11,12

# 残りのすべてを拒否して記録します。
$fwcmd add deny log ip from any to any

22 番と 80 番ポートへの接続のみを許可し、それ以外に試みられた 接続はすべて記録する、完全に機能するファイアウォールができました。 これで安全に再起動することができ、ファイアウォールが自動的に 起動してルールセットが読み込まれるはずです。 もしこれに何か間違いを見つけたり、何か問題に当たったり、 このページを改善する提案があるなら、 どうか私に電子メールを送って下さい。


6. 質問

6.1. limit 500 reached on entry 2800” のようなメッセージが出た後、私のマシンはそのルール番号に対 応する拒否されたパケットを記録しなくなりました。 ファイアウォールはまだ動作しているのでしょうか?
6.2. 何か間違っているに違いありません。 私はあなたの説明に文字通り従いましたが、 締め出されてしまいました。

6.1.limit 500 reached on entry 2800” のようなメッセージが出た後、私のマシンはそのルール番号に対 応する拒否されたパケットを記録しなくなりました。 ファイアウォールはまだ動作しているのでしょうか?

単にそのルールのログカウントが最大値に達した ということを意味しています。ルール自体はまだ機能していますが、 ログカウンタをリセットするまでそれ以上ログを記録しません。 カウンタのリセット方法の例を以下に示します。

# ipfw resetlog

また、この限界値を上述の IPFIREWALL_VERBOSE_LIMIT オプションで 変更することもできます。 さらに、この限界値は (カーネルを再構築して再起動せずに) sysctl(8) の net.inet.ip.fw.verbose_limit 変数により 変更することもできます。

6.2. 何か間違っているに違いありません。 私はあなたの説明に文字通り従いましたが、 締め出されてしまいました。

このチュートリアルはあなたが userland-ppp を稼働していて、その結果 tun0 [ppp(8) (またの名を user-ppp) で作られる最初の接続に相当します] インタフェース上で供給されたルールセットが動作していることを想定しています。 さらなる接続は tun1tun2 などを用います。

pppd(8)ppp0 インタフェースを代わりに用いるということにも注意するすべきです。 よって pppd(8) による接続を始めるなら ppp0 の代わりに tun0 を用いて下さい。 この変更を反映するファイアウォールのルールを 編集する早道は以下に示されています。 元のルールセットは fwrules_tun0 としてバックアップされています。

       % cd /etc/firewall
        /etc/firewall% su
        Password:
        /etc/firewall# mv fwrules fwrules_tun0
        /etc/firewall# cat fwrules_tun0 | sed s/tun0/ppp0/g > fwrules
     

いったん接続が確立したら、 現在 ppp(8)pppd(8) のどちらを利用しているかを知るために ifconfig(8) の出力で検査することができます。 例として、pppd(8) で作成された接続では、 このようなものが目にするでしょう (関係のあるものだけ示しています)。

       % ifconfig
        (skipped...)
        ppp0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1524
                    inet xxx.xxx.xxx.xxx --> xxx.xxx.xxx.xxx netmask 0xff000000
        (skipped...)
       

他方で、ppp(8) (user-ppp) で作成された接続では、 あなたはこれに似たものを目にするはずです。

       % ifconfig
        (skipped...)
        ppp0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500
        (skipped...)
        tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1524
                (IPv6 stuff skipped...)
                    inet xxx.xxx.xxx.xxx --> xxx.xxx.xxx.xxx netmask 0xffffff00
                    Opened by PID xxxxx
            (skipped...)