EN JA
IPFW(8)
IPFW(8) FreeBSD System Manager's Manual IPFW(8)

名称

ipfwファイアウォール、トラフィックシェイパ、パケットスケジューラ、カーネル内 NAT のためのユーザインタフェース

書式

ファイアウォール設定

ipfw [ -cq] add rule

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

ipfw [ -f | -q][ set N] flush

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


ipfw set [ disable number ...][ enable number ...]


ipfw set move [ rule] number to number


ipfw set swap number number


ipfw set show

SYSCTL ショートカット

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

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

検索テーブル

ipfw table number add addr[ / masklen][ value]

ipfw table number delete addr[ / masklen]

ipfw table { number | all} flush

ipfw table { number | all} list

DUMMYNET 設定 (トラフィックシェイパとパケットスケジューラ)

ipfw { pipe | queue | sched} number config config-options

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

カーネル内 NAT

ipfw [ -q] nat number config config-options


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

解説

ipfw ユーティリティは、 ipfw(4) ファイアウォール、 dummynet(4) トラフィックシェイパ/パケットスケジューラとカーネル内 NAT サービスを制御するためのユーザインタフェースです。

ファイアウォールの設定、または 規則セット は、1 から 65535 までの番号が付けられた 規則 のリストでできています。パケットは、プロトコルスタック中の多くの異なった場所からファイアウォールに渡されます (パケットの発信元と宛先によっては、ファイアウォールが同じパケットで複数回起動される可能性があります)。ファイアウォールに渡されたパケットは、規則番号の順序で、 規則セット 中のそれぞれの規則に対して比較されます (同じ数がある複数の規則が許可されます、その場合、それらは、挿入された順序で処理されます)。マッチしたとき、マッチする規則に対応するアクションが実行されます。

アクションと特定のシステム設定によって、さらなる処理に対して一致するものの後に、いくつかの規則でファイアウォールにパケットを再投入することができます。

規則セットは、修正または削除することができず、すべてのパケットと一致する (65535 と番号が付けられる) デフォルト の規則を常に含んでいます。 デフォルト の規則に関連したアクションは、カーネルがどのように設定されるかに依存して deny または allow のいずれかを指定できます。

規則セットが keep-state または limit オプションがある 1 つ以上の規則を含んでいるなら、ファイアウォールには、 ステートフル (状態依存型) の振る舞いがあります、すなわち、マッチにおいて 動的規則 を作成します、すなわち、それらの作成を引き起こしたパケットとして同じ 5 つの組 (プロトコル、発信元と宛先アドレスおよびポート) があるパケットとマッチする規則。生存時間が有限である動的規則は、 check-state, keep-state または limit 規則の最初に生じた時点でチェックされ、正当なトラフィックのみをオンデマンドで、ファイアウォールをオープンするために通常使用されます。 ipfw のステートフルな動作について更に情報が必要ならば、以下の ステートフルファイアウォール セクションと 使用例 セクションを参照して下さい。

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

各規則は、32 個の異なる セット の 1 つに属し、有効にする、無効にする、セットを入れ換える、セット中のすべての規則を別のセットへ移動する、セット中のすべての規則を削除するような、セットを不可分に操作する ipfw コマンドがあります。これらは、一時的な設定をインストールするか、または設定をテストするめに役に立つかもしれません。 セット に関する詳細については、セクション 規則セット を参照してください。

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

コマンドオプション

ipfw を呼び出すとき、次の一般的なオプションが利用可能です:
-a
規則をリストするとき、カウンタ値を表示します。 show コマンドは、このオプションの意味も含みます。
-b
アクションとコメントのみを表示します。規則のボディは、表示しません。 -c が暗黙のうちに指定されます。
-c
規則を入力したり参照したりするときに、コンパクトな書式で規則を表示します。すなわち、規則が何の追加情報も持たないとき、"ip from any to any"文字列を省略します。
-d
リストするとき、静的規則に加えて動的規則も表示します。
-e
リストし、 -d オプションが指定されているとき、期限切れの動的規則も表示します。
-f
誤って使用すると問題を起すかもしれないコマンド、すなわち、 flush、に対して確認を求めません。プロセスに関連する tty がないなら、これが、暗黙のうちに意味されます。
-i
テーブルをリストするとき、 (検索テーブルに関する詳しい情報については、下記の 検索テーブル セクションを参照) 形式は、IP アドレスとして評価します。デフォルトで、値は、整数として表示されます。
-n
コマンド文字列の文法だけをチェックし、実際には、カーネルには渡しません。
-N
出力に含まれるアドレスとサービス名の名前解決を試みます。
-q
add, nat, zero, resetlog または flush コマンドを実行するとき、静かにします。 ( -f の意味も含みます)。スクリプト (例えば、‘ sh /etc/rc.firewall’) で複数の ipfw コマンドを実行することによって、またはリモートログインセッションに経由で多くの ipfw 規則があるファイルを処理することによって規則セットを更新するとき、これは役に立ちます。また、(追加の場合) エントリが既に存在しているか、または (削除の場合) 存在していないならテーブルの追加または削除を停止します。

このオプションが重要である理由は、 ipfw がメッセージを印刷する、これらのアクションのいくつかのためにです。アクションがリモートクライアントへのトラフィックをブロックする結果となるなら、リモートログインセッションは、クローズされ、規則セットの残りは、処理されません。次に、コンソールへのアクセスが、回復するために必要とされます。

-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 アドレスのように頻繁に必要となる引数を集中管理するためのマクロを使用可能となります。

トラフィックシェイパの設定

ipfwpipe, queuesched コマンドは、トラフィックシェイパとパケットスケジューラを設定するために使用されます。詳細については、下記の トラフィックシェイパ (DUMMYNET) 設定 セクションを参照してください。

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

パケットフロー

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

       ^    to upper layers    V 
       |                       | 
       +----------->-----------+ 
       ^                       V 
 [ip(6)_input]           [ip(6)_output]     net.inet(6).ip(6).fw.enable=1 
       |                       | 
       ^                       V 
 [ether_demux]        [ether_output_frame]  net.link.ether.ipfw=1 
       |                       | 
       +-->--[bdg_forward]-->--+            net.link.bridge.ipfw=1 
       ^                       V 
       |      to devices       |

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

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

また、各パケットは、常に規則セット全体に対しチェックされることにも注意してください。これは、チェックが生じた場所、パケットのソースに関係ありません。実行された箇所によっては、無効となるような適合パターンやアクション (例えば、 ip_input または ip6_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 は、しません)。

いくつかの引数 (例えば、ポートまたはアドレスのリスト) は、コンマで区切られた値のリストです。この場合は、コンマ ',' の後の空白は、行をより読み易くすることができます。また、コマンド全体 (フラグを含む) を、単一引数に入れられます。例えば、次の書式は、等価です:

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"

規則書式

ファイアウォールの規則の書式は、次の通りです。

[ rule_number][ set  set_number][ prob  match_probabilityaction [ log [ logamount  number]][ altq  queue][ { taguntagnumberbody

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

レイヤ 2 ヘッダフィールド
可能ならば
IPv4 とび IPv6 プロトコル
TCP, UDP, ICMP など
発信元と宛先のアドレスとポート
方向
セクション パケットフロー を参照して下さい
送信と受信インタフェース
名前またはアドレス
その他の IP ヘッダフィールド
バージョン、サービスタイプ、データグラム長、識別子、フラグメントフラグ (0 でない IP オフセット)、生存時間
IP オプション
IPv6 拡張ヘッダ
フラグメンテーション、中継点ごと (Hop-by-Hop) オプション、ルーティングヘッダ、ソース (発信元) ルーティング rthdr0、モバイル IPv6 rthdr2、IPSec オプション。
IPv6 フロー ID
その他の TCP ヘッダフィールド
TCP フラグ (SYN, FIN, ACK, RST など)、シーケンス番号、確認応答番号、ウィンドウ
TCP オプション
ICMP タイプ
ICMP パケットの場合
ICMP6 タイプ
ICMP6 パケットの場合
ユーザ/グループ ID
パケットをローカルソケットに関連づけることが可能な場合
divert 状態
パケットが divert ソケット (例えば natd(8)) から来たかどうか。
Fib annotation state
パケットが、将来の決定を進める特定の FIB (ルーティングテーブル, 経路表) を使用してタグ付けをされるかどうか。

上記の情報のいくつか (例えば、発信元 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 と共に使用して) パケット到達順序の乱れを引き起こす複数経路の効果をシミュレートする応用など、多くの応用に有用です。

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

log [ logamount number]
log キーワードに規則をマッチするパケットは、 2 つの方法でログ記録するために利用可能にします。 sysctl 変数 net.inet.ip.fw.verbose が 0 (デフォルト) に設定されるなら、 ipfw0 疑似インタフェースにアタッチされた bpf(4) を使用することができます。次のコマンドを使用することによってブート後に手動で、この疑似インタフェースを作成することができます:

# ifconfig ipfw0 create

または、 rc.conf(5) ファイルに次の行を追加することによってブート時に自動的に、この疑似インタフェースを作成することができます:

firewall_logif="YES"

bpf(4) が疑似インタフェースにアタッチされていなら、オーバヘッドは、ありません。

net.inet.ip.fw.verbose が 1 に設定されるなら、パケットは、最大 logamount パケットまで LOG_SECURITY 機能がある syslogd(8) にログ記録されます。 logamount が指定されていなければ、制限は、sysctl 変数 net.inet.ip.fw.verbose_limit から参照されます。どちらの場合も、0 の値は、制限のないログ記録を意味します。

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

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

tag number
パケットが tag キーワードで規則と適合するとき、与えれた範囲 1 から 65534 の number の数値タグは、パケットにアタッチされます。タグは、後でこれらのパケットを識別するために使用することができる内部のマーカ (ケーブルを越えて外部に送信されない) の役割を果たします。例えば、インタフェース間に信頼を提供し、ポリシベースのフィルタリングを開始するために、使用することができます。パケットは、同時に複数のタグを持つことができます。タグは、"スティッキ"です、これは、いったんタグが適合する規則によってパケットに適用されると明示的な削除まで存在することを意味します。タグは、カーネル内のいずれの場所でもパケットで保持されますが、例えば、パケットをネットワークに転送するとき、またはパケットを divert(4) ソケットへ送信するときのように、パケットがカーネルから出るとき、タグは、失われます。

以前に適用されたタグをチェックするためには、 tagged (タグ付けされた) 規則オプションを使用します。以前に適用されたタグを削除するためには、 untag (タグ付け解除) キーワードを使用します。

注: タグがカーネル空間のいずれの場所でもパケットで保持されるので、 ipfw(4) taguntag キーワードを用いるだけでなく、 ( mbuf_tags(9) 機能を使用して) カーネルネットワークサブシステムのどこででも、それらを設定および設定解除することができます。例えば、後でファイアウォールで検査するためにトラフィック分析とタグ付けをおこなう特殊化した netgraph(4) ノードがあり得ます。

untag number
パケットが untag キーワードで規則に適合するとき、番号 number のタグは、このパケットにアタッチされたタグの中で検索され、見つかったなら、タグを削除します。存在しているなら、他のタグがパケットにバインドされ、そのまま残されます。
altq queue
パケットが altq キーワードで規則と適合するとき、与えられた queue ( altq(4) 参照) のための ALTQ 識別子は、アタッチされます。この ALTQ タグは、IPFW から送出される ("out") パケットのためだけに意味があり、拒否されたり、divert ソケットに行くパケットには、意味がないことに注意してください。パケットが処理される時点で十分なメモリがないなら、タグ付けをされないので、これのために利用者の ALTQ "デフォルト"キューポリシアカウントを作成することは賢明であることに注意してください。複数の altq 規則が単一のパケットに適合するなら、最初のものだけに ALTQ 分類タグを追加します。そうすることで、トラフィックは、規則セットの初期の分類のために count altq queue 規則を使用して形成され、その後にフィルタリング判定を適用します。例えば、 check-statekeep-state 規則は、後で来て、フォールバック ALTQ タグに加えて実際のフィルタリング判定を提供します。

利用者は、IPFW が名前によってキューを検索することができるようになる前にキューを設定するために pfctl(8) を実行しなければなりません、そして ALTQ 制御規則 (discipline) が再調整されるなら、カーネルでのキュー識別子を含む規則は、おそらく古くなり、再びロードする必要があります。古いキュー識別子は、たぶん分類誤りをもたらすでしょう。

すべてのシステム ALTQ 処理は、 ipfw enable altqipfw disable altq によってオンまたはオフに切り替えることができます。 net.inet.ip.fw.one_pass の使用法は、ALTQ タグを加えた後に実際の規則アクションが常に続いているままで、ALTQ トラフィック形成と無関係です。

規則アクション

規則は、次に示すアクションの 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 | tablearg[ , port]
マッチしているパケットで次のホップ (中継点) を、 IP アドレスまたはホスト名であるかもしれない、 ipaddr に変更します。また、IPv4 に関して、明白なアドレスの代わりに tablearg キーワードを使用することによってパケットを検索する最後のテーブルによって、次のホップ (中継点) を供給することができます。この規則にマッチするなら、検索は、終わります。

ipaddr がローカルアドレスの場合、適合したパケットは、ローカルマシンの port (または、規則で指定されていない場合は、そのパケットのポート番号) に転送されます。

 

ipaddr がローカルアドレスでない場合、ポート番号は、(指定されていても) 無視され、パケットは、ローカルな経路テーブルに存在するその IP に対する経路を使用してリモートアドレスに転送されます。

 

fwd 規則は、レイヤ 2 パケット (それらは、ether_input, ether_output, bridged で受信されます) には適合しません。

 

fwd アクションは、パケットの内容をまったく変更しません。実際、宛先アドレスが修正されずに残るので、転送先システムがそのようなパケットを取り込む規則を持たない限り、他のシステムに転送されたパケットは、通常転送先のシステムで拒否されます。ローカルに転送されるパケットの場合、ソケットのローカルアドレスは、パケットが元々持っていた宛先アドレスに設定されます。このことによって netstat(1) が出力するエントリは、若干奇妙な見え方になりますが、これは、透過プロキシサーバでの使用を意図しています。

nat nat_nr | tablearg
(ネットワークアドレス変換、アドレスリダイレクション、その他のために) パケットを nat インスタンスに渡します: さらなる詳細については、 ネットワークアドレス変換 (NETWORK ADDRESS TRANSLATION (NAT)) セクションを参照してください。
pipe pipe_nr
パケットを dummynet “パイプ” (バンド幅制限、遅延などに使用されます) へ渡します。詳しい情報については、 トラフィックシェイパ (DUMMYNET) 設定 セクションを参照してください。検索は、終了します。しかし、パイプから抜けたときに sysctl(8) 変数 net.inet.ip.fw.one_pass がセットされていない場合、パケットは、すぐ次の規則から始まるファイアウォールコードへ再度渡されます。
queue queue_nr
パケットを dummynet “キュー” (WF2Q+ を使ったバンド幅制限に使用されます) へ渡します。
reject
(非推奨)。 unreach host と同義です。
reset
この規則に適合したパケットを破棄します。さらに、そのパケットが TCP パケットであれば、 TCP リセット (RST) 通知を送出しようと試みます。検索は、終了します。
reset6
この規則に適合したパケットを破棄します。さらに、そのパケットが TCP パケットであれば、 TCP リセット (RST) 通知を送出しようと試みます。検索は、終了します。
skipto number | tablearg
それ以降の規則のうち number より小さな番号のものすべてを飛び越して、 number 以上の番号の規則で最初に存在するものから、検索を継続します。 計算された skipto のために skipto がある tablearg キーワードを使用することができますが、宛先キャッシュが、この場合可能でないので、規則は、 skipto から始めて、それを見つけるために常に探し回るとき、注意するべきです。
call number | tablearg
現在の規則番号は、内部スタックに保存され、規則セット処理は、 number 以上に番号付けされた最初の規則で継続します。 return アクションがある後の規則に遭遇するなら、処理は、この call 規則と 1 以上の数で最初の規則に戻ります ( divert アクションの後で divert(4) ソケットから戻るパケットのような同じ振る舞い)。これは、アセンブリ言語“subroutine”呼び出しにやや似た、異なったインタフェースなどの共通のチェックで規則付けを行うために使用されます。

任意の数がある規則は、 skipto のように前方にただジャンプするのではなく、呼び出されます。それで、誤りの場合の永久ループを防ぐために、 callreturn アクションの両方は、メモリが割り付けできないか、またはスタックがオーバフローするかアンダフローするなら、どんなジャンプも行われず、単に次の規則に行きます。

内部的に、規則番号のためのスタックは、 mbuf_tags(9) 機能を使用して実装され、現在、16 エントリのサイズがあります。 mbuf タグがパケットがカーネルから出るとき、失われるように、 divert は、永久ループと他の望ましくない影響を避けるためにサブルーチンで使用されるべきではありません。

return
最後の call アクションによって内部のスタックに保存された規則番号を取り、対応する call 規則の数より大きい数がある最初の規則に規則セット処理を返します。その他の詳細については、 call アクションの説明を参照してください。

return 規則は、通常、“subroutine”を終わらせて、その結果、無条件ですが、 ipfw コマンドラインユーティリティは、現在本体を所有するために check-state 以外のあらゆるアクションを必要とすることに注意してください。いくつかのパケットでのみ戻るために時々役に立ちますが、通常、読み易さのために単に“return”を印刷することを必要とします。この回避方法は、次のように新しい構文と -c スイッチを使用することです:

# 実際の本体なしで規則を追加します 
ipfw add 2999 return via any 
 
# "from any to any"部分なしで規則をリストします 
ipfw -c list

この表面的な問題は、将来のリリースで修正されるかもしれません。

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。検索は、終了します。
unreach6 code
この規則に適合したパケットを破棄し、コード code の ICMPv6 到達不可通知を送出しようと試みます。ここで code は、0, 1, 3, 4 の数字、または次のエイリアスのいずれかです: no-route, admin-prohib, address または port。検索は、終了します。
netgraph cookie
パケットに与えられた cookie をつけて netgraph に送出します。パケットが後に netgraph から返ってきたなら、 net.inet.ip.fw.one_pass sysctl 変数に依存して、次の規則に受け付けまたは継続のどちらかとなります。
ngtee cookie
パケットのコピーは、netgraph に送出され、オリジナルのパケットは、次の規則で継続します。 netgraphngtee アクションの詳細については、 ng_ipfw(4) を参照してください。
setfib fibnum | tablearg
パケットは、その後の決定を進める FIB (ルーティングテーブル, 経路表) fibnum を使用するためにタグ付けをされます。現在の実装は、これは、値 0 から 15 に制限されます、 setfib(2) を参照してください。処理は、次の規則を続行します。 setfib がある tablearg キーワードを使用することは可能です。 tablearg 値がコンパイルされた fib の範囲内でないなら、パケットの fib な、0 に設定されます。
setdscp DSCP | number | tablearg
IPv4/IPv6 パケットのための指定された DiffServ codepoint を設定します。処理は、次の規則で継続します。サポートされている値は、次の通りです:

CS0 ( 000000), CS1 ( 001000), CS2 ( 010000), CS3 ( 011000), CS4 ( 100000), CS5 ( 101000), CS6 ( 110000), CS7 ( 111000), AF11 ( 001010), AF12 ( 001100), AF13 ( 001110), AF21 ( 010010), AF22 ( 010100), AF23 ( 010110), AF31 ( 011010), AF32 ( 011100), AF33 ( 011110), AF41 ( 100010), AF42 ( 100100), AF43 ( 100110), EF ( 101110), BE ( 000000)。さらに、数値 (0..64) によって DSCP 値を指定することができます。また、 setdscp がある tablearg キーワードを使用することができます。 tablearg 値が 0..64 の範囲内にないなら、供給された下位 6 ビットが使用されます。

reass
IP フラグメントをキューに入れて、再構築します。パケットがフラグメント化されていないなら、カウンタは、更新され、処理は、次の規則で続行します。パケットが最後の論理的なフラグメントであるなら、パケットは、再構築され、 net.inet.ip.fw.one_pass が 0 に設定されているなら、処理は、次の規則で続行します。そうでなければ、パケットは、渡すことが許可され、検索は、終了します。パケットがフラグメントの論理グループの中間のフラグメントであるなら、それは、消費され、処理は、直ちに停止します。

net.inet.ip.maxfragpacketsnet.inet.ip.maxfragsperpacket を通して、それぞれ、処理できるフラグメントの最大数 (デフォルト: 800) とパケット毎のフラグメントの最大数 (デフォルト: 16) を制限する、フラグメントの取り扱いを調整することができます。

注意: フラグメントがポート番号をを含んでいないので、それらを、 reass 規則で避けるべきです。もう一つの方法として、 ( in / out のような) 方向ベース (direction-based) と ( via (経由) のような) ソースベース (source-based) のマッチパターンは、フラグメントを選択するために使用することができます。

通常、次のような簡単な規則です:

# 着信フラグメントを再構築する 
ipfw add reass all from any to any in

は、すべて、規則セットの始めに必要とします。

規則ボディ

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

ipfw add 100 allow ip from not 1.2.3.4 to any

さらに、次のように or オペレータを使用し、丸括弧 () やブレース {} で括られた内部にパターンを列挙することで、新しい適合パターンのセット ( 論理和 (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) は、 FreeBSD の初期のバージョンとの後方互換性のためのものです。最近の FreeBSD では、 options セクションで (MAC ヘッダ、IP プロトコル、アドレスとポートを含んで) 任意のマッチパターンを指定することができます。

規則フィールドには、次の意味があります:

proto: protocol | { protocol or ... }
protocol: [ not] protocol-name | protocol-number
数値または名前 (完全なリストについては、 /etc/protocols を参照) によって指定された IP プロトコル、または次のキーワードの 1 つ:
ip4 | ipv4
IPv4 パケットに適合する。
ip6 | ipv6
IPv6 パケットに適合する。
ip | all
あらゆるパケットに適合する。

proto オプションの ipv6 は、内部のプロトコルとして取り扱われます。そして、 ipv4 は、 proto オプションで利用可能ではありません。

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

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

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

addr: [ not]{ any | me | me6 | table( number[ , value]) | addr-list | addr-set}
any
任意の IP アドレスが適合します。
me
システムのインタフェースに設定された任意の IP アドレスが適合します。
me6
システムのインタフェースに設定された任意の IPv6 アドレスが適合します。アドレスのリストは、パケットが解析されるときに評価されます。
table( number[ , value])
検索テーブル number に存在するエントリに対応する任意の IPv4 アドレスが適合します。オプションの 32 ビット符号なし整数 value も指定された場合には、その値のエントリにのみ適合します。検索テーブルに関する詳細は、下記の 検索テーブル セクションを参照して下さい。
addr-list: ip-addr[ , addr-list]
ip-addr:
次の方法で指定される、ホストもしくはサブネットのアドレス:
numeric-ip | hostname
ドットで区切った数字 4 つ組またはホスト名で指定した、 1 つの IPv4 アドレスが適合します。ホスト名の名前解決は、その規則がファイアウォールのリストに追加されるときに行われます。
addr/ masklen
ベースとなる addr (IP アドレス、ネットワーク番号、またはホスト名で指定します) と masklen ビット幅のマスクに適合する全てのアドレスが適合します。例えば、1.2.3.4/25 または 1.2.3.0/25 は、1.2.3.0 から 1.2.3.127 までの全ての IP アドレスが適合することになります。
addr: mask
ベースアドレスが addr (IP アドレス、ネットワーク番号、またはホスト名で指定します) であり、マスクが mask (ドットで区切った 4 つの数字で指定されます) である全てのアドレスに適合します。例えば、1.2.3.4:255.0.255.0 または 1.0.3.0:255.0.255.0 は、1.*.3.* に適合します。この形式は、連続でないマスクの場合にだけ使用することを推奨します。連続なマスクの場合は、よりコンパクトでより間違いにくい、 addr/ masklen を使います。
addr-set: addr[ / masklen] { list }
list: { num | num-num}[ , list]
ベースアドレスが addr (IP アドレス、ネットワーク番号、またはホスト名で指定します) であり、最後のバイトがブレース {} の中に列挙されている全てのアドレスが適合します。ブレースと数字の間には空白を置いてはいけないことに注意して下さい (コンマの後の空白は、許されています)。リストの要素は、単一項目もしくは範囲が指定可能です。 masklen フィールドは、アドレスのセットのサイズに制限をつけるために使用され、 24 から 32 の間の任意の値をとることができます。指定されない場合 24 が仮定されます。
 
この書式は、1 つの規則でまばらなアドレス群を取り扱うときに特に便利です。ビットマスクを使用して適合を行うので、定数時間で処理でき、規則セットの複雑さが劇的に減少します。
 
例えば、1.2.3.4/24{128,35-55,89} または 1.2.3.0/24{128,35-55,89} として指定したアドレスは、次の IP アドレスに適合します:
 
1.2.3.128, 1.2.3.35 to 1.2.3.55, 1.2.3.89 .
addr6-list: ip6-addr[ , addr6-list]
ip6-addr:
ホストまたはサブネットを以下の方法のうちのどれかで指定します:
numeric-ip | hostname
単一の inet_pton(3) で認められている IPv6 アドレス、またはホスト名に適合します。ホスト名は、規則がファイアウォールリストに追加される時に解決されます。
addr/ masklen
ベースアドレスが addr ( inet_pton で認められている、またはホスト名) で、マスクの幅が masklen ビットである全ての IPv6 アドレスに適合します。

IPv6 アドレスは、一般に最初のプレフィックスの後はランダムなので、 IPv6 アドレスのセットに対するサポートは、提供されません。

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

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

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

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

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

規則オプション (適合パターン)

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

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

// this is a comment.
指定したテキストを、規則中にコメントとして挿入します。 // に続くすべてがコメントとして扱われ、規則中に格納されます。コメントのみの規則を持つことも可能であり、それは、 count アクションに続いてコメントが表示されます。
bridged
layer2 の別名です。
diverted
divert ソケットによって生成されたパケットのみ適合します。
diverted-loopback
配信のための IP スタック入力に戻された divert ソケットから来るパケットだけ適合します。
diverted-output
配信のための IP スタック出力に戻された divert ソケットから行くパケットだけ適合します。
dst-ip ip-address
宛先 IP アドレスが引数で指定したアドレスの 1 つである IPv4 パケットに適合します。
{ dst-ip6 | dst-ipv6} ip6-address
宛先 IP アドレスが引数で指定したアドレスの 1 つである IPv6 パケットに適合します。
dst-port ports
宛先ポートが引数で指定したポートの 1 つである IP パケットに適合します。
established
RST か ACK ビットがセットされている TCP パケットに適合します。
ext6hdr header
header で与えられた拡張ヘッダを含む IPv6 パケットに適合します。サポートされているヘッダは、次の通りです:

フラグメント, ( frag), Hop-to-hop オプション ( hopopt), 任意のタイプのルーティングヘッダ ( route), ルーティングヘッダタイプ 0 のソースルーティング ( rthdr0), ルーティングヘッダタイプ 2 のモバイル IPv6 ( rthdr2), 宛先オプション ( dstopt), IPSec 認証ヘッダ ( ah), IPsec カプセル化セキュリティペイロードヘッダ ( esp)。

fib fibnum
与えられた FIB (ルーティングテーブル) 番号を使用するためにタグ付けされたパケットにマッチします。
flow-id labels
labels で与えられた任意のフローラベルを含む IPv6 パケットに適合します。 labels は、フローラベルの数値をコンマで区切られたリストです。
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)

icmp6types types
ICMP6 タイプが types のリストに含まれる ICMP6 パケットに適合します。リストは、コンマで区切られた別々のタイプ (数値) の任意の数の組み合わせで指定されます。 範囲指定は認められていません
in | out
それぞれ到着または送出パケットに適合します。 inout は、互いに排他的です (実際、 out は、 not in として実装されています)。
ipid id-list
ip_id フィールドが id-list に含まれる IPv4 パケットに適合します。 id-list は、単一の値か、 ports と同等の方法で指定される、値のリストか範囲です。
iplen len-list
ヘッダとデータを含んだ全体の長さが len-list に含まれる IP パケットに適合します。 len-list は、単一の値か、 ports と同等の方法で指定される、値のリストか範囲です。
ipoptions spec
spec で指定したコンマ区切りリストオプションを含む IPv4 ヘッダを持つパケットに適合します。 IP オプションは、次のものがサポートされています:

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

ipprecedence precedence
先行フィールドが precedence に等しい IPv4 パケットに適合します。
ipsec
IPSEC ヒストリを持つパケットに適合します (すなわち、入力パケットが IPSEC でカプセル化されており、カーネルが IPSEC と IPSEC_FILTERTUNNEL のオプションをサポートし、正しくパケットのカプセル化を解除できた場合です)。

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

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

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

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

dscp spec[ , spec]
DS フィールド値が spec マスクに含まれている IPv4/IPv6 パケットにマッチします。コンマで区切られたリストによって複数の値を指定することができます。値は、 setdscp アクションまたは正確な数で使用されるキーワードの 1 つを指定できます。
ipttl ttl-list
生存時間が ttl-list に含まれる IPv4 パケットに適合します。 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 つ以上の発信元と宛先アドレスおよびポートが指定できます。現在のところ、IPv4 フローのみサポートされています。
lookup { dst-ip | dst-port | src-ip | src-port | uid | jail} N
引数として指定されたフィールドに適合する検索テーブル N のエントリを検索します。見つからなければ、適合は、失敗します。そうでなければ、適合は、成功し、 tablearg は、テーブルから抽出された値に設定されます。

特定のパケットフィールドに基づくトラフィックをすばやくディスパッチする (送り出す) ためにこのオプションを役立てることができます。検索テーブルの詳しい情報については、下記の 検索テーブル セクションを参照してください。

{ 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-type は、 port numbers と同じ方法で指定します (つまり、単一の値または範囲が、1 個以上コンマで区切られたものです)。 vlan, ipv4, ipv6 のような既知の値に対しては、シンボル名称を使用することができます。値は、10 進数か 16 進数 (0x が頭につく場合) で入力することができ、常に 16 進数で出力されます (これは、 -N オプションが使用されていない場合です。 -N オプションが使用されるとシンボル名称の解決が試みられます)。
proto protocol
対応する IP のプロトコルを持つパケットが適合します。
recv | xmit | via { ifX | if * | table( number[ , value | 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”の短縮形です。
sockarg
ローカルのソケットに関連づけられたパケットと SO_USER_COOKIE ソケットオプションが 0 以外の値に設定されたことに対しマッチします。副作用として、オプションの値は、 skipto または pipe 番号として順番に使用できる、 tablearg 値として利用可能にします。
src-ip ip-address
引数で指定したアドレスの 1 個を発信元 IP として持つ IPv4 パケットが適合します。
src-ip6 ip6-address
引数で指定したアドレスの 1 個を発信元 IP として持つ IPv6 パケットが適合します。
src-port ports
引数で指定したポートの 1 個を発信元ポートとして持つ IP パケットが適合します。
tagged tag-list
単一の値、値のリストまたは、 ports と同様に指定された範囲である、 tag-list に含まれているタグがあるパケットに適合します。 tag 規則アクションパラメータを使用して、タグをパケットに適用することができます (タグに関する詳細のための説明を参照してください)。
tcpack ack
TCP パケットのみです。 TCP ヘッダの確認応答番号フィールドが ack に設定されていれば適合します。
tcpdatalen tcpdatalen-list
TCP データの長さが tcpdatalen-list である TCP パケットに適合します。単一の値、値のリスト、または ports と同様の形式の範囲、のどれかを指定します。
tcpflags spec
TCP パケットのみです。 TCP ヘッダが spec で指定したコンマ区切りのフラグのリストを含んでいれば適合します。サポートされている TCP フラグは、次の通りです。

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

tcpseq seq
TCP パケットのみです。 TCP ヘッダのシーケンス番号フィールドが seq に設定されていれば適合します。
tcpwin tcpwin-list
ヘッダのウィンドウフィールドが、単一の値または ports と同じ方法で指定された値または範囲のリストのいずれかである、 tcpwin-list に設定される TCP パケットと一致します。
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 と似ていますが、ソースアドレスすべての代わりに、直接接続されたネットワークのソースアドレスを持つパケットを対象とするのでより限定的です。

検索テーブル

検索テーブルは、アドレスまたは他の検索キー (例えば、ポート、jail ID、インタフェース名) の大きなまばらなセットを扱うために役に立ちます。このセクションの残りで、私たちは、用語 ``アドレス'' を使用します。 0 から 65534 まで番号付けられた 65535 までの異なった検索テーブルがあります。

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

( add) でテーブルにエントリを追加するか、または ( delete) でテーブルからエントリを削除することができます。 ( list) でテーブルを調べるか、または ( flush) でテーブルをフラッシュすることができます。

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

検索テーブルは、現在のところ ports, jail ID と IPv4/IPv6 アドレスのみサポートしています。

tablearg 機能は、規則アクション、アクションパラメータ、または規則オプションのための引数としてテーブルで検索された値を使用する能力を提供します。これは、いくつかの設定の規則の数をかなり減少させることができます。 2 つのテーブルが規則で使用されるなら、2 番目の (宛先) の結果が、使用されます。 tablearg 引数は、次のアクションと共に使用することができます: nat, pipe, queue, divert, tee, netgraph, ngtee, fwd, skipto, setfib アクションパラメータ: tag, untag 規則オプション: limit, tagged

fwd で使用されるとき、IP アドレスまたはホスト名の形式にある値をテーブルエントリに供給することは可能です。テーブルと tablearg キーワードの使用例については、 使用例 セクションを参照してください。

skipto 動作で使用されるとき、ユーザは、コードが規則と与えられた番号と等しいか、または超えるまで規則セットを探し回ることを承知しているべきです、したがって、skipto とターゲットの間でコンパクトに規則セットを保持するように試みるべきです。

規則のセット

各規則は、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-statelimit オプションを通じて提供されます。

動的規則が生成されるのは、パケットが 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 トラフィックシェイパ、パケットスケジューラとネットワークエミュレータ、人工的にキューに入れることができるサブシステム、特定のネットワークリンクの振る舞いをエミュレートするパケットを遅延させるか、または落す、またはキューに入れるシステムのためのユーザインタフェースです。

dummynet は、最初に ipfw 規則で使用することができる任意のマッチパターンを使用してパケットを選択するためにファイアウォールを使用して動作します。次に、パケットをマッチングすることは、トラフィックの調整を実装する 2 つの異なったオブジェクトのいずれかに渡されます:

pipe
パイプ (pipe) は、与えられた帯域幅と伝播遅延、 FIFO スケジューラによってドライブされ、プログラマブルキューとパケット損失率がある単一のキューで リンク (link) をエミュレートします。パケットは、 ipfw から外へ出るので、キューの後ろに追加され、次に、FIFO の順序で希望の速度でリンクに転送されます。
queue
キュー (queue) は、いくつかのパケットスケジューリングアルゴリズムの 1 つを使用してパケットスケジューリングを実装するために使用される抽象化 (abstraction) です。 キュー に送られたパケットは、最初に、5 つの組のマスクに従ってフロー (flow) にグループ化されます。次に、フローは、 キュー に関連づけられたスケジューラに渡され、各流れは、 キュー 自体で設定されるとしてのスケジューリングパラメータ (重み付けなど) を使用します。スケジューラは、順番に、エミュレートされたリンクに接続され、重み付け (weight) と使用中のスケジューリングアルゴリズムの特徴に従ってバックログされたフローの中でリンクの帯域幅を調停します。

実際には、フローが使用できる帯域幅への強固な制限を設定するために pipes を使用することがきますが、一方、異なったフローがどのように利用可能帯域幅を共有するかを決定するために queue を使用することができます。

キュー、フロー、スケジューラとリンクの結合のグラフ表現は、下記の通りです。

                 (flow_mask|sched_mask)  sched_mask 
         +---------+   weight Wx  +-------------+ 
         |         |->-[flow]-->--|             |-+ 
    -->--| QUEUE x |   ...        |             | | 
         |         |->-[flow]-->--| SCHEDuler N | | 
         +---------+              |             | | 
             ...                  |             +--[LINK N]-->-- 
         +---------+   weight Wy  |             | +--[LINK N]-->-- 
         |         |->-[flow]-->--|             | | 
    -->--| QUEUE y |   ...        |             | | 
         |         |->-[flow]-->--|             | | 
         +---------+              +-------------+ | 
                                    +-------------+

コマンド

ipfw sched N config mask SCHED_MASK ...

ipfw queue X config mask FLOW_MASK ....

で設定される SCHED_MASK と FLOW_MASK の役割を理解することは重要です。

SCHED_MASK は、1 つ以上のスケジューラのインスタンス (SCHED_MASK を適用した後のパケットの 5 つの組の各値毎に 1 つの) へのフローを割り当てるために使用されます。例として、``src-ip 0xffffff00'' を使用すると、/24 の宛先のサブネット毎に 1 つのインスタンスが作成されます。

FLOW_MASK は、フローへのパケット分けるために SCHED_MASK と共に使用されます。例として、前の SCHED_MASK と共に ``src-ip 0x000000ff'' を使用すると、それぞれ個別の発信元アドレスのためにフローを作ります。順番に、各 /24 サブネットのためのフローは、同じスケジューラのインスタンスに送信されます。

上記のダイヤグラムは、 パイプ が SCHED_MASK をサポートするだけであり、 FIFO スケジューラの使用を強制するという唯一の制限がある、 パイプ の場合のためさえ保持します (これらは後方の互換性のためにあり、事実上、内部的に dummynet のパイプは、正確に上記のように実装されます)。

dummynet 操作の 2 つのモードがあります: “normal”と“fast”です。“normal”モードは、実際のリンクをエミュレートしようとします: dummynet スケジューラは、パケットが与えられた帯域幅で実際のリンクより速くパイプを残さないことを確実にします。“fast”モードによって、特定パケットは、(パケットフローがパイプの帯域幅を超えていないなら) dummynet スケジューラをバイパス (迂回) することができます。これは、(平均で) より少ないパケット毎の CPU サイクルを“fast”モードが必要とする理由です、そしてパケットレイテンシ (待ち時間) は、同じ帯域幅がある実際のリンクの比較でかなり低くなるかもしれません。デフォルトモードは、“normal”です。 net.inet.ip.dummynet.io_fast sysctl(8) 変数を 0 以外に設定することによって、“fast”モードを有効にすることができます。

パイプ、キューとスケジューラの設定

pipe, queuescheduler の設定コマンドは、次の通りです:

pipe number config pipe-configuration

queue number config queue-configuration

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

burst size
送信されるデータが、パイプの帯域幅の制限を超えている、 (パイプが、以前に、使用されていなかった) なら、データの size バイトまで dummynet スケジューラをバイパスさせることができ、物理的なリンクが許容するのと同じくらい速く送信されます。任意の追加データは、 pipe 帯域幅によって指定されたレート (速度) で転送されます。バースト (burst) サイズは、パイプがどのくらい長く使用されていなかったかに依存します。有効なバースト (burst) サイズは、次のように計算されます: MAX( size, bw * pipe_idle_time)。

profile filename
リンクにおけるパケットの転送で被られる追加のオーバヘッドを指定するファイル。

いくつかのリンクタイプは、パケットの転送での特別の遅延、例えば、 MAC レベルフレーミング、チャネルの使用の競合、 MAC レベル再伝送などを導入します。私たちの観点からは、チャネルは、リンクタイプに従って、定数であるか、または変数である、この特別の時間を効果的に利用不可能です。さらに、パケットは、(例えば、あまりに多くの再伝送の後、無線リンクで) この時以降に落されるかもしれません。私たちは、分布を表す実験曲線で追加遅延をモデル化できます。

      累積確立 
      1.0 ^ 
          | 
      L   +-- loss-level          x 
          |                 ****** 
          |                * 
          |           ***** 
          |          * 
          |        ** 
          |       * 
          +-------*-------------------> 
                      遅延

実験曲線には、垂直線と水平線があります。垂直線は、確率の範囲に対する一定の遅延を表します。水平線は、遅延分布での不連続性に対応しています: パイプは、与えられた確率に対して最も大きな遅延を使用します。

ファイル形式は、セパレータとしての空白類とコメントの始めを示す '#' の作用があり、次の通りです:

name identifier
("ipfw pipe show"でリストされる) 遅延分布を識別するオプションの名前。
bw value
パイプのために使用される帯域幅。ここで指定されないなら、パイプのための設定パラメータとして明白に存在していなければなりません。
loss-level L
パケットが失われる上記の確率。 (0.0 <= L <= 1.0, デフォルト 1.0 すなわち、損失なし)。
samples N
内部の表現 (2..1024;デフォルト 100) で使用されるサンプルの数。
delay prob | prob delay
これらの 2 つの線の 1 つは、強制的であり、データポイントがある次の線の形式を定義します。
XXX YYY
選ばれた形式に従って、最初の遅延または確率のいずれかがある、曲線の点で表される 2 つ以上の線。遅延の単位は、ミリ秒です。データポイントは、ソートされる必要はありません。また、実際の線の数は、"samples"パラメータの値と異なっているかもしれません: ipfw ユーティリティは、必要に応じて曲線をソートして、補間します。

プロファイルの例は、次の通りです:

name    bla_bla_bla 
samples 100 
loss-level    0.86 
prob    delay 
0       200 # 最小のオーバヘッドは、200ms 
0.5     200 
0.5     300 
0.8     1000 
0.9     1300 
1       1300 
#設定ファイルの終わり

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

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

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

スケジューラのために次の大文字と小文字を区別しないパラメータを設定することができます:

type {fifo | wf2q+ | rr | qfq}
使用するスケジューリングアルゴリズムを指定します。
fifo
は、(すべてのパケットが、スケジューラに到着するとき、同じキューに格納されることを意味する) まさに FIFO スケジューラです。 FIFO は、(2GHz のデスクトップマシンで 60-80 ナノ秒と評価される) 非常に低い定数があるパケットごとに O(1) の時間の複雑さがありますが、サービスの保証は、与えられません。
wf2q+
は、重み付け従って帯域幅を共有するためにフローを許可する、 Weighted Fair Queueing アルゴリズムである、 WF2Q+ アルゴリズムを実装しています。重み付けは、優先順位でないことに注意してください。極めて小さい重み付けがあるフローでさえ、決して飢えません。 WF2Q+ には、パケットごとに O(log N) の処理コストがあります、ここで、N は、フローの数であり、以前のバージョンの dummynet のキューで使用されるデフォルトアルゴリズムです。
rr
は、O(1) の処理コスト (おおよそ、1 パケットあたり 100-150 ナノ秒) があり、重み付けに従って帯域幅の割り付けを許可しますが、不十分なサービス保証である、 Deficit Round Robin アルゴリズムを実装しています。
qfq
は、同様のサービス保証があり、O(1) 処理コスト (おおよそ、1 パケットあたり 200-250 ナノ秒) の WF2Q+ の非常に速い変異型である、QFQ アルゴリズムを実装しています。

タイプに加えて、スケジューラのためにパイプのために許可されたすべてのパラメータもまた指定することできます。

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

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

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

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

 

使用可能なマスク指定子は、次を組み合わせたものです。

dst-ip mask, dst-ip6 mask, src-ip mask, src-ip6 mask, dst-port mask, src-port mask, flow-id mask, proto mask または all

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

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

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

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

red | gred w_q/ min_th/ max_th/ max_p
RED (Random Early Detection) キュー管理アルゴリズムを使用します。 w_qmax_p は、0 から 1 (0 を含みません) の範囲の浮動小数点数であり、 min_thmax_th は、キュー管理用の閾値を指定する整数です (キューがバイト数で指定された場合は、閾値は、バイトで計算され、そうでない場合は、スロット数で計算されます)。 dummynet は、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 より大きい必要があります)

IPv6 データと共に使用した場合、 dummynet には現在いくつかの制限があります。インタフェースへのリンクローカルパケットを経路変更するために必要な情報は、 dummynet によって処理した後に利用可能でないので、それらのパケットは、出力経路 (path) で落とされます。リンクローカルパケットを dummynet に渡さないことを保証するよう心がけるべきです。

チェックリスト

規則を構成する際に考慮すべき重要な点をいくつか述べます。
  • かならず送信パケットと受信パケットの両方のパケットをフィルタリングします。ほとんどのネットワークコネクションでは、パケットが双方向に流れることが必要です。
  • テストは、細心の注意を払って行ないます。テストの際にはコンソールの近くにいるのがよいでしょう。コンソールに近寄れない場合、 /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) ソケットは、そのポートへ行き先変更されたパケットを、全部受けとります。宛先ポートにバインドされたソケットがない場合や、パケットの行き先変更ソケットモジュールがロードされていない場合、または、カーネルがパケットの行き先変更ソケットをサポートするようにコンパイルされていない場合は、パケットは、破棄されます。

ネットワークアドレス変換 (NETWORK ADDRESS TRANSLATION (NAT))

ipfw は、 libalias(3) のカーネルバージョンを使用するカーネル内 NAT をサポートします。

nat 設定コマンドは、次の通りです:

nat nat_number config nat-configuration

次のパラメータを設定することができます:

ip ip_address
エイリアシングに使用する IP アドレスを定義します。
if nic
NIC の IP アドレスが変更されるなら、アドレスを動的に変更して、エイリアシングのための NIC の IP アドレスを使用します。
log
この nat インスタンスでログ登録を有効にします。
deny_in
外側の世界からのあらゆる着信接続を拒否します。
same_ports
実際のローカルポート番号から変更されていない別名ポート番号をそのままとするようにします。
unreg_only
登録されていないアドレス空間を起源としないローカルネットワークのトラフィックは、無視されます。
reset
アドレス変更でパケットエイリアシングエンジンのテーブルをリセットします。
reverse
libalias がエイリアシングを取り扱う方法を逆にします。
proxy_only
トランスペアレント (透過的な) プロキシ規則だけに従い、パケットのエイリアシングは、実行されません。
skip_global
グローバルな状態検索 (下記参照) の場合のインスタンスをスキップします。

nat_number: の代わりにいくつかの特別な値を供給することができます:

global
すべての設定された nat のインスタンスの変換状態を検索します。エントリが見つけられるなら、パケットは、そのエントリに従って、エイリアスされます。エントリがインスタンスのいずれにも見つけられないなら、パケットは、変更されずに渡され、新しいエントリは、作成されません。詳しい情報については、 natd(8) のセクション 複数のインスタンス を参照してください。
tablearg
検索テーブルで供給された引数を使用します。検索テーブルの詳しい情報については、 検索テーブル セクションを参照してください。

エイリアス/デエイリアスされた後にパケットが続くようにするには、 sysctl 変数 net.inet.ip.fw.one_pass を 0 に設定します。エイリアシングモードに関する詳しい情報については、 libalias(3) を参照してください。 nat の使用法に関するいくつかの例についてはセクション 使用例 を参照してください。

IPFW のリダイレクションと LSNAT サポート

リダイレクトと LSNAT サポートは、 natd(8) で使用される構文に厳密に従います。リダイレクトと lsnat を行う方法のいくつかの例については、セクション 使用例 を参照してください。

SCTP NAT サポート

ipfw コマンドラインツールを通して TCP と同様の方法で sctp nat を設定することができます。主な違いは、 sctp nat がポート変換しないということです。ローカル側とグローバル側のポートが同じになるので、両方を指定する必要はありません。ポートは、次のようにリダイレクトされます:

nat nat_number config if  nic redirect_port sctp  ip_address [,addr_list] {[port |  port-port] [,ports]}

sysctl(8) インタフェースを通して、リアルタイムに、ほとんどの sctp nat 設定を行うことができます。すべて動的に変更されますが、 hash_table サイズは、新しい nat インスタンスのためにだけ変更します。詳しい情報については、 SYSCTL 変数 を参照してください。

ローダ調整変数

ipfw モジュールがロードされる前に、 loader(8) プロンプトで、 loader.conf(5) で、または kenv(1) で調整変数を設定することができます。
net.inet.ip.fw.default_to_accept: 0
ipfw の最後の規則の振る舞いを定義します。この値は、カーネル設定ファイルの options IPFW_DEFAULT_TO_(ACCEPT|DENY) を上書きします。
net.inet.ip.fw.tables_max: 128
ipfw の利用可能なテーブルの数を定義します。数は、65534 を越えることができません。

SYSCTL 変数

ひとそろいの sysctl(8) 変数は、ファイアウォールと関連するモジュール ( dummynet, bridge, sctp nat) の振る舞いを制御します。これらは、それらのデフォルト値 (しかし、 sysctl(8) コマンドで、どの値が実際に使用されているかを常にチェックします) と意味とともに以下に表示されます:
net.inet.ip.alias.sctp.accept_global_ootb_addip: 0
nat がグローバル OOTB ASCONF-AddIP の受信にどのように応答するかを定義します:
0
応答なし (部分的にマッチしているアソシエーションが存在していないなら - ポートと vtags は、マッチしますが、グローバルアドレスは、マッチしない)
1
nat は、すべての OOTB グローバル AddIP メッセージを受け付けて処理します。

オプション 1 は、これがセキュリティリスクを形成するように、決して選択されるべきではありません。攻撃者は、メッセージを AddIP に送信することによって、複数の偽のアソシエーションを設立できます。

net.inet.ip.alias.sctp.chunk_proc_limit: 5
既存のアソシエーションにマッチするパケットのために解析される SCTP パケットのチャンクの最大数を定義します。この値は、 net.inet.ip.alias.sctp.initialising_chunk_proc_limit 以上に強制されます。大きな値は、DoS のリスクがありますが、小さな値を設定することは、パケット中の重要な制御チャンクが位置付けられられず、解析されない結果となります。
net.inet.ip.alias.sctp.error_on_ootb: 1
nat が、ErrorM パケットで任意の Out-of-the-Blue (OOTB) パケットに応答するとき、定義します。 OOTB パケットは、 nat で登録された存在しない関連付けで到着するパケットであり、 INIT または ASCONF-AddIP パケットではありません:
0
ErrorM は、OOTB パケットに応答して決して送信されません。
1
ErrorM は、ローカル側で受信された OOTB パケットに送信されるだけです。
2
ErrorM は、ローカル側に送信され、グローバル側では、部分的なマッチがある場合のみ (ポートと vtags は、マッチしますが、発信元のグローバルな IP は、マッチしません)、送信されます。この値は、 nat がグローバル IP アドレスを追跡している場合にだけ、役に立ちます。
3
ErrorM は、ローカル側とグローバル側の両方で (DoS のリスク) すべての OOTB パケットに応答して送信されます。

ErrorM パケットは、ほとんどの SCTP スタックによってまだサポートされていないので、現在のところ、デフォルトは 0 です。それがサポートされるとき、グローバルなアドレスを追跡しないなら、マルチホームのローカルホストが nat で機能できるようにするために、この値を 1 に設定することを勧めます。グローバルなアドレスを追跡するために、グローバルなホストが、ASCONF-AddIP を (再) 送信する必要があるとき、それらを、通知できるように、この値を 2 に設定することを勧めます。 nat がすべての OOTB のグローバルなパケット (DoS のリスク) に応答するように、値 3 は、(デバッグのため以外に) 決して選択されるべきではありません。

net.inet.ip.alias.sctp.hashtable_size: 2003
nat 検索 (100 < prime_number > 1000001) のために使用されるハッシュテーブルのサイズ。この値は、将来に作成される nat インスタンスのための hash table (ハッシュテーブル) サイズを設定します、したがって、 nat インスタンスを作成する前に、設定されなければなりません。テーブルサイズは、特定の必要性に適合するように変更されるかもしれません。並列アソシエーションがわずかしかなく、メモリが十分でないなら、利用者は、これらをより小さくすることができます。数千 (または、数百万) の並列アソシエーションがあるなら、利用者は、これらをより大きくするべきです。テーブルサイズのためにいは、素数が、最も良いです。 sysctl 更新関数は、次の最も大きな素数に入力値を調整します。
net.inet.ip.alias.sctp.holddown_time: 0
SHUTDOWN-COMPLETE を受信した後に、この何秒のためのテーブルのアソシエーションを保持します。これによって、終点は、shutdown_complete が失われ、再伝送が必要であるなら、素直にシャットダウンを修正できます。
net.inet.ip.alias.sctp.init_timer: 15
(INIT-ACK|AddIP-ACK) を待つ間のタイムアウト値。この値は、0 であってはなりません。
net.inet.ip.alias.sctp.initialising_chunk_proc_limit: 2
そのパケットにマッチしない既存のアソシエーションが存在しないとき、解析される SCTP パケットのチャンクの最大数を定義します。理想的には、このパケットは、ちょうど INIT または ASCONF-AddIP パケットになるはずです。より大きな値は、不正な形式のパケットが処理のリソースを消費できるので、 DoS のリスクになるかもしれません。
net.inet.ip.alias.sctp.param_proc_limit: 25
パケットで解析されるチャンク内のパラメータの最大数を定義します。他の sysctl 変数と同様に、大きい値は、DoS のリスクを引き起こします。
net.inet.ip.alias.sctp.log_level: 0
システムログメッセージの詳細のレベル (0 -最小量、1 -イベント、 2 -情報、3 -詳細、4 -デバッグ、5 -最大デバッグ)。高い損失の環境において役に立つオプションです。
net.inet.ip.alias.sctp.shutdown_time: 15
SHUTDOWN-COMPLETE を待つ間のタイムアウト値。この値は、0 であってはなりません。
net.inet.ip.alias.sctp.track_global_addresses: 0
nat 内で追跡されるグローバル IP アドレスを、有効/無効にし、各アソシエーションのために追跡されるアドレスの数の上限を設けます。
0
グローバルな追跡は、無効にされています。
>1
追跡、各アソシエーションがこの値に制限されるための追跡されたアドレスの最大数を有効にします。

この変数は、完全に動的で、新しい値は、すべての新たに到着するアソシエーションに採用され、既存のアソシエーションは、以前のように取り扱われます。グローバルな追跡は、増強された処理負荷、メモリの使用量、複雑さ、と複数の nat で複合ネットワークで、あり得る nat の状態の問題のコストにおいて、 nat 内の衝突の数を減少させます。グローバル IP アドレスを追跡しないことをお勧めします、これはまた、完全に機能的な nat の結果となります。

net.inet.ip.alias.sctp.up_timer: 300
トラフィックなしのアソシエーションを維持するタイムアウト値。この値は、0 であってはなりません。
net.inet.ip.dummynet.expire: 1
未処理のトラフィックを持たない動的パイプ/キューを怠惰に削除します。この変数を 0 に設定することでこの動作を無効にすることができます。この場合、パイプ/キューは、閾値に達した場合にのみ削除されることになります。
net.inet.ip.dummynet.hash_size: 64
動的パイプ/キューに使用されるハッシュ表のデフォルトの大きさです。この値は、パイプ/キューを設定するときに buckets オプションが指定されなかった場合に使用されます。
net.inet.ip.dummynet.io_fast: 0
0 以外に設定されるなら、 dummynet 操作 (上記参照) の“fast”モードは、有効にされます。
net.inet.ip.dummynet.io_pkt
dummynet に渡されるパケットの数。
net.inet.ip.dummynet.io_pkt_drop
dummynet によって落されたパケットの数。
net.inet.ip.dummynet.io_pkt_fast
dummynet スケジューラによってバイパス (迂回) させたパケットの数。
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.dummynet.pipe_byte_limit: 1048576
net.inet.ip.dummynet.pipe_slot_limit: 100
バイト単位またはパケット数で指定できる最大のキューサイズ。これらの制限は、mbufs のようなリソースの偶然の枯渇を防ぎます。これらの制限を上げるなら、十分なリソースが利用可能とできるように、システムが設定されることを確実にするべきでです。
net.inet.ip.fw.autoinc_step: 100
規則番号を自動生成する際の規則番号間の増分です。この値は、1 から 1000 の範囲でなければなりません。
net.inet.ip.fw.curr_dyn_buckets: net.inet.ip.fw.dyn_buckets
動的規則のハッシュ表内の現在のバケットの個数です (読み出しのみ可能)。
net.inet.ip.fw.debug: 1
ipfw が生成するデバッグメッセージを制御します。
net.inet.ip.fw.default_rule: 65535
デフォルトの規則番号 (読み込み専用)。 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_lifetimedyn_rst_lifetime は、厳密に 5 秒 (キープアライブを繰り返す周期) より短くなければなりません。ファイアウォールではこれが強制されます。
net.inet.ip.fw.enable: 1
ファイアウォールを有効にします。この変数を 0 に設定すると、マシンがコンパイル時に有効の設定がされている場合であっても、ファイアウォールがない状態で実行されます。
net.inet6.ip6.fw.enable: 1
IPv6 の場合について、上記と同じ機能性を提供します。
net.inet.ip.fw.one_pass: 1
設定されている場合、 dummynet パイプ、または ng_ipfw(4) ノードから出てくるパケットは、再度ファイアウォールを通過することはありません。そうでない場合、アクションの後、パケットは、次の規則でファイアウォールに再注入されます。
net.inet.ip.fw.tables_max: 128
テーブルの最大数。
net.inet.ip.fw.verbose: 1
冗長メッセージを有効にします。
net.inet.ip.fw.verbose_limit: 0
冗長出力を行うように設定されたファイアウォールが生成するメッセージ数を制限します。
net.inet6.ip6.fw.deny_unknown_exthdrs: 1
有効にした場合、不明な IPv6 拡張ヘッダつきのパケットは、拒否されます。
net.link.ether.ipfw: 0
ipfw がレイヤ 2 パケットを通すかどうかを制御します。デフォルトは、no です。
net.link.bridge.ipfw: 0
ipfw がブリッジされたパケットを通すかどうかを制御します。デフォルトは、no です。

使用例

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 つ以上のサブネットの管理者であるなら、アドレスセットと論理和 (OR) ブロックをうまく利用し、下記のように、クライアントのブロックへのサービスを選択的に有効にする非常にコンパクトな規則セットを記述することができます。

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 ...

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

ipfw add deny ip from any to any not verrevpath in

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

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

ipfw add deny ip from any to any not antispoof in

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

規則セットの適切な場所に次を追加することによって、ユーザのトラフィックを (再)マークするために setdscp オプションを使用できるかもしれません:

ipfw add setdscp be ip from any to any dscp af11,af21

動的規則

にせの 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 または limit 規則の最初の発生に遭遇したときにチェックされます。規則セットのスキャン量を最小にするために、 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 をシミュレーションなどで使う際の使用方法を示しています。

この規則は、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

検索テーブル

次の例では、いくつかのトラフィック帯域幅のクラスを作成する必要があり、異なったホスト/ネットワークを異なったクラスにする必要があります。各クラスごとに 1 つのパイプを作成し、それぞれそれらを設定します。次に、1 つのテーブルを作成し、IP サブネットとアドレスをそれに書き込みます。各サブネット/ホストのために、それが使用するべきであるパイプの数と同じ数の引数を設定します。次に、1 つの規則を使用してトラフィックを分類します:

ipfw pipe 1 config bw 1000Kbyte/s
ipfw pipe 4 config bw 4000Kbyte/s
...
ipfw table 1 add 192.168.2.0/24 1
ipfw table 1 add 192.168.0.0/27 4
ipfw table 1 add 192.168.0.2 1
...
ipfw add pipe tablearg ip from table(1) to any

fwd アクションを使用して、テーブルエントリは、ホスト名と IP アドレスを含むことができます。

ipfw table 1 add 192.168.2.0/24 10.23.2.1
ipfw table 1 add 192.168.0.0/27 router1.dmz
...
ipfw add 100 fwd tablearg ip from any to table(1)

次の例で、インタフェースごとのファイアウォールが作成されます:

ipfw table 10 add vlan20 12000
ipfw table 10 add vlan30 13000
ipfw table 20 add vlan20 22000
ipfw table 20 add vlan30 23000
..
ipfw add 100 ipfw skipto tablearg ip from any to any recv 'table(10)' in
ipfw add 200 ipfw skipto tablearg ip from any to any xmit 'table(10)' out

規則セット

規則セットを不可分に追加するためには、次の通りです、例えば、セット 18:

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

規則セットを不可分に削除するためには、コマンドは、単に次の通りです: To delete a set of rules atomically the command is simply:

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 が終了した後で無効な状態になるので以前の状態が復元されます。

特定のセットの規則を表示するためには:

ipfw set 18 show

無効にされた規則を表示するためには:

ipfw -S set 18 show

特定のセットの特定の規則のカウンタをクリアするためには:

ipfw set 18 zero NN

特定のセットの特定の規則を削除するためには:

ipfw set 18 delete NN

NAT, リダイレクトと LSNAT

最初に、nat インスタンス 123 へのすべてのトラフィックをリダイレクトします:

ipfw add nat 123 all from any to any

次に、IP 192.168.0.123 ですべての発信トラフィックをエイリアスするために nat インスタンス 123 を設定するためには、次のように、すべての着信接続をブロックし、両側の同じポートを保持することを試み、アドレスの変更でエイリアシングテーブルをクリアして、トラフィック/リンク統計のログを保持します。

ipfw nat 123 config ip 192.168.0.123 log deny_in reset same_ports

または、インスタンス 123 のアドレスを変更するるためには、エイリアシングテーブルを、クリアします (リセットオプションを参照):

ipfw nat 123 config ip 10.0.0.1

nat インスタンス 123 の設定を見るためには:

ipfw nat 123 show config

範囲 111-999 のすべてのインスタンスのログを表示するためには:

ipfw nat 111-999 show

すべてのインスタンスの設定を見るためには:

ipfw nat show config

または、mixed モードでリダイレクトの規則は、次のようになるでしょう:

ipfw nat 123 config redirect_addr 10.0.0.1 10.0.0.66
redirect_port tcp 192.168.0.1:80 500
redirect_proto udp 192.168.1.43 192.168.1.1
redirect_addr 192.168.0.10,192.168.0.11
10.0.0.100 # LSNAT
redirect_port tcp 192.168.0.1:80,192.168.0.10:22
500 # LSNAT

または、次のように分割することができるでしょう:

ipfw nat 1 config redirect_addr 10.0.0.1 10.0.0.66
ipfw nat 2 config redirect_port tcp 192.168.0.1:80 500
ipfw nat 3 config redirect_proto udp 192.168.1.43 192.168.1.1
ipfw nat 4 config redirect_addr 192.168.0.10,192.168.0.11,192.168.0.12
10.0.0.100
ipfw nat 5 config redirect_port tcp
192.168.0.1:80,192.168.0.10:22,192.168.0.20:25 500

歴史

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

作者

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

API は、BSDI のために Daniel Boulet によって書かれたコードに基づいています。

dummynet は、1997-1998 年に Luigi Rizzo によって導入されました。

Akamba Corp によってサポートされた dummynet トラフィックシェイパでいくらかの初期の作業 (1999-2000)。

ipfw コア (ipfw2) は、2002 年夏に Luigi Rizzo によって完全に再設計され、再実装されました。更なるアクションとオプションは、数年間様々な開発者によって追加されました。

カーネル内 NAT サポートは、Summer of Code 2005 プロジェクトの一環として Paolo Pisati <piso@FreeBSD.org>によって書かれました。

SCTP nat のサポートは、 The Centre for Advanced Internet Architectures (CAIA) <http://www.caia.swin.edu.au>によって開発されました。主要な開発者とメンテナは、David Hayes and Jason But です。詳細については、次を訪問してください: <http://www.caia.swin.edu.au/urp/SONATA>

遅延のプロファイルは、Projects Onelab と Onelab2 内の European Commission によってサポートされ、 Alessandro Cerri と Luigi Rizzo によって開発されました。

バグ

構文は、年月を重ねるにつれて成長しています、ときどき混乱させられるかもしれません。残念ながら、後方互換性のために、構文の定義で行われた誤りを訂正することができません。

!!! 警告 !!!

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

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

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

dummynet は、IPv6 リンクローカルアドレスを持つ全てのパケットを破棄します。

uid または gid を使用した規則は、予期した動作にはならないかも知れません。特に、外から入ってくる SYN パケットはまだ TCP 接続していないため、これらに関連付けられた uid または gid がありません。またパケットに関連付けられる uid/gid は、もし関連付けられたプロセスが setuid(2) か類似のシステムコールを呼んでいた場合、予測できないものになります。

規則構文は、コマンドライン環境に制約されており、いくつかのパターンは、バックスラッシュ文字でエスケープされるか、または適切にクォートされる必要があります。

libalias(3) のアーキテクチャのために、 ipfw nat は、tcp セグメンテーションオフローディング (tcp segmentation offloading (TSO)) と互換性がありません。したがって、利用者のネットワークトラフィックを確実に nat するためには、 ifconfig(8) を使用して NIC の TSO を無効にしてください。

ICMP エラーメッセージは、それぞれの通信のための動的な規則によって暗黙にマッチされません。ネットワークエラー検出とパス MTU 検索の失敗を避けるために、 ICMP エラーメッセージは、静的な規則を通して明白に許可される必要があります。

callreturn アクションを使用する規則は、規則セットに誤りがあるなら、混乱した振る舞いを導くかもしれません、そして/または、他のサブシステム (netgraph、dummynet など) との相互作用が、使用されます。これのための 1 つのあり得る事例は、後で最初に対になっていない return に遭遇する出力の間に、入力パスでサブルーチンの ipfw から出るパケットです。呼び出しスタックが入力パスの後にそのまま保持されるように、パケットは、出力パスでなく、入力パスで使用される規則番号に突然戻ります。処理の順序は、そのような誤りを避けるために注意深くチェックされるべきです。

October 25, 2012 FreeBSD