ipfw でフィルタリング
 FreeBSD でパケットのフィルタリングを行いたい場合には, ipfw を使うのが便利です.
(オプション)nmap を用いた開放ポートの確認
nmap を実行すると、開放ポートが分かります.
お断り
ポートスキャンは、スキャン相手のマシン、経路上のネットワークに大きな負担をかけます. ポートスキャンの実行前に、ポートスキャンの仕組みを良く理解し、他の人に迷惑をかけないように 良く注意し、吟味した上で実行してください。さもなければ、違法行為になると考えます.
このページでは、自分が所有するマシン上で、マシンの脆弱性 をチェックするために、ローカルに実行することを想定している.それ以外 の目的に使用することは絶対に避けてください
nmap のインストール
cd /usr/ports/distfiles/nmap make make install pkgdb -F
スキャン
TCP/IPのコネクトスキャンの例
nmap -sT -P0 -T4 -p 1-65535 -r -oN hoge.txt -v -A localhost
- -sT: コネクトスキャン
- -P0: host discovery を行わない
- -T4: Tの後は 0 から 6 の数字.4 は遅め
- -p 1-65535: ポート番号の範囲
- -r: スキャン時にポート番号のランダマイズをしない
- -oN: 普通の形式でファイルに出力
- -v: verbose
- -A: OS とバージョンの検出を有効にする
UDP/IPのスキャンの例
nmap -sU -P0 -T1 -p 1-65535 -r -oN hoge.txt -v localhost
- -sT: コネクトスキャン
- -P0: host discovery を行わない
- -T4: Tの後は 0 から 6 の数字.4 は遅め
- -p 1-65535: ポート番号の範囲
- -r: スキャン時にポート番号のランダマイズをしない
- -oN: 普通の形式でファイルに出力
- -v: verbose
- -A: OS とバージョンの検出を有効にする
/etc/rc.conf を編集し ipfw を有効にする.
/etc/rc.conf に、以下の行を追加する。fxp0 の部分は、適切な名前に変更す ること(ifconfig -a で確認できる)。
firewall_enable="YES" firewall_logging="YES" firewall_script="/etc/rc.firewall" firewall_interface="fxp0" firewall_type="open"

外部への通信の遮断
最初は,外部への通信の遮断を行う.
- 外部への通信と、外部からの通信は区別して設定するということに注意(混同しないように)
- LAN 内の通信は全て許可
LAN 内の IP アドレスを,このページでは,「XXX.YYY.ZZZ.0/24」と書く.
- 外部への通信について,許可したいポートのポート番号を指定します(指定しなかったポートは遮断されます).
- keep-state を有効にします
外部への通信を許すポートを決める
とりあえず,次のポートを許していれば困らないと思います(ケース・バイ・ケースですので,必要に応じて緩めてください).
- 20,21 ・・・ ftp, ftp-data # ftp 要求を受け付けたいか
- 22 ・・・ ssh
- 25 ・・・ sendmail
- 42,53 ・・・ DNS (UDP)
- 123 ・・・ NTP (UDP)
- 80, 3128, 8000, 8001, 8080 ・・・ WWW
- 110 ・・・ pop3
- 143 ・・・ imap
- 280 ・・・ http-mgmt
- 443 ・・・ https
- 515 ・・・ lpd (プリンタ)
- 1755 ・・・ ストリーミング
- 5999 ・・・ cvsup
ipfw 設定ファイルの例
参考 にしたWeb ページ: http://y-kit.jp/inet/page/port.htm(現存しない)
setup_loopback () { # LOCALHOST はすべて OK ${fwcmd} add 100 allow ip from me to me # LAN ${fwcmd} add 200 allow ip from XXX.YYY.ZZZ.0/24 to me ${fwcmd} add 201 allow ip from me to XXX.YYY.ZZZ.0/24 ${fwcmd} add 202 add allow ip from XXX.YYY.ZZZ.0/24 to XXX.YYY.ZZZ.0/24 # me -> out # Global 20(ftp-data), 21(ftp) ${fwcmd} add 400 allow tcp from me to any 20 keep-state ${fwcmd} add 401 allow udp from me to any 20 ${fwcmd} add 402 allow udp from any 20 to me ${fwcmd} add 403 allow tcp from me to any 21 keep-state ${fwcmd} add 404 allow udp from me to any 21 ${fwcmd} add 405 allow udp from any 21 to me # 25(sendmail) ${fwcmd} add 410 allow tcp from me to any 25 keep-state ${fwcmd} add 411 allow udp from me to any 25 ${fwcmd} add 412 allow udp from any 25 to me # 80, 3128, 8000, 8001, 8080 (WWW) ${fwcmd} add 420 allow tcp from me to any 80 keep-state ${fwcmd} add 421 allow udp from me to any 80 ${fwcmd} add 422 allow udp from any 80 to me ${fwcmd} add 423 allow tcp from me to any 3128 keep-state ${fwcmd} add 424 allow udp from me to any 3128 ${fwcmd} add 425 allow udp from any 3128 to me ${fwcmd} add 426 allow tcp from me to any 8000 keep-state ${fwcmd} add 427 allow udp from me to any 8000 ${fwcmd} add 428 allow udp from any 8000 to me ${fwcmd} add 429 allow tcp from me to any 8001 keep-state ${fwcmd} add 430 allow udp from me to any 8001 ${fwcmd} add 431 allow udp from any 8001 to me ${fwcmd} add 432 allow tcp from me to any 8080 keep-state ${fwcmd} add 433 allow udp from me to any 8080 ${fwcmd} add 434 allow udp from any 8080 to me # 280 (http-mgmt) ${fwcmd} add 440 allow tcp from me to any 280 keep-state ${fwcmd} add 441 allow udp from me to any 280 ${fwcmd} add 442 allow udp from any 280 to me # 443 (https) ${fwcmd} add 450 allow tcp from me to any 443 keep-state ${fwcmd} add 451 allow udp from me to any 443 ${fwcmd} add 452 allow udp from any 443 to me # 515(printer) ${fwcmd} add 460 allow tcp from me to any 515 keep-state ${fwcmd} add 461 allow udp from me to any 515 ${fwcmd} add 462 allow udp from any 515 to me # 1755 (streaming) ${fwcmd} add 470 allow tcp from me to any 1755 keep-state ${fwcmd} add 471 allow udp from me to any 1755 ${fwcmd} add 472 allow udp from any 1755 to me # 5999(cvsup) ${fwcmd} add 473 allow tcp from me to any 5999 keep-state ${fwcmd} add 474 allow udp from me to any 5999 ${fwcmd} add 475 allow udp from any 5999 to me # 53 (DNS) ${fwcmd} add 480 allow udp from me to any 53 keep-state ${fwcmd} add 481 allow udp from me to any 53 ${fwcmd} add 482 allow udp from any 53 to me # 123 (ntp) ${fwcmd} add 480 allow udp from me to any 123 keep-state ${fwcmd} add 490 allow udp from me to any 123 ${fwcmd} add 491 allow udp from any 123 to me # DENY ${fwcmd} add 999 deny ip from any to any }
設定内容の確認
ipfw の設定情報(ルールリスト)は、ipfw show で確認できる.
# ipfw show
ipfw ルールの動作確認
まずは,実在するマシンに telnet してみる.多分 接続が拒否されると思いますが、それはそれで良いのです.つまり, telnet のパケットが外部に出ているということが分かります.

sysctl コマンドで、net.inet.ip.fw.verbose=1 を設定すると、 /var/log/secuty ファイルにログが記録されるようになる. (システムを再起動すると、net.inet.ip.fw.verbose の値は元に戻る)。
ipfw show sysctl net.inet.ip.fw.verbose=1 cd /var/log cat security
公開サーバでの設定例 (Web/SSH サーバを例として)
ポート単位での遮断公開サーバ(外からの要求は何でも歓迎)の場合,必要なポートだけを開放します. つまり,外部からの通信については,開放ポートへの通信だけが許可され,それ以外のポートへの通信を遮断します.
先ほど設定した /etc/rc.firewall の setup_loopback() の部分に,次のルールを追加します.
# 80, 3128, 8000, 8001, 8080 (WWW) ${fwcmd} add 300 allow tcp from me 80 to any ${fwcmd} add 301 allow ucp from me 80 to any ${fwcmd} add 302 allow tcp from any to me 80 ${fwcmd} add 303 allow ucp from any to me 80 ${fwcmd} add 304 allow tcp from me 3128 to any ${fwcmd} add 305 allow ucp from me 3128 to any ${fwcmd} add 306 allow tcp from any to me 3128 ${fwcmd} add 307 allow ucp from any to me 3128 ${fwcmd} add 308 allow tcp from me 8000 to any ${fwcmd} add 309 allow ucp from me 8000 to any ${fwcmd} add 310 allow tcp from any to me 8000 ${fwcmd} add 311 allow ucp from any to me 8000 ${fwcmd} add 312 allow tcp from me 8001 to any ${fwcmd} add 313 allow ucp from me 8001 to any ${fwcmd} add 314 allow tcp from any to me 8001 ${fwcmd} add 315 allow ucp from any to me 8001 ${fwcmd} add 316 allow tcp from me 8080 to any ${fwcmd} add 317 allow ucp from me 8080 to any ${fwcmd} add 318 allow tcp from any to me 8080 ${fwcmd} add 319 allow ucp from any to me 8080 # 280 (http-mgmt) ${fwcmd} add 320 allow tcp from me 280 to any ${fwcmd} add 321 allow ucp from me 280 to any ${fwcmd} add 322 allow tcp from any to me 280 ${fwcmd} add 323 allow ucp from any to me 280 # 443 (https) ${fwcmd} add 330 allow tcp from me 443 to any ${fwcmd} add 331 allow ucp from me 443 to any ${fwcmd} add 332 allow tcp from any to me 443 ${fwcmd} add 333 allow ucp from any to me 443 # 22 (ssh) ${fwcmd} add 340 allow tcp from me 22 to any ${fwcmd} add 341 allow ucp from me 22 to any ${fwcmd} add 342 allow tcp from any to me 22 ${fwcmd} add 343 allow ucp from any to me 22 # 115 (sftp) ${fwcmd} add 350 allow tcp from me 115 to any ${fwcmd} add 351 allow ucp from me 115 to any ${fwcmd} add 352 allow tcp from any to me 115 ${fwcmd} add 353 allow ucp from any to me 115
ipfw 使用法
IPFWのルール変更
この形式での使用法は:ipfw [-N] コマンド [index] アクション [log] プロトコル アドレス [ オプション ]-N
-
アドレスやサービス名を文字列に変換して表示する.
-
add
-
ファイアウォール / アカウンティングルールリストに エントリを追加する.
-
ファイアウォール / アカウンティングルールリストから エントリを削除する.
-
index が指定されていると,エントリはチェーン中の index で示される位置に置かれる.
index が指定されて いなければ,エントリは(65535 番のデフォルトルールである
パケット拒絶を別にして) 最後のチェーンエントリの index に
100 を足した 位置 (チェーンの最後) に置かれる.
-
カーネルが IPFIREWALL_VERBOSE つきでコンパイルされている場合,
マッチしたルールをシステムコンソールに出力させる.
-
reject
-
パケットを捨てる.
ICMP ホスト / ポート到達不能パケットを (適切な方を) 発信元へ送る.
-
通常通りパケットを通過させる.(別名: pass および accept)
-
パケットを捨てる.発信元は ICMP メッセージによる 通知を受けない
(そのためパケットが宛先に到達しなかったように見える).
-
マッチするパケットを port で指定されたポートにバインドされている
divert(4) ソケットに送ります.
-
このルールはパケットカウンタを更新するだけで, パケットを通過させたり拒絶したりしない.
検索は次のチェーンエントリから続けられます.
-
all
-
任意の IP パケットにマッチします.
-
ICMP パケットにマッチします.
-
TCP パケットにマッチします.
-
UDP パケットにマッチします.
from <address/mask>[port] to <address/mask>[port] [via <interface>]port はポートをサポートする プロトコル (UDP と TCP) の 場合にだけ指定可能.
via は必須ではなく, 特定のインターフェースを通ってきたパケット だけにマッチするように, IP アドレスまたはローカル IP インターフェースの ドメイン名, またはインターフェース名 (例えば ed0) を 指定することができる.
<address/mask> の指定は:
<address>または
<address>/mask-bitsまたは
<address>:mask-patternIP アドレスのかわりに有効なホスト名を指定することも可能です. mask-bits はアドレスマスクで上位何ビットを1にするべきかを 示す十 進数値です. 例えば次の指定,
192.216.222.1/24はクラス C のサブネット (この場合 192.216.222) の任意のアドレスにマッチする マスクを作成する. mask-pattern は与えられたアド レスと 論理 AND される IP アドレスです. キーワード any は「任意の IP アドレス」を指定するために 使用することができる.
IPFW ルールリストの表示
この形式での使用法は:ipfw [-atN] listこの形式で使用する際に有効なフラグは三つあります:
-
-a
-
リスト表示の際にカウンタの値も表示します. このオプションは アカウンティングカウンタの内容を見る唯一の手段です.
-
各チェーンエントリが最後にマッチした時刻を表示します. この時刻表示は ipfw(8)
ユーティリティで使用される入力形式と 互換
性がありません.
-
(可能であれば) アドレスやサービス名を文字列に変換して表示します.