ipfw でフィルタリング

 
ipfw は,FreeBSD のベースシステムに含まれるパケットフィルタである. カーネルモジュール ipfw.ko として提供され, /etc/rc.conf の設定により起動時に自動的に読み込まれる. FreeBSD には ipfw のほかに pfipfilter も含まれており,いずれか 1 つを選んで使用する.

(オプション)nmap を用いた開放ポートの確認

nmap を実行すると,そのホストで外部からの接続を受け付けている 開放ポートを確認できる.

ポートスキャンは,スキャン対象のマシンと経路上のネットワークに負荷をかける. スキャンしてよいのは,自分が管理するマシン,または 管理者から書面で許可を得たマシンだけである. それ以外へのスキャンは,不正アクセス禁止法などに抵触する場合がある. このページでは,自分が管理するマシンをローカルにスキャンすることを想定している.

nmap のインストール

パッケージからインストールする.

pkg install nmap

ports からビルドする場合は次の通り.

cd /usr/ports/security/nmap
make install clean

スキャン

TCP のコネクトスキャンの例

nmap -sT -Pn -T4 -p 1-65535 -r -oN result-tcp.txt -v -A localhost

UDP のスキャンの例

nmap -sU -Pn -T4 --top-ports 100 -oN result-udp.txt -v localhost

自分のマシンで待ち受けているポートを確認するだけであれば, スキャンを行わずに sockstat を使う方が速く,正確である.

sockstat -4 -6 -l

/etc/rc.conf を編集し ipfw を有効にする

ルールは /etc/ipfw.rules に自分で記述し,そのファイルを firewall_script で指定する. /etc/rc.firewall は OS の更新で上書きされるため,直接編集しない.

/etc/rc.conf に,次の行を追加する.

firewall_enable="YES"
firewall_script="/etc/ipfw.rules"
firewall_logging="YES"

sysrc コマンドを使って設定することもできる.

sysrc firewall_enable="YES"
sysrc firewall_script="/etc/ipfw.rules"
sysrc firewall_logging="YES"
遮断ルールを適用すると,作業中の ssh 接続が切断されることがある. リモートから設定する場合には,ssh を許可するルールをルールファイルに書いてから適用する, コンソールから操作できる状態で適用する,のいずれかを行う.

外部への通信の遮断(クライアントとして使う場合の設定)

最初に,外部への通信を遮断する設定を行う.

外部への通信を許可するポートを決める

次のポートを許可しておけば,一般的な用途では支障が少ない(用途に応じて増減させる).

平文でパスワードやデータを送る ftp (20, 21),pop3 (110),imap (143),smtp (25) は, TLS を用いる代替(sftp または scp,995,993,587)に置き換える. ftp は,制御用とデータ用の 2 本の接続を使い,データ用のポート番号が動的に決まるため, フィルタリングの設定も複雑になる.

ipfw ルールファイルの例

/etc/ipfw.rules を作成し,次の内容を記述する. XXX.YYY.ZZZ.0/24 の部分は,自分の LAN のアドレスに変更する.

#!/bin/sh

fwcmd="/sbin/ipfw -q"

# ルールの初期化
${fwcmd} -f flush

# ループバック
${fwcmd} add 100 allow ip from any to any via lo0
${fwcmd} add 110 deny ip from any to 127.0.0.0/8
${fwcmd} add 120 deny ip from 127.0.0.0/8 to any

# 確立済み通信(動的ルール)の照合
${fwcmd} add 200 check-state

# LAN 内の通信は許可
${fwcmd} add 300 allow ip from XXX.YYY.ZZZ.0/24 to me
${fwcmd} add 310 allow ip from me to XXX.YYY.ZZZ.0/24

# 外部への TCP 通信(22:ssh, 53:DNS, 80:http, 443:https, 587:submission, 993:imaps, 995:pop3s)
${fwcmd} add 400 allow tcp from me to any 22,53,80,443,587,993,995 setup keep-state

# 外部への UDP 通信(53:DNS, 123:NTP)
${fwcmd} add 410 allow udp from me to any 53,123 keep-state

# ping(echo request)と,経路 MTU 探索などに必要な ICMP
${fwcmd} add 420 allow icmp from me to any icmptypes 8 keep-state
${fwcmd} add 421 allow icmp from any to me icmptypes 3,4,11

# DHCP でアドレスを取得する場合
${fwcmd} add 430 allow udp from any 67 to me 68 in

# 上記以外は遮断し,ログに記録する
${fwcmd} add 65000 deny log ip from any to any

設定の反映

ルールファイルを保存したあと,次のコマンドで反映する.

service ipfw restart

設定内容の確認

ipfw の設定情報(ルールリスト)は,ipfw show で確認できる. show はパケットカウンタ付きの表示である.

ipfw show

動的ルール(keep-state により生成されたルール)は,ipfw -d list で確認できる.

ipfw -d list

ipfw ルールの動作確認

許可したポートへの通信ができること,許可していないポートへの通信が遮断されることを確認する. 接続確認には nc を使う.-z は接続確認のみ,-v は詳細表示,-w は待ち時間(秒)である.

nc -vz -w 3 www.freebsd.org 443
nc -vz -w 3 www.freebsd.org 23

443 は接続に成功し,23(telnet)は遮断されて時間切れになる.

どのルールにマッチしたかは,ipfw show のパケットカウンタで確認できる. 遮断ルールのカウンタが増えていれば,そのルールで遮断されている.

ipfw show

log キーワードを付けたルールにマッチしたパケットは, /var/log/security に記録される.

tail -f /var/log/security

ログが出力されない場合は,sysctl で net.inet.ip.fw.verbose の値を確認する. 0 のときは 1 に設定する(この設定は再起動すると元に戻る. 恒久的に有効にするには,/etc/rc.conf に firewall_logging="YES" を記述する).

sysctl net.inet.ip.fw.verbose
sysctl net.inet.ip.fw.verbose=1

同一ルールのログ出力回数には上限があり,上限に達するとログが止まる. 上限は net.inet.ip.fw.verbose_limit で設定する(0 は無制限).

sysctl net.inet.ip.fw.verbose_limit=100

公開サーバでの設定例(Web/SSH サーバを例として)

公開サーバの場合,外部からの通信については,公開するポートへの通信だけを許可し, それ以外のポートへの通信を遮断する.

/etc/ipfw.rules を編集し,最後の deny ルール(例では 65000 番)よりも前に,次のルールを追加する.

# 外部から受け付けるサービス(22:ssh, 80:http, 443:https)
${fwcmd} add 500 allow tcp from any to me 22,80,443 setup keep-state

ssh を公開する場合には,パスワード認証を無効にし,公開鍵認証を使う. /etc/ssh/sshd_config で PasswordAuthentication no,PermitRootLogin no を設定し, sshd を再起動する.

service sshd restart

ルールファイルを保存したあと,次のコマンドで反映する.

service ipfw restart

ipfw の設定情報(ルールリスト)は,ipfw show で確認できる.

ipfw show

ipfw 使用法

ルールの追加と削除

ルール追加の書式は次の通り.
      ipfw [-q] add [ルール番号] アクション [log] プロトコル アドレス [ オプション ]
-q -N add delete ルール番号 flush zero [ルール番号] ルール番号 log

アクション

プロトコル

アドレスとポートの指定

      from <address>[/masklen] [port] to <address>[/masklen] [port]

主なオプション

ルールリストの表示

書式は次の通り.
      ipfw [-a] [-d] [-t] [-N] list

関連する外部ページipfw(8) マニュアルFreeBSD ハンドブック「ファイアウォール」