技術的雑談-FreeBSDで2つのNICでサーバを立ち上げる
環境
FreeBSD5.4
目的
- FreeBSDで2つのNICを使い、片方のNICでサーバを立ち上げている(if0)
ISP0 ISP1 | | | | *ISP0 : 固定IPもらえるけど遅い回線(サーバ用) |if0 |if1 *ISP1 : プライベートIPだけど速い回線 +-------------+ | FreeBSD | +-------------+
- でも、ISP0は(Flet's ISDNなどの)低速プロバイダーであり、portupgradeなどで占有して欲しくない
- ISP1は高速なネットワークだが、ケーブルテレビなどのISPなのでサーバを公開できない
現象
- /etc/rc.confの"defaultrouter"をif0に向けると問題は無いが、ISP1は全く使われない
- "defaultrouter"をif1に向けるとip0上で公開しているサーバからの応答パケットまでがif1から出て行ってしまい、サーバ接続が成り立たない
原因
FreeBSD4.9頃から5.3まではipfwに問題があり、NICを超えたforwadingがうまく機能していないため、ipfwやその他のものでパケット転送ができなかったため、解決方法がありませんでした。
対処
FreeBSD5.4以上のOSでipfwで設定してやれば解決できます。
- kernelの再構築
以下のオプションを加えてkernelを再コンパイルする。(GENERIC kernelでは含まれていない)
options IPFIREWALL options IPFIREWALL_FORWARD options IPFIREWALL_DEFAULT_TO_ACCEPT options IPFIREWALL_FORWARD_EXTENDED options IPDIVERT
- /etc/rc.confに以下の記述を追加する
※以下の文例の「if0/if1」は実際にインストールされているNICデバイスのデバイス名に適宜読み替えてください。
ifconfig_if0="inet <if0のアドレス> netmask <if0のネットマスク>" ifconfig_if1="inet <if1のアドレス> netmask <if1のネットマスク>" defaultrouter="<if1のアドレス>" firewall_enable="YES" firewall_type="/root/firewall.conf"
- /root/firewall.confに以下の記述を加える
add 00100 allow ip from 127.0.0.1 to 127.0.0.1 add 00200 allow ip from me to me add 00300 fwd <ISP0のdefault routerのIPアドレス> ip from <if0のアドレス> to not <if1のネットワークアドレス(例:10.100.0.0/16とか)> add 65535 allow ip from any to any
fwdのある行がキモです。
つまり、if0から出て行こうとするパケットをISP0のルーターに直接送り出してあげます。
これをしないと、ローカルネットワークにないアドレスへのパケットは、デフォルトで/etc/rc.confで設定したNIC(ここではif1)に流されます。つまり、if0でサーバ宛のリクエストを受け取っても応答がif1に行ってしまうため、恐らくISP1側では「不正なパケット」として破棄されてしまうでしょう。
- 最後に、サーバをリブートする
もしくは、
#cd /etc/rc.d #./netif restart && ./ipfw restart
でもOKかとは思いますが、どこかのファイルに記述ミスがあるとサーバに繋がらなくなるか、ブートプロセスでシングルユーザモード落ちですので、
必ずサーバの目の前でリブートなりNICの再起動を行うようにしましょう!!!
これで何度泣いた事か……ええ。
ちなみに、きちんとこの設定が生きているか確認するには、
- このサーバに接続してみる。sshとかhttpで。
- このサーバからfetchなどで他のサーバ(一般的なホームページとか)のちょっと大きめなファイルをダウンロードさせてみて、前後で「netstat -i」の値を比べて、fetchのやり取りがif1を通して行われた事を確認する。
これを読んでも何のことだかわからない人は、jp.FreeBSD.orgのQ&A:2341を参照ください。(この記事もほとんどそれのパクリです。)
履歴
2005/9/25 -- 初版
技術的雑談へ戻る