おうちのNATルーターをFreeBSDで設定して使っているので、その設定について書いてみたいと思います。
以下をポリシーとしています。
- 最低限の機能しか持たせない
- 複雑なことはしない
- インターネット側ではLISTENしない
- 必要なサービスは内側のインターフェーでLISTENする
- インターネット側からのポートフォワードはしない
必要な機能は以下になります。
- ISPからDHCPでIPアドレスとデフォルトルートとDNSをもらう
- DHCPでもらったDNSにフォワードするサーバを上げる
- 内側のクライアントのDHCPに答える
- 内から外のNATを行う
使用する機器は二つのネットワークインターフェースがあるのが望ましいですが、VLAN(with etherswitch)を使って二つのネットワークを設定して利用することもできます。
1番はdhclientを使います。dhclientは外側のインターフェースで立ち上げます。
2番はlocal-unboundを使います。dhclientのアドレス取得時のスクリプトで、フォワード先を設定ファイルに書き入れます。(メモ)
3番はportsで入れられるdnsmasqを使います。dnsmasqはisc-dhcpくらべ設定が簡単なようです。dnsmasqはdnsの機能もありますが、dnsはunboundを使うのでdhcpだけで使います。
4番はカーネルのipfwを使っています。カーネルのpfでもできますしプロセスのnatdでもできるようです。12-STABLEで設定していたら動かなくて調べてみたらカーネルオプションのIPFIREWALL_DEFAULT_TO_ACCEPTが必要でした。
状態確認のために内側からだけtelnetで入れるようにしてあります。これはinetdのLISTENを内側だけにしています。
設定変えた時などは、netstatで確認して、ダブルチェックでポートスキャンサイトを使って変なポートが開いてないか確認してます。
パフォーマンスはスピードチェックのサイトを使って確認しいます。うちは遅い契約なので、ルーターがボトルネックにならずに契約スピードが出ています。
12-CURRENTの時期はipfwの調子が悪くて、11-STABLEを使っていたのですが、12-ALPHAになったので試してみたらちゃんと動くようになっていました。
ZRouterで設定をvendorディレクトリに入れてビルドしています。NATルーターが動作不良になると、原因を調べるにも事欠くので、同じ機種を2つ用意して、ロールバックできるようにひとつ前を残して焼きなおすようにしています。
20年以上前にFreeBSD 2.2で同じようなことをしていました。当時はdelegateを使っていました。OMRONを辞めたときにもう二度とBSDを使うことはないだろうと思っていたのが、またBSDを使うことができて嬉しかった記憶があります。
おまけ
ISPの接続がちゃんとできているかどうかを確認するために1分おきに下記のスクリプトを実行するようにしてみました。
# !/bin/sh
ROUTE=`netstat -rn | awk '/default/{print $2}'`
if [ -n "$ROUTE" ]; then
ping -c 1 ${ROUTE} >> /dev/null
if [ $? == 0 ]; then
gpioctl 18 0
else
gpioctl 18 1
fi
else
gpioctl 18 1
fi
ISPへの疎通が無くなるとLEDが消えます。(このモジュールでは1でLEDが消えて、0で点灯します)
追記:消えてもあまり気づきにくいので、疎通がなく無くなると赤のLEDが点灯するような方法が良いと思います。
おまけ2
ポートフォワードは通常は行わないのですがVPNで外から入って何かしたい場合は、中にあるVPNサーバに一時的にポートフォワードしてます。NATサーバとVPNサーバを同じところで動かすことは能力的には可能ですが、設定が複雑になるので別にしています。
おまけ3
こんな感じで実験用のサブネットをUSB Ethernetモジュールで設定してみました。
IIJのSEIL/X4も3ポートのようです。
デフォルトルートがこのモジュールになっていればarge0とue0の間はつうつうになりますが、もしDMZのような設定で分離したい時にはipfwなどで設定すると良いと思います。
ue0のip addressはインターフェースの認識が後の方になるのでrc.dのpoststartで設定する必要がありました。
Atheros(MIPS 24K)の無線ルータを有線だけで使っています。ファーンもなくてうるさくなく快適です。一般ご家庭で消費電力の大きいx86をルータとして使うのは愚行ではないかと思います。