トップ 一覧 検索 ヘルプ RSS ログイン

技術的雑談-FreeBSDで2つのNICでサーバを立ち上げるの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!技術的雑談-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|http://www.jp.freebsd.org/QandA/HTML/2341.html]を参照ください。(この記事もほとんどそれのパクリです。)

!!履歴
2005/9/25 -- 初版

[[技術的雑談]]へ戻る

!!突っ込み
{{comment}}

[[技術的雑談]]へ戻る

{{trackback}}

[[技術的雑談]]へ戻る