OCNのサイトの参考例はルーターで一通りのセキュリティ設定をした後、サーバー本体でも同様のセキュリティ設定をするようになっている。確かに2重にかければルーターが何らかの理由によって穴が開いてもサーバー本体でブロックすることができる。FreeBSDではipfilterを使った設定例が示されていたので、これを参考にした。
ipfilterはモジュールをカーネルにロードする方式を選んだ。もう一つの方法はカーネルの再構築であるが、モジュールを使う方がお手軽である。現状のカーネル状態を表示する。
# kldstat
Id Refs Address Size Name
1 3 0xc0100000 338728 kernel
モジュールを追加してその結果を再表示する。
# kldload ipl
# kldstat
Id Refs Address Size Name
1 3 0xc0100000 338728 kernel
2 1 0xc0cd1000 14000 ipl.ko
これだけではリブートすると元に戻ってしまうので、ブート時に自動組込されるように/boot/loader.confに下記を追記する。
ipl_load="YES"
さらに/etc/rc.confを編集して下記をコメントする。
ipfilter_enable="YES"
ipfilter_rules="/etc/ipf.rules"
ipfilter_flags=""
ipmon_enable="YES"
ipmon_flags="-D /var/log/ipflog"
これでipf.rulesによりフィルターが有効になり、ログの採取もできるようになる。
デフォルトのipf.rulesは以下のコマンドで実施する。
grep -v inet6はIPv6を使わないというおまじないとのこと。
# cd /usr/src/contrib/ipfilter/
# perl mkfilters | grep -v inet6 > /etc/ipf.rules
ただし、FreeBSD4.4Rインストールの際、全てのソースファイルのインストールを選択しておく必要がある。インストールしていない場合は/stand/sysinstallで追加する。
#less /etc/ipf.rules
でデフォルトのipf.rulesを調べると
block in log quick from any to any with ipopts
block in log quick proto tcp from any to any with short
pass out on ed0 all head 150
block out from 127.0.0.0/8 to any group 150
block out from any to 127.0.0.0/8 group 150
pass in on ed0 all head 100
block in from 127.0.0.0/8 to any group 100
となっている。
グループ 150 が ed0 からの出力
グループ 100 が ed0 からの入力
と規定されている。
これをベースにチューニングしていくわけであるが、自宅サーバーは外部向けにはwww、smtp、内部向けにはssh、POP、ftpを使いたいのでこれらについて記述する。サーバーのアドレスは192.168.0.2と仮定する。
block in log quick from any to any with ipopts
block in log quick proto tcp from any to any with short
pass out on ed0 all head 150
block out from 127.0.0.0/8 to any group 150
block out from any to 127.0.0.0/8 group 150
block out from any to 192.168.0.2/32 group 150
pass out quick proto tcp/udp from 192.168.0.2/32 to any keep
state group 150
block out quick all group 150
pass in on ed0 all head 100
block in from 127.0.0.0/8 to any group 100
block in from 192.168.0.2/32 to any group 100
block in quick from 10.0.0.0/8 to any group 100
block in quick from 172.16.0.0/12 to any group 100
block in quick from 0.0.0.0/8 to any group 100
block in quick from 169.254.0.0/16 to any group 100
block in quick from 224.0.0.0/4 to any group 100
block in quick from 240.0.0.0/4 to any group 100
pass in quick proto udp from 192.168.0.1/32 to 192.168.0.2/32
port = 514 group 100
pass in quick proto tcp from any to 192.168.0.2/32 port = 80
group 100
pass in quick proto tcp from any to 192.168.0.2/32 port = 25
flags S/SA group 100
#pass in quick proto tcp from any to 192.168.0.2/32 port = 113
flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 110 flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 22 flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 20 flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 21 flags S/SA group 100
block in log quick all group 100
pass in quick on lo0 all
pass out quick on lo0 all
当初、wwwへのアクセス許可を
pass in quick proto tcp from any to 192.168.0.2/32 port = 80
flags S/SA group 100
と記述したらLAN内から192.168.0.2を叩いてもブラウジングできない。試しに
telnet 192.168.0.2 80
とするとちゃんと接続できるし
GET
と叩くとテキストを引っ張ってくるので、ipf.rules記述に問題があるようである。試しに/etc/rc.confで
#ipfilter_enable="YES"
とコメントアウトすると問題なくWeb画面が
閲覧出来た。PORT80に穴を開けないとWebは見ることができないので、googleで検索した
結果をいろいろと試してみた。結局は
pass in quick proto tcp from any to 192.168.0.2/32 port = http
group 100
と記述したら通るようになった。オプションのS/SAを外す必要があった。
pass in quick proto udp from 192.168.0.1/32 to 192.168.0.2/32
port = 514 group 100
はルーターからのsyslogを受け取るための記述である。
入ってくる方は以下のコマンドでわかる。
# ipfstat -i
block in log quick from any to any with ipopt
block in log quick proto tcp from any to any with short
pass in on ed0 from any to any head 100
block in from 127.0.0.0/8 to any group 100
block in from 192.168.0.2/32 to any group 100
block in quick from 10.0.0.0/8 to any group 100
block in quick from 172.16.0.0/12 to any group 100
block in quick from 0.0.0.0/8 to any group 100
block in quick from 169.254.0.0/16 to any group 100
block in quick from 224.0.0.0/4 to any group 100
block in quick from 240.0.0.0/4 to any group 100
pass in quick proto udp from 192.168.0.1/32 to 192.168.0.2/32
port = 514 group 100
pass in quick proto tcp from any to 192.168.0.2/32 port = 80
group 100
pass in quick proto tcp from any to 192.168.0.2/32 port = 25
flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 110 flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 22 flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 20 flags S/SA group 100
pass in quick proto tcp from 192.168.0.0/24 to 192.168.0.2/32
port = 21 flags S/SA group 100
block in log quick from any to any group 100
pass in quick on lo0 from any to any
出る方は以下のコマンドでわかる。
# ipfstat -o
pass out on ed0 from any to any head 150
block out from 127.0.0.0/8 to any group 150
block out from any to 127.0.0.0/8 group 150
block out from any to 192.168.0.2/32 group 150
pass out quick proto tcp/udp from 192.168.0.2/32 to any keep
state group 150
block out quick from any to any group 150
pass out quick on lo0 from any to any
サーバーが不調になった際、NICの故障も考えられたので念のため、交換した。さすがにNE2000互換の10MbpsタイプのNICは売っておらず、プラネックスコミュニケーションのFW-110TX-PKを購入して装着した。NIC自体はPCのBIOSで認識されており、/stand/sysinstallでIPアドレスを設定したら、無事使用できるようになった。
しばらくして/var/log/ipflogが更新されいないのに気がついた。原因を探っていた結果、設定ファイルを修正することで解決した。新しいNICは
%dmesg
rl0:
rl0: Ethernet address: 00:90:cc:42:8e:1b
でrl0と認識されており、NE2000互換NICのed0とは違っていたのでこれを書き換える必要がある。
# vi /etc/rc.conf
ifconfig_ed0="inet 192.168.0.10 netmask 255.255.255.0"
のed0をrl0に書き換える。
#vi /etc/ipf.rules
pass out on ed0 all head 150
pass in on ed0 all head 100
のed0をrl0に書き換える。
以上、2つの設定ファイルでNIC関連の箇所を書き換え、リブートすればOKである。
上述したipf.rulesはFreeBSD4系から使い始め、現在の6.3系でもそのままである。ところが、最近になって、最新Linuxディストリビューションから自宅サーバーのWebサイトが閲覧できない。さらに、特定のメールアドレス、例えばGmailから自宅サーバー宛にメールが届かないというトラブルが判明した。
試行錯誤の結果、最終的にipf.rulesに問題があることが分かったので、変更することにした。現用サーバーのNICはrl0であり、サーバーのアドレスは192.168.0.20と仮定する。
フィリタングの考え方は基本的には同じであるが、自宅LAN内からのアクセスは全て通すように変えてある。また、外部からはhttp80とsmtp25のみであるがkeep stateの記述が追加されている。
変更したipf.rulesを反映させるためには以下のコマンドを叩けばOKである。
#ipf -FA -Z -f /etc/ipf.rules
block in log quick from any to any with ipopts
block in log quick proto tcp from any to any with short
pass out on rl0 all head 250
block out from 127.0.0.0/8 to any group 250
block out from any to 127.0.0.0/8 group 250
block out from any to 192.168.0.20/32 group 250
pass out quick proto tcp/udp from 192.168.0.20/32 to any keep state group 250
block out quick all group 250
pass in on rl0 all head 200
block in from 127.0.0.0/8 to any group 200
block in from 192.168.0.20/32 to any group 200
block in quick from 10.0.0.0/8 to any group 200
block in quick from 172.16.0.0/12 to any group 200
block in quick from 0.0.0.0/8 to any group 200
block in quick from 169.254.0.0/16 to any group 200
block in quick from 224.0.0.0/4 to any group 200
block in quick from 240.0.0.0/4 to any group 200
pass in quick proto tcp from any to 192.168.0.20/32 port = 80 flags S/SA keep state group 200
pass in quick proto tcp from any to 192.168.0.20/32 port = 25 flags S/SA keep state group 200
pass in quick from 192.168.0.0/24 to 192.168.0.20/32 keep state group 200
pass out quick from 192.168.0.20/32 to 192.168.0.0/24 keep state group 250
block in log quick all group 200
pass in quick on lo0 all
pass out quick on lo0 all