ipfw
 ipfw と NAT の設定手順
ipfw は FreeBSD のパケットフィルタである.
現在の FreeBSD では,ipfw の機能はカーネルモジュール
(ipfw.ko,ipfw_nat.ko)として提供されており,
カーネルの再構築は不要である.
/etc/rc.conf の設定に従って,起動時に必要なモジュールが自動的に読み込まれる.
アドレス変換(NAT)には,カーネル内 NAT(ipfw nat)と,
divert ソケットを用いる旧来のユーザランド NAT(natd)がある.
カーネル内 NAT はパケットをユーザランドに渡さないため処理の負荷が小さく,
新規の設定ではカーネル内 NAT を用いる.
- ゲートウェイとして動作させる
/etc/rc.conf に以下の行を追加する.gateway_enable="YES" - ipfw を有効にする
/etc/rc.conf に以下の行を追加する.firewall_enable="YES" firewall_script="/etc/ipfw.rules" firewall_logging="YES" firewall_nat_enable="YES" firewall_quiet="YES"firewall_scriptには,ルールを記述したファイルを指定する. /etc/rc.firewall を直接書き換えると,OS の更新時に変更が失われるため, 別ファイルを作成して指定する.firewall_logging="YES"はnet.inet.ip.fw.verboseを 1 に設定し, log キーワードの付いたルールに一致したパケットを syslog(facility は LOG_SECURITY)に記録させる. 旧来のカーネルオプションIPFIREWALL_VERBOSEは不要である.firewall_nat_enable="YES"は,カーネル内 NAT のモジュールipfw_nat.koを読み込ませる.
- ipfw のルールを記述する
ここでは次の方針でルールを作る.- 禁止したパケットについてのログを録ること
- telnet での外部への接続を禁止
- 192.168.33.* に向けての接続は telnet 以外すべて許可
- tcp で外部に接続するのは telnet 以外すべて許可
- udp で 192.168.33.* 以外への接続は DNS(ポート番号 53)のみ許可
- icmp はすべて許可
- 許可していないものはすべて禁止
#!/bin/sh fwcmd="/sbin/ipfw -q" oif="外側インターフェース名" onet="192.168.33.0/24" inet="192.168.40.0/24" ${fwcmd} -f flush # ループバック ${fwcmd} add 100 allow ip from any to any via lo0 ${fwcmd} add 200 deny ip from any to 127.0.0.0/8 ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any # カーネル内 NAT ${fwcmd} nat 1 config if ${oif} same_ports unreg_only reset ${fwcmd} add 400 nat 1 ip from any to any via ${oif} # telnet の禁止(ログを録る) ${fwcmd} add 1000 deny log tcp from any to any 23 # 192.168.33.0/24 に向けての接続の許可 ${fwcmd} add 2000 allow ip from any to ${onet} # tcp の許可(telnet はルール 1000 で禁止済み) ${fwcmd} add 3000 allow tcp from any to any # DNS の許可 ${fwcmd} add 4000 allow udp from any to any 53 ${fwcmd} add 4100 allow udp from any 53 to any # icmp の許可 ${fwcmd} add 5000 allow icmp from any to any # 上記以外はすべて禁止(ログを録る) ${fwcmd} add 65000 deny log ip from any to anyルールはルール番号の小さい順に照合され,最初に一致したルールの動作が行われるため, 禁止のルールを許可のルールより前に置く.ipfw -qの-qは,ルール適用時のメッセージ出力を抑止する. - ルールを反映させる
再起動せずに反映させるには次のコマンドを実行する.# service ipfw restart遠隔ログイン中にルールを適用して接続が切れた場合は, コンソールから次のコマンドを実行すると,ルールの照合を一時的に停止できる.# ipfw disable firewall - 確認
以下のコマンドで ipfw のルールリストを表示する.# ipfw listカウンタの値も合わせて表示するには次のコマンドを実行する.# ipfw -a listNAT の設定と統計は次のコマンドで確認する.# ipfw nat 1 show config # ipfw nat 1 show log
natd を使う場合
divert ソケットを用いる natd を使用する場合は, /etc/rc.conf に以下の行を追加する.
gateway_enable="YES"
natd_enable="YES"
natd_interface="外側インターフェース名"
このとき,ルールファイルでは NAT のルールを divert アクションで記述する.
${fwcmd} add 400 divert natd ip from any to any via ${oif}
ipfw のルール変更
この形式での使用法は:
ipfw [-q] コマンド [ルール番号] [set N] アクション [log] プロトコル アドレス [ オプション ]
コマンド
-
add
-
ルールリストにエントリを追加する.
-
ルールリストからエントリを削除する.
-
デフォルトルールを除くすべてのエントリを削除する.
-
カウンタ,ログカウンタを 0 に戻す.
-
ルール番号は 1 から 65535 の範囲の値であり,
65535 はデフォルトルールのために予約されている.
ルール番号を指定すると,エントリはその位置に置かれる.
指定しなければ,デフォルトルールを除く最後のエントリの番号に,
sysctl 変数
net.inet.ip.fw.autoinc_step の値(既定値は 100)を
足した位置に置かれる.
同じ番号のルールを複数登録することもでき,その場合は追加した順に照合される.
-
マッチしたルールをログに記録する.
net.inet.ip.fw.verbose が 1 のとき syslog に記録され,
0 のときは ipfw0 疑似インタフェースに対して
tcpdump などで参照できる.
-
allow
-
パケットを通過させる.照合はここで終了する.(別名: pass,accept,permit)
-
パケットを捨てる.発信元は ICMP メッセージによる通知を受けない
(そのためパケットが宛先に到達しなかったように見える).(別名: drop)
-
パケットを捨て,ICMP ホスト到達不能パケットを発信元へ送る.
旧来の reject はこの動作の別名であり,現在は非推奨である.
-
パケットを捨て,TCP パケットの場合は TCP リセット(RST)を発信元へ送る.
-
パケットを,指定した番号のカーネル内 NAT インスタンスへ渡す.
-
マッチしたパケットを,port にバインドされている divert(4) ソケットへ送る.
natd を使う場合に用いる.
-
パケットカウンタを更新するだけで,パケットを通過させたり拒絶したりしない.
照合は次のルールから続けられる.
-
動的ルール(ステートフルフィルタ)を扱う.
keep-state の付いたルールに一致すると,
同じ 5 組(プロトコル,送信元と宛先のアドレスおよびポート)のパケットに
一致する動的ルールが生成される.
これにより,こちらから開始した通信の戻りパケットだけを許可できる.
-
ip または all
-
任意の IP パケットにマッチする.
-
ICMP パケットにマッチする.
-
TCP パケットにマッチする.
-
UDP パケットにマッチする.
from <address/mask>[port] to <address/mask>[port] [via <interface>]
port はポートをサポートするプロトコル(TCP と UDP)の場合にだけ指定可能.via は必須ではなく,特定のインタフェースを通ったパケットだけにマッチさせるために, IP アドレス,ローカル IP インタフェースのドメイン名, またはインタフェース名(例えば em0)を指定することができる. パケットの向きを限定するには in,out, 受信側・送信側のインタフェースを限定するには recv,xmit を用いる.
<address/mask> の指定は:
<address>
または
<address>/mask-bits
または
<address>:mask-pattern
IP アドレスのかわりにホスト名を指定することも可能である.
mask-bits はアドレスマスクで上位何ビットを 1 にするかを示す十進数値である.
例えば次の指定
192.216.222.1/24
は,192.216.222.0/24 の任意のアドレスにマッチするマスクを作成する.
mask-pattern は,与えられたアドレスと論理 AND される IP アドレスである.
キーワード any は「任意の IP アドレス」を指定するために使用することができる.
ipfw ルールリストの表示
この形式での使用法は:
ipfw [-adnNStT] list
主なフラグは次の通りである.
-
-a
-
リスト表示の際にカウンタの値も表示する.
ipfw show はこのオプションを指定したことになる.
-
静的なルールに加えて,動的ルールも表示する.
-
各エントリが最後にマッチした時刻を表示する.
この時刻表示は ipfw(8) の入力形式とは互換性がない.
-
各エントリが最後にマッチした時刻を,エポックからの秒数で表示する.
スクリプトで処理する場合に用いる.
-
(可能であれば)アドレスやサービス名を名前に変換して表示する.
-
各ルールが属するセット番号を表示する.
このフラグを指定しない場合,無効化されたセットのルールは表示されない.