スポンサーリンク

IPFW(8) FreeBSD システム管理者マニュアル IPFW(8)

名称

ipfw − IP ファイアウォールとトラフィックシェイパの制御プログラム

書式

ipfw [−cq] add rule

ipfw [−acdefnNStT] {list | show} [rule | first-last ...]

ipfw [−f | −q] flush

ipfw [−q] {delete | zero | resetlog} [set] [number ...]

ipfw enable {firewall | one_pass | debug | verbose | dyn_keepalive}

ipfw disable {firewall | one_pass | debug | verbose | dyn_keepalive}

ipfw set [

                 disable number ...] [enable number ...]

ipfw set move [rule] number to number
ipfw set swap
number number
ipfw set show

ipfw table number add addr[
/masklen] [value]
ipfw table
number delete addr[/masklen]
ipfw table
number flush
ipfw table
number list

ipfw {pipe | queue} number config config-options
ipfw
[−s [field]] {pipe | queue} {delete | list | show} [number ...]

ipfw [−cfnNqS] [
−p
preproc [
preproc-flags
]] pathname

解説

ipfw とそのユーティリティは FreeBSD の ipfw(4) ファイアウォールと dummynet(4) トラフィックシェイパを制御するユーザインタフェースです。

: このマニュアルページは 2002 年 7 月に FreeBSD 5.0 に導入され ipfw2 としても知られている ipfw の新バージョンについて説明していま す。 ipfw2 は旧版のファイアウォール ipfw1 のスーパセットです。この 2 つの違いはセクション IPFW2 拡張に列挙されています。古いルールセットを 書き直し、より効率的にするために、ここを読むことをお勧めします。 FreeBSD 4.x で ipfw2 を実行する手順については、セクション FreeBSD 4.xIPFW2 を使うを参照下さい。

ipfw の設定、もしくは ルールセットは、1 から 65535 までの番号をつけられた ルールのリストからなります。パケットはプロトコルスタック中のいくつかの箇 所から ipfw に渡されます (パケットの発信元と宛先によっては、 ipfw は同じ パケットに対して複数回起動させられる可能性があります)。ファイアウォールに 渡されるパケットはファイアウォールの ルールセット中のルールそれぞれに対し て照合されます。

マッチした場合、マッチしたルールに対応するアクションが実行されます。アク ションと実際のシステムの設定によっては、マッチしたルールの後のルールでさ らに処理を行うためにパケットがファイアウォールに再注入されることがありま す。

ipfw ルールセットには常に デフォルトルール (番号 65535) が含まれます。こ のルールは変更も削除もできず、全パケットにマッチします。 デフォルトルール に関連付けられるアクションは denyallow のどちらかになりますが、これは どのようにカーネルを設定したかに依存します。

ルールセットがオプション keep-state または limit 付きのルールを含む場合、 ipfw は ステートフル (状態依存型) で動作します。すなわち、あるマッチの結 果、マッチしたパケットのパラメータにちょうど一致するルールが動的に生成さ れます。

これらの動的ルールの生存時間は有限で、 check-state または keep-state また は limit ルールが最初に生じた場所でチェックされます。動的ルールは、普通、 正当なトラフィックをオンデマンドでファイアウォールを通過させるために用い ます。 ipfw のステートフルな動作について更に情報が必要ならば、以下の ス テートフルファイアウォールセクションと 使用例セクションを参照して下さい。

全てのルール(動的ルールを含む)は、関連するカウンタをいくつか持っていま す。それらは、パケットカウント、バイトカウント、ログカウント、最後にマッ チした時刻を示すタイムスタンプです。カウンタは、 ipfw コマンドによって表 示することができ、またリセットすることができます。

ルールの追加は add コマンドにて可能です。ルールひとつひとつ、またはまとめ ての削除は delete コマンドにて可能であり、(セット 31 以外の) すべてのルー ルの削除は flush コマンドにて可能です。ルールの表示 (オプションでカウンタ 内容を含めることができます) は、 show コマンドおよび list コマンドにて可 能です。最後に、カウンタのリセットは zero コマンドおよび resetlog コマン ドにて可能です。

また、各ルールは 32 個の異なる セットの 1 つに所属し、セットに対する不可 分な操作、例えば有効化・無効化・セットの入れ換え・セット内の全ルールを別 のセットへ移動・セット内の全ルールの削除などを行うための ipfw コマンドが あります。これらは一時的な設定をインストールしたり設定のテストを行ったり するときに便利です。 セットに関する詳細はセクション ルールセットを参照し て下さい。

次のオプションが利用可能です:

       −a

ルールのリストを表示する際に、カウンタ値を示します。 show コマン ドは、このオプションを暗黙的に指定しただけのものです。

−b
アクションとコメントのみを表示します。ルールのボディは表示しませ ん。 −c が暗黙のうちに指定されます。

−c
ルールを入力したり参照したりするときに、コンパクトな書式でルール を表示します。つまり、ルールが何の追加情報も持たないときは、オプ ショナルな文字列 "ip from any to any" を表示しません。

−d
ルールのリストを表示する際に、静的ルールに加えて動的ルールも表示 します。

−e
ルールのリストを表示する際に、もし −d オプションが指定されていれ ば、期限切れの動的ルールも表示します。

−f
誤って使用すると問題を起す可能性のあるコマンド、 すなわち flush に対して、実行の確認を行いません。プロセスに関連付けられた tty が 無い場合、このオプションが暗黙のうちに指定されたとして処理されま す。

−n
コマンド文字列の文法だけをチェックし、実際にはカーネルには渡しま せん。

−N
出力に含まれるアドレスとサービス名の名前解決を試みます。

−q
add
, zero, resetlog, flush を実行する際、動作について報告しません (暗黙のうちに −f が指定されます)。スクリプト (例えば ‘sh /etc/rc.firewall’) の中で複数の ipfw コマンドを実行してルール を変更する場合や、リモートログインセッション経由で多数の ipfw ルールを含むファイルを処理することによりルールを変更する場合に有 用です。通常 (冗長) モードで (デフォルトカーネル設定で) flush を 行った場合、メッセージを表示します。すべてのルールが捨てられます ので、メッセージはログインセッションへ渡せません。つまり、リモー トログインセッション経由の場合、セッションはクローズされ、残りの ルールセットは処理されません。この状態から回復するためにはコン ソールへのアクセスが必要になります。

−S
ルールのリストを表示する際に、各ルールが属する セットを表示しま す。このフラグが指定されていなければ、無効化されているルールは表 示されません。

−s [field]
パイプ経由でリスト出力している際に、4 つのカウンタの 1 つについて 整列させます (総パケット数/バイト数または現在のパケット数/バイト 数)。

−t
ルールのリストを表示する際に、最後にマッチしたタイムスタンプを表 示します (ctime() で変換されます)。

−T
ルールのリストを表示する際に、最後にマッチしたタイムスタンプを表 示します (基準時点からの秒で表示されます)。この書式の方が、スクリ プトでの後処理に向いています。

冒頭の書式の行で示したように、設定を簡単にするため、ルールを ipfw に処理 させるファイルに記述することができます。 pathname には絶対パス名を使用す る必要があります。このファイルからは 1 行ずつ読み込まれ、 ipfw ユーティリ ティの引数として受け付けられます。

−p preproc を使用して、 pathname がパイプされるプリプロセッサを指定するこ ともできます。有用なプリプロセッサには、 cpp(1)m4(1) があります。 preproc の最初の文字がスラッシュ (‘/’) から始まらない場合、 PATH を使用し た通常の名前検索が行われます。 ipfw が実行されるときまでに全ファイルシス テムが (まだ) マウントされないような環境 (例えば NFS 経由でマウントされる 場合) では、このことに注意してください。ひとたび −p が指定されると、以降 の引数がプリプロセッサに渡されます。これにより、(ローカルホスト名により条 件付けするなど) 柔軟性のある設定ファイルを作成可能となり、IP アドレスのよ うに頻繁に必要となる引数を集中管理するためのマクロを使用可能となります。

後述の トラフィックシェイパ (DUMMYNET) 設定セクションで示すように、 ipfw pipe および queue コマンドを使用して、トラフィックシェイパを構築可能で す。

世界とカーネルの調子が外れると、 ipfw ABI が壊れてしまい、いかなるルール も追加できなくなります。これはブートに悪影響があり得ます。 ipfw disable firewall で、一時的にファイアウォールを無効化することで、ネットワークアク セスを再取得して問題解決できます。

パケットフロー

1 個のパケットが、プロトコルスタックの複数の場所で、有効なルールセットに 対しチェックされます。このチェックはいくつかの sysctl 変数に基づきます。 これらの場所と変数を以下に示します。ルールセットを正しく設計するために は、この図をよく理解することが大切です。

            ^     to upper layers   V
            |                       |
            +----------->-----------+
            ^                       V
       [ip_input]              [ip_output]   net.inet.ip.fw.enable=1
            |                       |
            ^                       V
      [ether_demux]    [ether_output_frame]  net.link.ether.ipfw=1
            |                       |
            +-->--[bdg_forward]-->--+        net.link.ether.bridge_ipfw=1
            ^                       V
            |      to devices       |

上図に示されるように、同一のパケットがファイアウォールを通過する回数は、 パケットの発信元や宛先、システムの設定により、 0 回から 4 回の範囲で変動 します。

パケットがスタックを通過するにつれヘッダが削除 / 追加される可能性があり、 ヘッダがチェックに使えたり使えなかったりすることに注意して下さい。例え ば、外から入ってくるパケットは ether_demux() から ipfw が実行されるときに は MAC ヘッダを含んでいるはずですが、その同じパケットが、 ip_input() から ipfw が実行されたときには MAC ヘッダは取り除かれているはずです。

また、各パケットは常にルールセット全体に対しチェックされることにも注意し てください。これは、チェックが生じた場所、パケットのソースに関係ありませ ん。実行された箇所によっては無効となるようなマッチパターンやアクション ( 例えば、 ip_input() 中で MAC ヘッダとマッチを試みるようなもの) をルールが 含んでいるなら、そのパターンはマッチしないことになります。とはいえ、その ようなパターンの前に not オペレータを記述すれば、このパターンは 常にその ようなパケットにマッチすることになります。したがって、必要に応じ、生じ得 る場所の違いを理解して、適切なルールセットを記述することはプログラマの責 任です。そこで skipto ルールが役に立つことでしょう。例えば次のようにしま す。

      # ether_demux または bdg_forward からのパケット
      ipfw add 10 skipto 1000 all from any to any layer2 in
      # ip_input からのパケット
      ipfw add 10 skipto 2000 all from any to any not layer2 in
      # ip_output からのパケット
      ipfw add 10 skipto 3000 all from any to any not layer2 out
      # ether_output_frame からのパケット
      ipfw add 10 skipto 4000 all from any to any layer2 out

(そうです、今のところ ether_demux と bdg_forward とを区別する方法はありま せん)。

文法

一般に、各キーワードもしくは引数は、別々のコマンド行引数として与えられ、 その前や後には空白は付きません。キーワードは、大文字小文字を区別します が、引数は、その性質に依存し、大文字小文字を区別するかもしれませんし、し ないかもしれません (例えば uid は区別しますが、hostname はしません)。

ipfw2 では、コンマ ’,’ の後に空白を入れ、行を読み易くできます。また、コマ ンド全体 (フラグを含む) を、単一引数に入れられます。例えば、次の書式は等 価です:

      ipfw -q add deny src-ip 10.0.0.0/24,127.0.0.1/8
      ipfw -q add deny src-ip 10.0.0.0/24, 127.0.0.1/8
      ipfw "-q add deny src-ip 10.0.0.0/24, 127.0.0.1/8"

ルール書式

ipfw ルールの書式は次の通りです。

[rule_number] [set set_number] [prob match_probability]
action
[log [logamount number]] body

この中で、ルールのボディ (body) は次の中からどの情報を使用してパケットを フィルタするかを指定します。

          レイヤ 2 ヘッダフィールド

可能ならば
IPv4 プロトコル
TCP, UDP, ICMP など
送信元および宛先のアドレスとポート
方向
セクション パケットフローを参照 して下さい
送信および受信インタフェース
名前またはアドレス
その他の IP ヘッダフィールド
バージョン、サービスタイプ、デー タグラム長、識別子、フラグメント フラグ (0 でない IP オフセッ ト)、生存時間
IP オプション
その他の TCP ヘッダフィールド
TCP フラグ (SYN, FIN, ACK, RST など)、シーケンス番号、確認応答 番号、ウィンドウ
TCP オプション
ICMP タイプ
ICMP パケットの場合
ユーザ/グループ ID
パケットをローカルソケットに関連 づけることが可能な場合

上記の情報のうち幾つか、例えば、送信元 MAC アドレスまたは IP アドレスと TCP/UDP ポートは容易に詐称が可能であることに注意して下さい。したがって、 これらのフィールドのみでフィルタすることは必ずしも望ましい結果を保証しま せん。

rule_number
各ルールは、1 から 65535 の範囲の rule_number に関連づけられてお り、後者は デフォルトルールのために予約されています。ルールはルー ル番号の順にチェックされます。複数のルールが同一の番号を持つこと が可能で、その場合は追加された順序でチェックされます (表示する場 合も同様です) 。番号の指定なしでルールが入力された場合、カーネル は、そのルールが デフォルトルールより前にあるルールの中で最後にな るように割り当てます。自動的につけられるルール番号は、デフォルト を除いた中で最後となるルール番号を、 sysctl 変数 net.inet.ip.fw.autoinc_step の値だけ増加させて割り当てられます。 この変数のデフォルトは 100 です。もし、この操作が (例えば許可され た最大ルール番号を越えるといった理由で) 不可能であれば、最後のデ フォルトでない値が代わりに使用されます。

set set_number
各ルールは 0 から 31 の範囲の set_number に関連づけられています。 セットは個別に無効化したり有効化したりすることができます。した がって、このパラメータは不可分なルールセット操作を行うために必要 不可欠なものです。このパラメータを使うことで、ルールをまとめて削 除することを単純にすることもできます。セット番号を指定せずにルー ルを入力した場合、セット 0 が使用されます。
セット 31 は特別であり、無効化できませんし、この中のルールは ipfw flush コマンドで削除できません (しかし、 ipfw delete set 31 コマ ンドで削除するこはできます)。セット 31 はまた、 デフォルトルール としても使用されます。

prob match_probability
指定した確率 (0 から 1 までの浮動小数点数です) でしかマッチしない マッチを宣言します。ランダムにパケットを落とす応用や、 (dummynet(4) と共に使用して) パケット到達順序の乱れを引き起こす複 数経路の効果をシミュレートする応用など、多くの応用に有用です。

注: この条件は、他の条件の前にチェックされます。これに は、keep-state や check-state といった副作用のあるものも含まれま す。

log [logamount number]
パケットが log キーワードを持ったルールにマッチした場合、メッセー ジが syslogd(8) に LOG_SECURITY ファシリティで記録されます。 sysctl 変数 net.inet.ip.fw.verbose が 1 (カーネルが IPFIREWALL_VERBOSE でコンパイルされていればこれがデフォルトです) に設定されており、そのルールについてこれまで記録されたパケットの 数がその logamount パラメータを越えていなければ、記録が行われま す。 logamount が指定されていなければ、制限は sysctl 変数 net.inet.ip.fw.verbose_limit から参照されます。両者の値が 0 であ れば記録の制限は取り除かれます。

一度制限に達したなら、このエントリに対するロギングカウンタかパ ケットカウンタをクリアすれば記録を再び有効にすることができます。 resetlog コマンドを参照して下さい。

注: ログが実行されるのは、すべてのパケットマッチ条件が成功裏に確 認された後であり、最後の動作 (受理や拒否等) をパケットに実施する 前です。

ルールアクション
ルールは次に示すアクションの 1 つと関連づけることができます。これはパケッ トがルールのボディにマッチしたときに実行されます。

allow | accept | pass | permit
ルールにマッチするパケットを受け付けます。検索は終了します。

check-state
動的ルールセットに対してパケットのチェックを行ないます。マッチし た場合、その動的ルールを生成したルールに関連づけられたアクション を実行し、マッチしなかった場合、次のルールに移ります。
check-state
ルールはボディを持ちません。 check-state ルールが見つ からないときは、動的ルールセットは最初の keep-state ルール、もし くは limit ルールの場所でチェックされます。

count
ルールにマッチした全てのパケットのカウンタを更新します。検索は次 のルールへ続行します。

deny | drop
ルールにマッチした全てのパケットを破棄します。検索は終了します。

divert port
ルールにマッチするパケットをポート port にバインドされている divert(4) ソケットに送出します。検索は終了します。

fwd | forward ipaddr[,port]
マッチしたパケットの次のホップを ipaddr に変更します。これには IP アドレスとして、数字 4 つ組形式またはホスト名が使用できます。この ルールにマッチした場合、検索は終了します。

ipaddr がローカルアドレスの場合、マッチしたパケットはローカルマシ ンの port (または、ルールで指定されていない場合はそのパケットの ポート番号) に転送されます。
ipaddr
がローカルアドレスでない場合、ポート番号は (指定されていて も) 無視され、パケットはローカルな経路テーブルに存在するその IP に対する経路を使用してリモートアドレスに転送されます。
fwd
ルールはレイヤ 2 パケット (それらは ether_input, ether_output, bridged で受信されます) にはマッチしません。
fwd
アクションはパケットの内容をまったく変更しません。実際、宛先 アドレスが修正されずに残るので、転送先システムがそのようなパケッ トを取り込むルールを持たない限り、他のシステムに転送されたパケッ トは、通常転送先のシステムで拒否されます。ローカルに転送されるパ ケットの場合、ソケットのローカルアドレスはパケットが元々持ってい た宛先アドレスに設定されます。このことによって netstat(1) が出力 するエントリは若干奇妙な見え方になりますが、これは透過プロキシ サーバでの使用を意図しています。

fwd を有効にするには、カーネルをオプション options IPFIREWALL_FORWARD を付けてコンパイルすることが必要です。追加のオ プション options IPFIREWALL_FORWARD_EXTENDED を指定することで、安 全策がすべて外され、ローカルに設定された IP アドレス宛のパケット をリダイレクトすることも可能になります。そのようなルールはローカ ルに生成されたパケットにも適用されるので、 ICMP メッセージサイズ 超過などのような自動的に生成されるパケットが適切に振る舞うよう細 心の注意が必要なことに注意して下さい。

pipe pipe_nr
パケットを dummynet(4) ‘‘パイプ’’ (バンド幅制限、遅延などに使用さ れます) へ渡します。詳しい情報については トラフィックシェイパ (DUMMYNET) 設定セクションを参照してください。検索は終了します。し かし、パイプから抜けたときに sysctl(8) 変数 net.inet.ip.fw.one_pass がセットされていない場合、パケットは、す ぐ次のルールから始まるファイアウォールコードへ再度渡されます。

queue queue_nr
パケットを dummynet(4) ‘‘キュー’’ (WF2Q+ を使ったバンド幅制限に使 用されます) へ渡します。

reject
(非推奨)。 unreach host と同義です。

reset
このルールにマッチしたパケットを破棄します。さらに、そのパケット が TCP パケットであれば、 TCP リセット (RST) 通知を送出しようと試 みます。検索は終了します。

skipto number
それ以降のルールのうち number より小さな番号のものすべてを飛び越 して、 number 以上の番号のルールで最初に存在するものから、検索を 継続します。

tee port
このルールにマッチしたパケットの複製を、ポート port にバインドさ れた divert(4) ソケットに送出します。検索は、その次のルールへ継続 されます。

unreach code
このルールにマッチしたパケットを破棄し、コード code の ICMP 到達 不可通知を送出しようと試みます。ここで code は 0 から 255 の数 字、または次のエイリアスのいずれかです: net, host, protocol, port, needfrag, srcfail, net-unknown, host-unknown, isolated, net-prohib, host-prohib, tosnet, toshost, filter-prohib, host-precedence, precedence-cutoff 。検索は終了します。

ルールボディ
ルールのボディは 0 個以上のパターン (送信元と宛先アドレスやポートの指定、 プロトコルオプション、受信または送信インタフェースの指定など) を含みま す。このパターンはパケットを識別するためにマッチしなければならないもので す。一般に、パターンは (暗黙的に) and オペレータで接続されます -- つま り、ルールがマッチするためには全てがマッチしなければなりません。個々のパ ターンには、マッチの結果を反転させるために not オペレータを前置することが できます。これは次のようになります。

ipfw add 100 allow ip from not 1.2.3.4 to any

さらに、次のように or オペレータを使用し、丸括弧 () や ブレース {} で括ら れた内部にパターンを列挙することで、新しいマッチパターンのセット ( 論理和 ブロック ) を構築することができます:

ipfw add 100 allow ip from { x or not y or z } to any

括弧のレベルは 1 つのみが可能です。ほとんどのシェルが丸括弧やブレースに特 別な意味を持たせていることに注意して下さい。したがって、そのような解釈が 起こらないようにバックスラッシュ \ をその前に置くことを勧めます。

ルールのボディは、一般に送信元と宛先アドレスの指定を含まなければなりませ ん。キーワード any は必須フィールドの内容が重要でないことを指定するために 様々な箇所で使用することができます。

ルールボディは以下の書式で指定します。

[proto from src to dst] [options]

最初の部分 (proto from src to dst) は ipfw1 との後方互換のためにありま す。 ipfw2 では、任意のマッチパターン (MAC ヘッダ、IPv4 プロトコル、アド レス、ポートを含む) が options セクションで指定できます。

ルールフィールドは以下の意味を持ちます。

       proto: protocol | { protocol or ... }

protocol: [
not
] protocol-name | protocol-number
IPv4 におけるプロトコルを、数字や名前で指定します (完全なリストは /etc/protocols を参照して下さい)。 ip または all のキーワードを使 用すると、すべてのプロトコルがマッチします。

{ protocol or ... } 書式 (論理和ブロック) は、簡便さのためだけに 提供されており、価値が低下しています。

src and dst: {
addr
| { addr or ... }} [[
not
] ports]
単一のアドレス (またはリスト、後述) で、オプションとして、その後 に ports 指示子を続けて置くことができます。

第 2 の書式 (複数アドレス付きの 論理和ブロック) は、簡便さのため だけに提供されており、価値が低下しています。

addr: [
not
] {
any
| me | table(number[,value]) | addr-list | addr-set}

any
任意の IP アドレスがマッチします。

me
システムのインタフェースに設定された任意の IP アドレスがマッチし ます。アドレスのリストはパケットが解析されるときに評価されます。

table(number[,value])
検索表 number に存在するエントリに対応する任意の IP アドレスが マッチします。オプションの 32 ビット符号なし整数 value も指定され た場合には、その値のエントリにのみマッチします。検索表に関する詳 細は下記の 検索表セクションを参照して下さい。

addr-list: ip-addr[,addr-list]

ip-addr:
次の方法で指定される、ホストもしくはサブネットのアドレス:

numeric-ip | hostname
ドットで区切った数字 4 つ組またはホスト名で指定した、 1 つの IPv4 アドレスがマッチします。ホスト名の名前解決は、 そのルールがファイアウォールのリストに追加されるときに行 われます。

addr/masklen
ベースとなる addr (ドットで区切った数字 4 つ組またはホス ト名で指定します) と masklen ビット幅のマスクに一致する全 てのアドレスがマッチします。例えば、1.2.3.4/25 は 1.2.3.0 から 1.2.3.127 までの全ての IP アドレスがマッチすることに なります。

addr:mask
ベースアドレスが addr (ドットで区切った 4 つの数字または ホスト名で指定されます) であり、マスクが mask (ドットで区 切った 4 つの数字で指定されます) である全てのアドレスに マッチします。例えば、1.2.3.4:255.0.255.0 は、1.*.3.* に マッチします。この形式は、連続でないマスクの場合にだけ使 用することを推奨します。連続なマスクの場合は、よりコンパ クトでより間違いにくい、 addr/masklen を使います。

addr-set: addr[
/masklen]{list}

list: {
num
| num-num}[,list]
ベースアドレスが addr (ドットで区切った数字 4 つ組またはホスト名 で指定します) であり、最後のバイトがブレース {} の中に列挙されて いる全てのアドレスがマッチします。ブレースと数字の間には空白を置 いてはいけないことに注意して下さい (コンマの後の空白は許されてい ます)。リストの要素は、単一項目もしくは範囲が指定可能です。 masklen フィールドはアドレスのセットのサイズに制限をつけるために 使用され、 24 から 32 の間の任意の値をとることができます。指定さ れない場合 24 が仮定されます。
この書式は 1 つのルールでまばらなアドレス群を取り扱うときに特に便 利です。ビットマスクを使用してマッチを行うので、定数時間で処理で き、ルールセットの複雑さが劇的に減少します。
例えば、アドレスを 1.2.3.4/24{128,35-55,89} として指定した場合、 次のアドレスがマッチします:
1.2.3.128, 1.2.3.35 to 1.2.3.55, 1.2.3.89 .

ports: {
port
| port-port}[,ports]
(TCP や UDP などのように) ポート番号をサポートしているプロトコル について、オプションとして、 ports を指定することができます。 1 つ以上のポートまたはポートの範囲を空白なしのコンマ区切りで指定し ます。さらにオプションとして、 not オペレータを付加して指定するこ とができます。記号 ‘-’ による表現は、ポート範囲 (両端含む) を指定 します。

ポート数値の代わりに (ファイル /etc/services から取った) サービス 名を使用できます。ポートリストの長さは 30 ポートまたはポート範囲 に制限されていますが、ルールの options セクションで 論理和ブロッ クを使用することにより、より広い範囲を指定することができます。

バックスラッシュ (‘\’) を使用することにより、サービス名中のダッ シュ (‘-’) 文字をエスケープ可能です (シェルから入力するとき、シェ ル自身がバックスラッシュをエスケープ文字として解釈するのをさける ために、バックスラッシュを 2 回タイプしなければなりません)。

ipfw add count tcp from any ftp\\-data-ftp to any

断片化されたパケットでオフセットが非 0 のもの (すなわち、最初の断 片ではないもの) は、 1 つ以上のポート指定を持つルールにはマッチし ません。断片化されたパケットへのマッチングに関する詳細は frag オ プションを参照してください。

ルールオプション (マッチパターン)
ルール内で追加のマッチパターンを使用することができます。これらはルール内 に 0 個以上置けるので オプションと呼ばれており、オプションで not オペラン ドを前置することができ、 論理和ブロックとしてグループ化することが可能で す。

以下のマッチパターンが使用できます (アルファベット順に並べています)。

// this is a comment.
指定したテキストを、ルール中にコメントとして挿入します。 // に続 くすべてがコメントとして扱われ、ルール中に格納されます。コメント のみのルールを持つことも可能であり、それは count アクションに続い てコメントが表示されます。

bridged
layer2
の別名です。

dst-ip ip-address
宛先 IP アドレスが引数で指定したアドレスの 1 つである IP パケット にマッチします。

dst-port ports
宛先ポートが引数で指定したポートの 1 つである IP パケットにマッチ します。

established
RST か ACK ビットがセットされている TCP パケットにマッチします。

frag
IP データグラムのフラグメントであり、かつ、最初のフラグメントでな いパケットにマッチします。これらのパケットは次のプロトコルヘッダ (例えば TCP, UDP) を持たないので、これらのヘッダを調べるオプショ ンはマッチすることができないことに注意して下さい。

gid group
group
によって送信された、またはそれに対して受信された全ての TCP もしくは UDP パケットにマッチします。 group は名前か数値で指定す ることができます。

jail prisonID
prison ID が prisonID である jail によって送信された、またはそれ に対して受信された全ての TCP もしくは UDP パケットにマッチしま す。

icmptypes types
types
で指定したリスト中に存在する ICMP タイプを持つ ICMP パケッ トにマッチします。リストはタイプおのおのをコンマで区切ったもので す。 範囲は許されません。サポートされている ICMP タイプは次の通り です。

エコー応答 (0), 宛先到達不可 (3), 発信元抑制 (4), リダイレクト (5), エコー要求 (8), ルータ広告 (9), ルータ要請 (10), 時間超過 (11), IP ヘッダ異常 (12), タイムスタンプ要求 (13), タイムスタンプ 応答 (14), インフォメーション要求 (15), インフォメーション返答 (16), アドレスマスク要求 (17), アドレスマスク応答 (18)

in | out
それぞれ到着または送出パケットにマッチします。 inout は互いに 排他的です (実際、 outnot in として実装されています)。

ipid id-list
ip_id
フィールドが id-list に含まれる IP パケットにマッチします。 id-list は、単一の値か、 ports と同等の方法で指定される、値のリス トか範囲です。

iplen len-list
ヘッダとデータを含んだ全体の長さが len-list に含まれる IP パケッ トにマッチします。 len-list は、単一の値か、 ports と同等の方法で 指定される、値のリストか範囲です。

ipoptions spec
spec
で指定したコンマ区切りリストオプションを含む IP ヘッダを持つ パケットにマッチします。 IP オプションは次のものがサポートされて います:

ssrr (ストリクトソースルーティング), lsrr (ルーズソースルーティン グ), rr (レコードルート), ts (タイムスタンプ)。 ‘!’ を置くことで 特定のオプションが存在しないという記述ができます。

ipprecedence precedence
先行フィールドが precedence に等しい IP パケットにマッチします。

ipsec
IPSEC ヒストリを持つパケットにマッチします (すなわち、入力パケッ トが IPSEC でカプセル化されており、カーネルが IPSEC と IPSEC_FILTERGIF のオプションをサポートし、正しくパケットのカプセ ル化を解除できた場合です)。

ipsec を指定することは、 proto ipsec を指定することとは違います。 何故なら後者は、IPSEC カーネルサポートの有無および IPSEC データの 正当性にかかわらず、特定の IP プロトコルフィールドのみを見るから です。

更に、IPSEC サポート無しのカーネルでは、このオプションは黙って無 視されることに注意してください。この場合、このフラグを指定しても ルール処理に影響が無く、あたかも ipsec フラグが指定されていないか のように当該ルールが処理されます。

iptos spec
spec
で指定したコンマ区切りリストのサービスタイプを含む tos フィールドを持つ IP パケットにマッチします。サポートされている サービスの IP タイプは次の通りです。

lowdelay (IPTOS_LOWDELAY), throughput (IPTOS_THROUGHPUT), reliability (IPTOS_RELIABILITY), mincost (IPTOS_MINCOST), congestion (IPTOS_CE) 。 ‘!’ を置くことで特定のオプションが存在し ないという記述ができます。

ipttl ttl-list
生存時間が ttl-list に含まれる IP パケットにマッチします。 ttl-list は、単一の値か、 ports と同等の方法で指定される、値のリ ストか範囲です。

ipversion ver
IP バージョンフィールドが ver である IP パケットにマッチします。

keep-state
マッチする際に、ファイアウォールは動的ルールを作成します。作成さ れるルールは、デフォルトでは、同じプロトコルを使用している発信元 と宛先 IP/ポート間での双方向のトラフィックにマッチするような動作 となります。このルールには有限の生存時間 (sysctl(8) 変数の集合に より制御されます) があり、生存時間はマッチするパケットが見つかる たびにリフレッシュされます。

layer2
レイヤ 2 のパケット、つまり、 ether_demux() と ether_output_frame() から ipfw へ渡されるパケットのみにマッチしま す。

limit {
src-addr
| src-port | dst-addr | dst-port} N
ファイアウォールは、このルールで指定したものと同じパラメータの集 合を持つ接続を、 N 個だけ許可します。 1 つ以上の発信元と宛先アド レスおよびポートが指定できます。

{ MAC | mac } dst-mac src-mac
与えられた dst-mac アドレスと src-mac アドレスを持つパケットに マッチします。アドレスは、 any キーワード (任意の MAC アドレスに マッチします) またはコロンで区切った 16 進数 6 個の組で指定しま す。この 6 個組アドレスの後ろには、オプションとして、重要なビット を表現するマスクをつけることができます。マスクは次のいずれかの方 法で指定可能です:

1. スラッシュ (/) に続けて、重要なビット数を指定します。例え ば、重要なビットが 33 ビットであるアドレスは次のように指 定します:

MAC 10:20:30:40:50:60/33 any

2. アンパサンド (&) に続けて、コロン区切りの 6 組の 16 進数 として指定されるビットマスクを指定します。例えば、最後の 16 ビットが重要であるアドレスは次のように指定します:

MAC 10:20:30:40:50:60&00:00:00:00:ff:ff any

多くのシェルでアンパサンド文字は特別な意味を持ちますの で、普通はエスケープが必要であることに注意してください。

MAC アドレスの順序 (宛先が最初で 2 番目に発信元) は物理的な線上の ものと同じですが、 IP アドレスで使用されるものとは反対であること に注意して下さい。

mac-type mac-type
イーサネットタイプフィールドが引数で指定したものの 1 つと一致する パケットにマッチします。 mac-typeport numbers と同じ方法で指 定します (つまり、単一の値または範囲が、1 個以上コンマで区切られ たものです)。 vlan, ipv4, ipv6 のような既知の値に対しては、シンボ ル名称を使用することができます。値は 10 進数か 16 進数 (0x が頭に つく場合) で入力することができ、常に 16 進数で出力されます (これ は -N オプションが使用されていない場合です。 -N オプションが使用 されるとシンボル名称の解決が試みられます)。

proto protocol
対応する IPv4 のプロトコルを持つパケットがマッチします。

recv | xmit | via {ifX | if* | ipno | any}
指定したインタフェースから受信したパケット、送信したパケット、通 過したパケットがそれぞれマッチします。インタフェースの指定は、正 確な名前 (ifX) 、またはデバイス名 (if*) 、 IP アドレスで行なう か、もしくは何らかのインタフェースを通じて行ないます。

via キーワードにより、指定したインタフェースが常にチェックされる ことになります。 recvxmitvia の代わりに使用された場合、そ れぞれ、受信インタフェースのみ、または送信インタフェースのみが チェックされます。両方とも指定した場合、送信インタフェースと受信 インタフェースの両方に基づくパケットのマッチが可能になります。例 えば次のようになります。

ipfw add deny ip from any to any out recv ed0 xmit ed1

recv インタフェースは到着または送出パケットのどちらかについて検査 することができますが、 xmit インタフェースは送出パケットのみにつ いて検査することができます。したがって xmit を使用する場合には out は必須です (そして in は無効となります)。

パケットが受信インタフェースや送信インタフェースを持たないことが あります。ローカルホストから発生したパケットは受信インタフェース を持ちませんし、ローカルホストに到着する予定のパケットは送信イン タフェースを持ちません。

setup
SYN ビットがセットされているが ACK ビットを持たない TCP パケット にマッチします。これは ‘‘tcpflags syn,!ack’’ の短縮形です。

src-ip ip-address
引数で指定したアドレスの 1 個を発信元 IP として持つ IP パケットが マッチします。

src-port ports
引数で指定したポートの 1 個を発信元ポートとして持つ IP パケットが マッチします。

tcpack ack
TCP パケットのみです。 TCP ヘッダの確認応答番号フィールドが ack に設定されていればマッチします。

tcpflags spec
TCP パケットのみです。 TCP ヘッダが spec で指定したコンマ区切りの フラグのリストを含んでいればマッチします。サポートされている TCP フラグは次の通りです。

fin, syn, rst, psh, ack, urg 。 ‘!’ を置くことで特定のフラグが存 在しないという記述ができます。 tcpflags の指定を含むルールは、0 でないオフセットを持つフラグメントパケットには決してマッチするこ とはありえません。フラグメントパケットのマッチについての詳細は frag オプションを参照して下さい。

tcpseq seq
TCP パケットのみです。 TCP ヘッダのシーケンス番号フィールドが seq に設定されていればマッチします。

tcpwin win
TCP パケットのみです。 TCP ヘッダのウィンドウフィールドが win に 設定されていればマッチします。

tcpoptions spec
TCP パケットのみです。 spec で指定したコンマ区切りのオプションの リストが TCP ヘッダに含まれていればマッチします。サポートされてい る TCP オプションは次の通りです。

mss (最大セグメントサイズ), window (TCP ウィンドウ広告), sack (選 択的 ACK), ts (RFC1323 タイムスタンプ), cc (RFC1644 T/TCP コネク ションカウント)。 ‘!’ を置くことで特定のオプションが存在しないと いう記述ができます。

uid user
user
が送信したまたは受信する、すべての TCP パケットと UDP パケッ トにマッチします。 user は、名前でも ID 番号でもマッチします。

verrevpath
内向きパケットに対しては、パケットのソースアドレスに対し、経路 テーブルが検索されます。パケットがシステムに入って来たインタ フェースと、経路の出力インタフェースがマッチする場合、パケットは マッチします。インタフェースがマッチしない場合、パケットはマッチ しません。外向きパケットや、入力インタフェースを持たないパケット は、マッチします。

このオプションの名称と機能は、意図的に下記 Cisco IOS コマンドと同 じです:

ip verify unicast reverse-path

本オプションは、このインタフェースのものではないソースアドレスを 持つパケットをすべて拒否する対スプーフィングルールを作成するのに 使用可能です。 antispoof オプションも参照して下さい。

versrcreach
内向きパケットに対しては、パケットのソースアドレスに対し、経路 テーブルが検索されます。ソースアドレスへの経路は存在するが、デ フォルトの経路でない場合やブラックホール経路、拒否されてる経路で ある場合に、パケットはマッチします。そうでなければ、パケットは マッチしません。外向きパケットはすべてマッチします。

このオプションの名称と機能は、意図的に下記 Cisco IOS コマンドと同 じです:

ip verify unicast source reachable-via any

本オプションは、ソースアドレスが到達可能でないパケットをすべて拒 否する対スプーフィングルールを作成するのに使用可能です。

antispoof
内向きパケットに対しては、パケットのソースアドレスが直接接続され ているネットワークに属するものかどうか確認します。ネットワークが 直接接続されていれば、パケットを受信したインタフェースはネット ワークに接続されているインタフェースと比較されます。受信インタ フェースと直接接続されているインタフェースが同一でなければ、パ ケットはマッチしません。そうでなければパケットはマッチします。外 向きパケットはすべてマッチします。

本オプションは、直接接続されたネットワークから来たふりをしている のにそのインタフェース経由で入ってきていないパケットをすべて拒否 する対スプーフィングルールを作成するのに使用可能です。本オプショ ンは verrevpath と似ていますが、ソースアドレスすべての代わりに、 直接接続されたネットワークのソースアドレスを持つパケットを対象と するのでより限定的です。

検索表

検索表は分散した大量のアドレス、典型的には 100 から数千のエントリを取り扱 うのに便利です。 0 から 127 までの 128 個の異なる検索表を持てます。

各エントリは addr[/masklen] で表され、 (ドットで区切った数字 4 つ組もしく はホスト名で指定された) ベースアドレス addrmasklen ビット幅のマスクで 表されるアドレスすべてにマッチします。 masklen が指定されていなければ、デ フォルトは 32 です。表で IP アドレスを検索する場合には、最も限定されたエ ントリがマッチします。各エントリには、32 ビット符号なし整数 value が関連 づけられ、ルールマッチコードによりチェックされる場合があります。ルールが 追加された時に value が指定されていなければ、デフォルトは 0 です。

エントリは (add) で表に追加でき、 (delete) で表から削除できます。表は (list) で確認でき、 (flush) でフラッシュします。

内部的には、各表は経路テーブル (route(4) を参照して下さい) と同じように基 数木で保持されています。

ルールのセット

各ルールは 32 個の異なる セットのひとつに属しています。セットには 0 から 31 までの番号をつけられています。セット 31 はデフォルトルールのために予約 されています。

デフォルトでは、新規のルールを入力する際に set N アトリビュートを使用しな ければ、ルールはセット 0 に置かれます。セットは個別に、かつ、不可分に有効 化したり無効化したりできるので、この機構によって、ファイアウォールの設定 を複数個格納し、それらを素早く (かつ不可分に) 切り替えるための方法が簡単 になります。セットを有効化/無効化するコマンドは次の通りです。

ipfw set [

                       disable number ...] [enable number ...]

ここでは複数の enable または disable セクションが指定可能です。コマンドで 指定したセット全てについて、コマンドは不可分に実行されます。デフォルトで は全てのセットは有効化された状態です。

セットを無効化すると、ファイアウォールの設定中にそのルールが存在しないか のように振る舞います。ただし例外が 1 つだけあります。

無効化される以前にルールから生成された動的ルールは、期限切れとなる まではまだ活動可能な状態です。動的ルールを削除するためには、その ルールを生成した親ルールを明示的に削除しなければなりません。

ルールのセット番号は次のコマンドで変更できます。

ipfw set move {rule rule-number | old-set} to new-set

また、次のコマンドを使用して 2 つのルールセットを不可分に入れ換えることが できます。

ipfw set swap first-set second-set

ルールのセットの使い方のいくつかは、 使用例セクションを参照して下さい。

ステートフルファイアウォール

ステートフルオペレーションは、与えられたパターンにマッチするパケットが検 出されたときに、ファイアウォールが特定のフローについてのルールを動的に作 成するための方法です。ステートフルオペレーションに対するサポートは ルールcheck-state, keep-state, limit オプションを通じて提供されます。

動的ルールが生成されるのは、パケットが keep-statelimit ルールにマッチ したときで、その結果、与えられた protocol を持ち、 src-ip/src-port dst-ip/dst-port のアドレスの組の間のパケット全てのみにマッチする 動的ルー ルが生成されます (srcdst はここでは最初にマッチしたアドレスを区別する ためにのみ使用しています。その後、両者は完全に等価になります)。動的ルール は最初に check-state, keep-state, limit が生じたところでチェックされ、 マッチした際に実行されるアクションは親ルールと同じものになります。

動的ルールでは、プロトコル、IP アドレス、ポート以外の属性がチェックされな いことに注意して下さい。

動的ルールの典型的な使い方は、ファイアウォールの設定を閉じた状態にしてお きつつ、内部ネットワークからの最初の TCP SYN パケットに、そのフローに対す る動的ルールをインストールさせ、そのセッションに属するパケットがファイア ウォールを通過できるようにするというものです。

ipfw add check-state

ipfw add allow tcp from my-subnet to any setup keep-state

ipfw add deny tcp from any to any

同様なアプローチが UDP に対しても使えます。内部から来た UDP パケットに動 的ルールをインストールさせ、その応答がファイアウォールを通過するようにし ます。

ipfw add check-state

ipfw add allow udp from my-subnet to any keep-state

ipfw add deny udp from any to any

動的ルールは、ある時間の後、期限切れとなります。その時間は、フローの状態 といくつかの sysctl 変数の設定に依存します。詳細はセクション sysctl 変数 を参照して下さい。 TCP セッションでは、動的ルールに対し、定期的にキープア ライブパケットを送出させるように指示し、期限切れになる頃にルールの状態を リフレッシュさせることができます。

動的ルールの使用方法に関する他の例はセクション 使用例を参照して下さい。

トラフィックシェイパ (DUMMYNET) 設定

ipfw は、 dummynet(4) トラフィックシェイパへのユーザインタフェースも提供 します。

dummynet の動作は、まずファイアウォールを用いてパケットをクラス分けし、そ れらを フロー(flow) に分割します。その際に、 ipfw ルールで使用できる如何 なるマッチパターンをも使用できます。ローカルポリシにより、フロー 1 個に TCP コネクション 1 個のパケットを含めることもできますし、指定したホストの パケットでも、サブネット全体のパケットでも、あるプロトコルタイプのパケッ トでも含めることができます。

同一のフローに属するパケットは、その後、トラフィックへの制限を実装する 2 つのオブジェクトのいずれか一方に渡されます。

           pipe  パイプ (pipe) は、指定したバンド幅、伝搬遅延、キューサイズ、パケット損失率を持つリンク 1 個をエミュレートします。クラス分けを受けた後、パケットは、パイプに入る前にキューに蓄えられ、パイプのパラメータに従いパイプ中を伝送されます。

queue キュー (queue) は、WF2Q+ (Worst-case Fair Weighed Fair Queueing: 最悪均等重み付け均等待ち行列) ポリシを実装するため に用いる抽象化です。このポリシは、WFQ ポリシの効率的な変種で す。
キューは 重み (weight) とパイプの参照を、個々のフローに対応付 けます。同じパイプに結合されバックログを持つ (キューにパケッ トがある) フロー全てで、それぞれの重みに比例してそのパイプの バンド幅を山分けします。重みは優先度ではないことに注意して下 さい。大きい重みを持つフローがずっとバックログを抱えていたと しても、それより軽い重みを持つフローも、バンド幅を自分の割合 の分は得ることは保証されます。

実際の使い方として、 pipe を使い、フローが取り得るバンド幅にハードリミッ トを設けることができます。一方で、 queue を使い、異なるフローがどのように して利用可能なバンド幅を山分けするかを決定することができます。

pipequeue の設定コマンドは次の通りです。

pipe number config pipe-configuration

queue number config queue-configuration

次のパラメータをパイプに対して設定可能です。

       bw bandwidth | device

バンド幅で、単位は [K|M]{bit/s|Byte/s} です。

値 0 (デフォルト) は無限のバンド幅を意味します。単位は、次の

ipfw pipe 1 config bw 300Kbit/s

のように、数値の直後に続けて書く必要があります。次の

ipfw pipe 1 config bw tun0

のように、数値の代りにデバイス名を指定した場合、送信クロックは指 定したデバイスから与えられます。現在のところ、 tun(4) デバイスの みがこの機能を提供しており、 ppp(8) と組み合わせて使用します。

delay ms-delay
伝達遅延時間であり、ミリ秒単位で指定します。値は、クロックティッ クの倍数 (典型的には 10ms ですが、カーネルを ‘‘options HZ=1000’’ で動作させて精度を 1ms かそれ以下にすると良いことが経験的に知られ ています) に丸められます。デフォルト値は 0 であり、遅延無しを意味 します。

次のパラメータをキューに対して設定できます。

pipe pipe_nr
キューを指定したパイプに接続します。複数のキュー (同じ重みの場合 も異なる重みの場合もあります) を同一のパイプに接続することができ ます。パイプはキューの集合に対する集約されたレートを指定します。

weight weight
このキューにマッチするフローに適用する重みを指定します。重みは 1 から 100 の範囲でなければならず、デフォルトは 1 です。

最後に、次のパラメータをパイプやキューに対して設定できます。

buckets hash-table-size
様々なキューを格納するハッシュ表のサイズを指定します。デフォルトは 64 で、 sysctl(8) 変数 net.inet.ip.dummynet.hash_size によって制御 されます。指定可能な範囲は 16 から 65536 までです。

mask mask-specifier
ipfw
ルールにより指定したパイプもしくはキューに対して送られたパケッ トを、さらに複数のフローにクラス分けすることができます。その後、そ れぞれのパケットは、異なる 動的なパイプもしくはキューに送られます。 フロー識別子は、パイプもしくはキューの設定中の mask オプションの指 定に応じて IP アドレス、ポート、プロトコルタイプをマスクすることに より構築されます。異なるフロー識別子それぞれに対し、新しいパイプも しくはキューが元となるオブジェクトと同一のパラメータとともに生成さ れ、マッチするパケットがそこに送られます。

このようにして、 動的パイプを使用するとき、フローそれぞれはパイプで 指定したものと同じバンド幅を得ます。一方、 動的キューを使用する時、 フローそれぞれは、同じキューにより生成された他のフローと、親パイプ のバンド幅を均等に山分けします (異なる重みを持つ他のキューが同じパ イプに接続される場合があることに注意して下さい)。
使用可能なマスク指定子は、次を組み合わせたものです。

dst-ip mask, src-ip mask, dst-port mask, src-port mask, proto mask, all

最後の指定子は、すべてのフィールドのすべてのビットが検査されること を意味しています。

noerror
パケットが dummynet のキューやパイプによって落されたとき、通常は、 デバイスキューが一杯になったときに生じるのと同様な形で、エラーが カーネル内の呼び出し元ルーチンに報告されます。このオプションを設定 すると、パケットの配送に成功したかのように報告されます。これは、遠 隔地にあるルータでの損失や輻輳をシミュレートしたいという一部の実験 的な設定のために必要とされています。

plr packet-loss-rate
パケットの損失率です。引数 packet-loss-rate は 0 から 1 までの浮動 小数点数で、 0 は損失がないことを、1 は 100% 失われることを意味しま す。損失率は内部的には 31 ビットで表現されています。

queue {slots | sizeKbytes}
スロット数 slots または KBytes で表したキューのサイズです。デフォル トは 50 スロットで、これはイーサネットデバイスにおける典型的な キューのサイズです。低速リンクのためにキューのサイズを小さいままに しておくことが推奨されます。そうしないとキューの遅延がトラフィック に及ぼす影響が著しくなるかもしれません。例えば、最大サイズのイーサ ネットパケット (1500 バイト) が 50 個のとき、 600Kbit、 つまり 30Kbit/秒 のパイプで 20 秒ということになります。それよりもずっと大 きな MTU を持ったインタフェース (例えばループバックインタフェースは 16KB パケットです) からパケットを受け取る場合、さらに悪い結果となる ことがあります。

red | gred w_q/min_th/max_th/max_p
RED (Random Early Detection) キュー管理アルゴリズムを使用します。 w_qmax_p は 0 から 1 (0 を含みません) の範囲の浮動小数点数であ り、 min_thmax_th はキュー管理用の閾値を指定する整数です ( キューがバイト数で指定された場合は閾値はバイトで計算され、そうでな い場合はスロット数で計算されます)。 dummynet(4) は、gentle RED とい う変型 (gred) もサポートします。 RED の動作を制御するために、3 個の sysctl(8) 変数を使用可能です。

net.inet.ip.dummynet.red_lookup_depth
リンクがアイドルの時の、平均キューの計算精度を指定します ( デフォルトは 256 であり、0 より大きい必要があります)

net.inet.ip.dummynet.red_avg_pkt_size
パケットサイズの平均の期待値を指定します (デフォルトは 512 であり、0 より大きい必要があります)

net.inet.ip.dummynet.red_max_pkt_size
パケットサイズの最大値の期待値を指定します。キューの閾値が バイトの場合のみ使用されます (デフォルトは 1500 であり、0 より大きい必要があります)

チェックリスト

ルールを構成する際に考慮すべき重要な点をいくつか述べます。

 かならず送信パケットと受信パケットの両方のパケットをフィルタリングします。ほとんどのネットワークコネクションではパケットが双方向に流れることが必要です。

テストは細心の注意を払って行ないます。テストの際にはコンソールの近く にいるのがよいでしょう。コンソールに近寄れない場合、 /usr/share/examples/ipfw/change_rules.sh にあるような自動回復スクリプ トを使用してください。

ループバックインタフェースのことを忘れてはなりません。

細かい事柄

 フラグメント化されたデータグラムが無条件で破棄される状況があります。TCP パケットは、最低 20 バイトの TCP ヘッダを含まない場合、破棄されます。 UDP パケットは、完全な 8 バイトの UDP ヘッダを含まない場合、破棄されます。 ICMP パケットは、4 バイトの ICMP ヘッダ、すなわち ICMP タイプとコードとチェックサムを含まない場合、破棄されます。これらのパケットは、単に ‘‘pullup failed’’ としてログされます。何故なら、パケット中に有意なログエントリを生成するだけの有用なデータが含まれないかもしれないためです。

無条件で破棄されるもう 1 種類のパケットは、フラグメントオフセットが 1 の TCP パケットフラグメントです。これはパケットとしては有効なものです が、利用目的はファイアウォールをかいくぐることしかありません。ログが 有効な場合、これらのパケットはルール -1 により破棄されたと報告されま す。

ネットワーク越しにログインしている場合、 kld(4) バージョンの ipfw を ロードすることはそれほど単純なことではありません。以下のコマンドを奨 めます。

kldload ipfw && \
ipfw add 32000 allow ip from any to any

これに引続き、同じような状況で

      ipfw flush

とするのは良くありません。

 システムセキュリティレベルが 3 以上に設定されている場合、 ipfw フィルタリストを変更できません (システムセキュリティレベルについてはinit(8) を参照してください)。

パケットの行き先変更

指定されたポートにバインドされた divert(4) ソケットは、そのポートへ行き先 変更されたパケットを、全部受けとります。宛先ポートにバインドされたソケッ トがない場合や、カーネルがパケットの行き先変更ソケットをサポートするよう にはコンパイルされていない場合、パケットは破棄されます。

SYSCTL 変数

sysctl(8) 変数の集合は、ファイアウォールと関連するモジュール ( dummynet, bridge ) の動作を制御します。デフォルト値と意味と共に、これらを以下に列挙 します (どの値が実際に使用されるかは sysctl(8) で確認してください)。

       net.inet.ip.dummynet.expire: 1

未処理のトラフィックを持たない動的パイプ/キューを怠惰に削除しま す。この変数を 0 に設定することでこの動作を無効にすることができま す。この場合、パイプ/キューは閾値に達した場合にのみ削除されること になります。

net.inet.ip.dummynet.hash_size: 64
動的パイプ/キューに使用されるハッシュ表のデフォルトの大きさです。 この値はパイプ/キューを設定するときに buckets オプションが指定さ れなかった場合に使用されます。

net.inet.ip.dummynet.max_chain_len: 16
ハッシュバケット (hash bucket) 内のパイプ/キューの最大個数の値で す。 net.inet.ip.dummynet.expire=0 であっても、積 max_chain_len*hash_size が空のパイプ/キューが期限切れになったとす る閾値を決定するのに使用されます。

net.inet.ip.dummynet.red_lookup_depth: 256

net.inet.ip.dummynet.red_avg_pkt_size: 512

net.inet.ip.dummynet.red_max_pkt_size: 1500
RED アルゴリズムで使う損失確率の計算に使用されるパラメータです。

net.inet.ip.fw.autoinc_step: 100
ルール番号を自動生成する際のルール番号間の増分です。この値は 1 か ら 1000 の範囲でなければなりません。この変数は ipfw2 にのみ存在 し、 ipfw1 では差分は 100 に固定されています。

net.inet.ip.fw.curr_dyn_buckets: net.inet.ip.fw.dyn_buckets
動的ルールのハッシュ表内の現在のバケットの個数です (読み出しのみ 可能)。

net.inet.ip.fw.debug: 1
ipfw
が生成するデバッグメッセージを制御します。

net.inet.ip.fw.dyn_buckets: 256
動的ルールで使用されるハッシュ表に含まれるバケットの個数です。 2 の累乗でなければならず、上限は 65536 です。全ての動的ルールが期限 切れとなったときにのみ効果が現れるので、確実にハッシュ表のサイズ が変更されるようにするには flush コマンドを使用するべきでしょう。

net.inet.ip.fw.dyn_count: 3
現在の動的ルールの数です (読み込み専用)。

net.inet.ip.fw.dyn_keepalive: 1
TCP セッションにおいて keep-state ルールのためのキープアライブパ ケットを生成するようにします。キープアライブパケットはルールの生 存時間が残り 20 秒となったときに接続の両端に向けて 5 秒毎に生成さ れます。

net.inet.ip.fw.dyn_max: 8192
動的ルールの最大値です。この限界にいきつくと、古いルールが無効に なるまでは、それ以上、動的ルールを組み込むことはできません。

net.inet.ip.fw.dyn_ack_lifetime: 300

net.inet.ip.fw.dyn_syn_lifetime: 20

net.inet.ip.fw.dyn_fin_lifetime: 1

net.inet.ip.fw.dyn_rst_lifetime: 1

net.inet.ip.fw.dyn_udp_lifetime: 5

net.inet.ip.fw.dyn_short_lifetime: 30
これらの値は、動的ルールの生存時間を秒単位でコントロールします。 最初の SYN 交換の際には生存時間が短期 (short) になり、その後互い の SYN が検出された後は増加させられ、最後の FIN 交換の間、または RST を受信した際に再び減らされます。 dyn_fin_lifetime および dyn_rst_lifetime は厳密に 5 秒 (キープアライブを繰り返す周期) よ り短くなければなりません。ファイアウォールではこれが強制されま す。

net.inet.ip.fw.enable: 1
ファイアウォールを有効にします。この変数を 0 に設定すると、マシン がコンパイル時に有効の設定がされている場合であっても、ファイア ウォールがない状態で実行されます。

net.inet.ip.fw.one_pass: 1
設定されている場合、 dummynet(4) パイプから出てくるパケットは再度 ファイアウォールを通過することはありません。そうでない場合、パイ プアクションの後、パケットは次のルールでファイアウォールに再注入 されます。

net.inet.ip.fw.verbose: 1
冗長メッセージを有効にします。

net.inet.ip.fw.verbose_limit: 0
冗長出力を行うように設定されたファイアウォールが生成するメッセー ジ数を制限します。

net.link.ether.ipfw: 0
ipfw
がレイヤ 2 パケットを通すかどうかを制御します。デフォルトは no です。

net.link.ether.bridge_ipfw: 0
ipfw
がブリッジされたパケットを通すかどうかを制御します。デフォル トは no です。

FreeBSD 4.x IPFW2 を使う

ipfw2 は、 FreeBSD 5.x と 6.0 で標準となっていますが、 FreeBSD 4.x では、 カーネルを options IPFW2 を付けてコンパイルし、 /sbin/ipfw/usr/lib/libalias-DIPFW2 を付け (buildworld の前に /etc/make.confIPFW2=TRUE を追加しておくことで同じ効果を得ることができます) 再コンパイ ル、再インストールしない限り、今でも ipfw1 を使用します。

IPFW2 拡張

このセクションでは ipfw2 で導入され、 ipfw1 には存在しなかった機能の一覧 を示します。ここではルールセットを記述する際に影響が大きいと思われる順に 示します。より効果的なやり方でルールセットを記述するためにこれらの機能を 使用したいと思うかもしれません。

       文法とフラグ

ipfw1 は、-n フラグ (文法チェックのみ) をサポートしませんし、コン マの後の空白をサポートしませんし、単一引数中での全ルールフィール ドをサポートしません。 ipfw1 では -p フラグ (プリプロセッサ) とと もに -f フラグ (強制) を指定することはできません。 ipfw1 は -c ( コンパクト) フラグをサポートしません。

非 IPv4 のパケットの取り扱い
ipfw1
は全ての非 IPv4 パケットを黙って受け付けます (ipfw1net.link.ether.bridge_ipfw=1の場合にのみ非 IPv4 パケットを参照し ます)。 ipfw2 は全てのパケット (非 IPv4 パケットを含む) をルール セットにしたがってフィルタします。 ipfw1 と同じような動作をさせた い場合はルールセットの先頭で次のようにします。

ipfw add 1 allow layer2 not mac-type ip

layer2 オプションは冗長であるように見えますが、必要です。レイヤ 3 からファイアウォールを通るパケットは MAC ヘッダを持たないので、 mac-type ip パターンはレイヤ3のパケットに対して常に失敗します。つ まり、 not オペレータをおくと全てを通過させるルールになってしまい ます。

宛先
ipfw1
はアドレスセットや宛先リストをサポートしていません。

ポートの指定
ipfw1
では TCP と UDP のポートを指定する際に指定できるポート範囲 は 1 つだけでした。また、 ipfw2 で 30 エントリ可能であるのに対 し、10 エントリに制限されていました。また、 ipfw1 では tcp または udp パケットを要求するルールの場合に限ってポートを指定することが 可能です。 ipfw2 では全てのパケットにマッチさせるルールでポートの 指定を行うことが可能で、マッチはポート識別子を含んだプロトコルを 運ぶパケットのみに適用されます。

最後に、 ipfw1 では最初のポートエントリを port:mask と指定するこ とができました。ここで mask は任意の 16 ビットマスクが使用可能で す。この文法が有用であるかどうかは疑問なので ipfw2 ではもはやサ ポートされていません。

論理和ブロック
ipfw1
は論理和ブロックをサポートしていません。

キープアライブ
ipfw1
は状態依存セッションのためのキープアライブを生成しません。 結果として、休止状態のセッションは動的ルールの生存時間が期限切れ となるために落されることがあります。

ルールセット
ipfw1
はルールセットを実装していません。

MAC ヘッダによるフィルタとレイヤ 2 のファイアウォール
ipfw1
は MAC ヘッダフィールドによるフィルタを実装していませんし、 ether_demux()ether_output_frame() からのパケットによっても起 動しません。 sysctl 変数 net.link.ether.ipfw はここでは何の効果も ありません。

オプション
ipfw1
では、次のオプションは単一値のみ受け付けます:

ipid, iplen, ipttl

次のオプションは ipfw1 では実装されていません:

dst-ip, dst-port, layer2, mac, mac-type, src-ip, src-port

さらに、次のオプションは RELENG_4 の ipfw1 では実装されていませ ん:

ipid, iplen, ipprecedence, iptos, ipttl, ipversion, tcpack, tcpseq, tcpwin

dummynet オプション
dummynet
パイプ/キュー用の次のオプションはサポートされていません:

noerror

使用例

ipfw はあまりにも多くの使用方法があるのでこのセクションでは使用例のほんの 一部を示すのみにしておきます。

基本的なパケットフィルタリング

次のコマンドは cracker.evil.org から wolf.tambov.su の telnet ポートへ送 られるすべての TCP パケットを拒否するルールを追加します。

ipfw add deny tcp from cracker.evil.org to wolf.tambov.su telnet

次のコマンドはクラッカーのネットワーク全体からホスト my へのすべてのコネ クションを拒否します。

ipfw add deny ip from 123.45.67.0/24 to my.host.org

最初に効率良く (動的ルールを用いずに) アクセスを制限する方法は、次のルー ルを用いることです。

ipfw add allow tcp from any to any established

ipfw add allow tcp from net1 portlist1 to net2 portlist2 setup

ipfw add allow tcp from net3 portlist3 to net3 portlist3 setup

...

ipfw add deny tcp from any to any

最初のルールは通常の TCP パケットにすぐにマッチしますが、最初の SYN パ ケットにはマッチしません。指定した発信元/宛先の組の SYN パケットのみ、次 の setup ルールにマッチします。これら以外の SYN パケットは、最後の deny ルールにより却下されます。

もし、1 つ以上のサブネットの管理者なら、 ipfw2 の文法の利点を活用してアド レスセットと論理和ブロックを指定することで、次のように、クライアントのブ ロックにサービスを選択的に利用可能とする極めてコンパクトなルールセットを 記述することができます。

goodguys="{ 10.1.2.0/24{20,35,66,18} or 10.2.3.0/28{6,3,11} }"

badguys="10.1.2.0/24{8,38,60}"

ipfw add allow ip from ${goodguys} to any

ipfw add deny ip from ${badguys} to any

... normal policies ...

ipfw1 の文法では、上の例では各 IP に別々のルールを用意する必要がありま す。

verrevpath オプションを使用し、下記をルールセットの先頭に置くことで、自動 的な対スプーフィングが可能になります:

ipfw add deny ip from any to any not verrevpath in

このルールは、変なインタフェースからシステムに来たように見える内向きパ ケットをすべて落とします。例えば、保護された内部ネットワーク上のホストに 属するソースアドレスを持つパケットは、外部インタフェースからシステムに入 ろうとした場合、落とされます。

antispoof オプションを下記をルールセットの先頭に追加することで、同様のこ とが行なえますが、より限定された対スプーフィングが可能になります:

ipfw add deny ip from any to any not antispoof in

このルールは、他の直接接続されたシステムから変なインタフェースに来たよう に見える内向きパケットをすべて落とします。例えば、ソースアドレスが 192.168.0.0/24 であり fxp0 で受信するように設定されているのに fxp1 で受信 されたパケットは落とされます。

動的ルール

にせの TCP パケットを含む怒涛の攻撃 (flood attack) からサイトを保護するた めに、次の動的ルールを用いた方が安全です。

ipfw add check-state

ipfw add deny tcp from any to any established

ipfw add allow tcp from my-net to any setup keep-state

これらのルールにより、ファイアウォールは、自分たちのネットワークの内側か ら到着する通常の SYN パケットで始まるコネクションに対してのみ動的ルールを 組み込みます。動的ルールは、最初の check-state ルール、または、 keep-state ルールに遭遇した時点でチェックされます。ルールセットのスキャン 量を最小にするために、 check-state ルールは、ルールセットの最初のほうに置 くことになるのが普通です。実際の燃費は変動します。

ユーザが開ける接続数を制限するには、次のタイプのルールを使用可能です。

ipfw add allow tcp from my-net/24 to any setup limit src-addr 10

ipfw add allow tcp from any to me setup limit src-addr 4

前者 (ゲートウェイ上で動作することを仮定) は、/24 ネット上の各ホストが最 大 10 個の TCP 接続を開くことを許します。後者は、サーバ上に設定可能であ り、単一のクライアントが同時に 4 個を越える接続を使用できないようにしま す。

注意: ステートフルなルールは、怒涛の SYN 攻撃により極めて大量の動的ルール を作ってしまい、サービス不能攻撃を受けることになる可能性があります。ファ イアウォールの動作をコントロールする sysctl(8) 変数に従いファイアウォール が動作することによって、このような攻撃の影響を部分的にでも制限することは できます。

ここで、カウントされている情報とタイムスタンプ情報を見る list コマンドの よい例を示します。

ipfw -at list

これはタイムスタンプを省略して次のように指定できます。

ipfw -a list

これは次の指定と等価です。

ipfw show

次のルールは 192.168.2.0/24 からのすべての受信パケットを、5000 番のポート に行き先変更するものです。

ipfw divert 5000 ip from 192.168.2.0/24 to any in

トラフィックシェイパ

次のルールは、 ipfwdummynet(4) をシミュレーションなどで使う際の使用方 法を示しています。

このルールは 5% の確率でランダムにパケットを落します。

ipfw add prob 0.05 deny ip from any to any in

同様の効果は dummynet パイプで実現可能です。

ipfw add pipe 10 ip from any to any

ipfw pipe 10 config plr 0.05

人工的にバンド幅を制限するためにパイプを使用可能です。例えばルータとして 動作するマシン上で、 192.168.2.0/24 上のローカルクライアントからのトラ フィックを制限したい場合、次のようにします。

ipfw add pipe 1 ip from 192.168.2.0/24 to any out

ipfw pipe 1 config bw 300Kbit/s queue 50KBytes

out 指示子を使用して、ルールが 2 度使われないようにしていることに注意して ください。 ipfw ルールは、実際には、入力パケットと出力パケットの両方に適 用されることを覚えておいてください。

バンド幅に制限がある双方向リンクをシミュレートする場合、正しい方法は次の 通りです。

ipfw add pipe 1 ip from any to any out

ipfw add pipe 2 ip from any to any in

ipfw pipe 1 config bw 64Kbit/s queue 10Kbytes

ipfw pipe 2 config bw 64Kbit/s queue 10Kbytes

例えば、あなたの装飾的なウェブページが低速リンクのみで接続されている在宅 ユーザにどう見えているか知りたい場合などに、上述の方法は非常に有用かもし れません。半二重メディア (例えば appletalk, Ethernet, IRDA) をシミュレー トしたい場合を除き、単一のパイプを両方の方向に使用すべきではありません。 両方のパイプが同じ設定である必要はないので、非対称リンクもシミュレート可 能です。

RED キュー管理アルゴリズムを使用してネットワーク性能を検証するには、次の ようにします。

ipfw add pipe 1 ip from any to any

ipfw pipe 1 config bw 500Kbit/s queue 100 red 0.002/30/80/0.1

トラフィックシェイパの他の典型的な応用は、いくばくかの通信遅延を導入する ことです。これは、バンド幅よりも接続のラウンドトリップ時間が制約要因とな ることがしばしばという状況下で、遠隔手続き呼び出しを多用するアプリケー ションに対し非常に大きな影響を与えます。

ipfw add pipe 1 ip from any to any out

ipfw add pipe 2 ip from any to any in

ipfw pipe 1 config delay 250ms bw 1Mbit/s

ipfw pipe 2 config delay 250ms bw 1Mbit/s

フローごとのキューはさまざまな用途に有用です。非常に単純な用途は、トラ フィックの集計です。

ipfw add pipe 1 tcp from any to any

ipfw add pipe 1 udp from any to any

ipfw add pipe 1 ip from any to any

ipfw pipe 1 config mask all

上述のルールセットは、すべてのトラフィックに対するキューを生成 (して統計 情報を収集) します。パイプには制限をつけていないので、統計情報を集める効 果しかありません。最後のルールだけでなく 3 個のルールが必要なことに注意し てください。 ipfw が IP パケットのマッチを試みるときにポートを考慮しない ため、別々のポート上の接続が違うものとして見えません。

より洗練された例は、ネットワークの出力トラフィックを、ネットワーク毎に制 約するのではなく、ホスト毎に制約するものです。

ipfw add pipe 1 ip from 192.168.2.0/24 to any out

ipfw add pipe 2 ip from any to 192.168.2.0/24 in

ipfw pipe 1 config mask src-ip 0x000000ff bw 200Kbit/s queue 20Kbytes

ipfw pipe 2 config mask dst-ip 0x000000ff bw 200Kbit/s queue 20Kbytes

ルールセット

ルールセットを不可分に追加するには、例えばセット 18 なら、次のようにしま す。

ipfw set disable 18

ipfw add NN set 18 ... # 必要に応じて繰り返す

ipfw set enable 18

ルールセットを不可分に削除するには、単に次のコマンドでよいです。

ipfw delete set 18

ルールセットのテストを行ったり、何か間違いがあった場合にルールセットを削 除して制御を回復するには、次のようにします。

ipfw set disable 18

ipfw add NN set 18 ... # 必要に応じて繰り返す

ipfw set enable 18; echo done; sleep 30 && ipfw set disable 18

ここで各設定がうまくいった場合、 "sleep" が終了する前に control-C を押す と、ルールセットは活動状態のままとなります。そうでない場合、たとえ箱にア クセスすることができなかったとしても、ルールセットは sleep が終了した後で 無効な状態になるので以前の状態が復元されます。

関連項目

cpp(1), m4(1), bridge(4), divert(4), dummynet(4), ip(4), ipfirewall(4), protocols(5), services(5), init(8), kldload(8), reboot(8), sysctl(8), syslogd(8)

バグ

年月とともに文法が大きくなり、ときどき訳がわからないところもあるかもしれ ません。不幸にして、後方互換性のために昔しでかした文法定義の誤りを訂正で きないでいます。

!!! 警告 !!!

ファイアウォールを誤って設定するとコンピュータが使用不能な状態になり、こ とによると、ネットワークサービスを停止させてしまい、制御を回復するために コンソールアクセスが必要となってしまう可能性があります。

divert によって行き先を変更された入力パケットの断片 (フラグメント) は、ソ ケットに配送される前に再構成されます。これらのパケットで使用されるアク ションはパケットの最初のフラグメントにマッチしたルールのものです。

ユーザランドへ向けられ、ユーザランドのプロセスによって再投入されるパケッ トは、パケットの発信元インタフェースを含むパケット属性のいろいろを失って います。パケットの始点インタフェース名は、8 バイト未満であって、ユーザラ ンドのプロセスが保存しこれを sockaddr_in で再使用するのであれば、保持され ます (natd(8) はそうします)。さもなくば、この情報は失われます。パケットが この方法で再投入された場合、後のルールは正しく適用されないかもしれませ ん。ルールの並びにおける divert ルールの順序は非常に重要なものとなりま す。

作者

Ugen J. S. Antsilevich,
Poul-Henning Kamp,
Alex Nash,
Archie Cobbs,
Luigi Rizzo.

API は Daniel Boulet が BSDI 用に記述したコードに基づいています。

dummynet(4) トラフィックシェイパは Akamba Corp. がサポートしました。

歴史

ipfw は、 FreeBSD 2.0 ではじめて登場しました。 dummynet(4) は FreeBSD 2.2.8 で導入されました。ステートフル拡張は、 FreeBSD 4.0 で導入さ れました。 ipfw2 は 2002 年夏に導入されました。

FreeBSD 10.0 March 2, 2005 FreeBSD 10.0

スポンサーリンク