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 table number add
addr[ ipfw {pipe | queue} number
config config-options ipfw [−cfnNqS] [ 解説 |
ipfw とそのユーティリティは FreeBSD の ipfw(4) ファイアウォールと dummynet(4) トラフィックシェイパを制御するユーザインタフェースです。 注: このマニュアルページは 2002 年 7 月に FreeBSD 5.0 に導入され ipfw2 としても知られている ipfw の新バージョンについて説明していま す。 ipfw2 は旧版のファイアウォール ipfw1 のスーパセットです。この 2 つの違いはセクション IPFW2 拡張に列挙されています。古いルールセットを 書き直し、より効率的にするために、ここを読むことをお勧めします。 FreeBSD 4.x で ipfw2 を実行する手順については、セクション FreeBSD 4.x で IPFW2 を使うを参照下さい。 ipfw の設定、もしくは ルールセットは、1 から 65535 までの番号をつけられた ルールのリストからなります。パケットはプロトコルスタック中のいくつかの箇 所から ipfw に渡されます (パケットの発信元と宛先によっては、 ipfw は同じ パケットに対して複数回起動させられる可能性があります)。ファイアウォールに 渡されるパケットはファイアウォールの ルールセット中のルールそれぞれに対し て照合されます。 マッチした場合、マッチしたルールに対応するアクションが実行されます。アク ションと実際のシステムの設定によっては、マッチしたルールの後のルールでさ らに処理を行うためにパケットがファイアウォールに再注入されることがありま す。 ipfw ルールセットには常に デフォルトルール (番号 65535) が含まれます。こ のルールは変更も削除もできず、全パケットにマッチします。 デフォルトルール に関連付けられるアクションは deny か allow のどちらかになりますが、これは どのようにカーネルを設定したかに依存します。 ルールセットがオプション 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 −d −e −f −n −N −q −S −s [field] −t −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] この中で、ルールのボディ (body) は次の中からどの情報を使用してパケットを フィルタするかを指定します。 |
レイヤ 2 ヘッダフィールド
可能ならば 上記の情報のうち幾つか、例えば、送信元 MAC アドレスまたは IP アドレスと TCP/UDP ポートは容易に詐称が可能であることに注意して下さい。したがって、 これらのフィールドのみでフィルタすることは必ずしも望ましい結果を保証しま せん。 rule_number set set_number prob match_probability 注: この条件は、他の条件の前にチェックされます。これに は、keep-state や check-state といった副作用のあるものも含まれま す。 log [logamount number] 一度制限に達したなら、このエントリに対するロギングカウンタかパ ケットカウンタをクリアすれば記録を再び有効にすることができます。 resetlog コマンドを参照して下さい。 注: ログが実行されるのは、すべてのパケットマッチ条件が成功裏に確 認された後であり、最後の動作 (受理や拒否等) をパケットに実施する 前です。 ルールアクション allow | accept | pass |
permit check-state count deny | drop divert port fwd | forward
ipaddr[,port] ipaddr
がローカルアドレスの場合、マッチしたパケットはローカルマシ
ンの port
(または、ルールで指定されていない場合はそのパケットの
ポート番号) に転送されます。 fwd を有効にするには、カーネルをオプション options IPFIREWALL_FORWARD を付けてコンパイルすることが必要です。追加のオ プション options IPFIREWALL_FORWARD_EXTENDED を指定することで、安 全策がすべて外され、ローカルに設定された IP アドレス宛のパケット をリダイレクトすることも可能になります。そのようなルールはローカ ルに生成されたパケットにも適用されるので、 ICMP メッセージサイズ 超過などのような自動的に生成されるパケットが適切に振る舞うよう細 心の注意が必要なことに注意して下さい。 pipe pipe_nr queue queue_nr reject reset skipto number tee port unreach code ルールボディ 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: [ { protocol or ... } 書式 (論理和ブロック) は、簡便さのためだけに 提供されており、価値が低下しています。 src and dst: { 第 2 の書式 (複数アドレス付きの 論理和ブロック) は、簡便さのため だけに提供されており、価値が低下しています。 addr: [ any me table(number[,value]) addr-list: ip-addr[,addr-list] ip-addr: numeric-ip | hostname addr/masklen addr:mask addr-set: addr[ list: { ports: { ポート数値の代わりに (ファイル /etc/services から取った) サービス 名を使用できます。ポートリストの長さは 30 ポートまたはポート範囲 に制限されていますが、ルールの options セクションで 論理和ブロッ クを使用することにより、より広い範囲を指定することができます。 バックスラッシュ (‘\’) を使用することにより、サービス名中のダッ シュ (‘-’) 文字をエスケープ可能です (シェルから入力するとき、シェ ル自身がバックスラッシュをエスケープ文字として解釈するのをさける ために、バックスラッシュを 2 回タイプしなければなりません)。 ipfw add count tcp from any ftp\\-data-ftp to any 断片化されたパケットでオフセットが非 0 のもの (すなわち、最初の断 片ではないもの) は、 1 つ以上のポート指定を持つルールにはマッチし ません。断片化されたパケットへのマッチングに関する詳細は frag オ プションを参照してください。 ルールオプション
(マッチパターン) 以下のマッチパターンが使用できます (アルファベット順に並べています)。 // this is a comment. bridged dst-ip ip-address dst-port ports established frag gid group jail prisonID icmptypes types エコー応答 (0), 宛先到達不可 (3), 発信元抑制 (4), リダイレクト (5), エコー要求 (8), ルータ広告 (9), ルータ要請 (10), 時間超過 (11), IP ヘッダ異常 (12), タイムスタンプ要求 (13), タイムスタンプ 応答 (14), インフォメーション要求 (15), インフォメーション返答 (16), アドレスマスク要求 (17), アドレスマスク応答 (18) in | out ipid id-list iplen len-list ipoptions spec ssrr (ストリクトソースルーティング), lsrr (ルーズソースルーティン グ), rr (レコードルート), ts (タイムスタンプ)。 ‘!’ を置くことで 特定のオプションが存在しないという記述ができます。 ipprecedence precedence ipsec ipsec を指定することは、 proto ipsec を指定することとは違います。 何故なら後者は、IPSEC カーネルサポートの有無および IPSEC データの 正当性にかかわらず、特定の IP プロトコルフィールドのみを見るから です。 更に、IPSEC サポート無しのカーネルでは、このオプションは黙って無 視されることに注意してください。この場合、このフラグを指定しても ルール処理に影響が無く、あたかも ipsec フラグが指定されていないか のように当該ルールが処理されます。 iptos spec lowdelay (IPTOS_LOWDELAY), throughput (IPTOS_THROUGHPUT), reliability (IPTOS_RELIABILITY), mincost (IPTOS_MINCOST), congestion (IPTOS_CE) 。 ‘!’ を置くことで特定のオプションが存在し ないという記述ができます。 ipttl ttl-list ipversion ver keep-state layer2 limit { { MAC | mac } dst-mac src-mac 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 proto protocol recv | xmit | via {ifX |
if* | ipno | any} via キーワードにより、指定したインタフェースが常にチェックされる ことになります。 recv や xmit が via の代わりに使用された場合、そ れぞれ、受信インタフェースのみ、または送信インタフェースのみが チェックされます。両方とも指定した場合、送信インタフェースと受信 インタフェースの両方に基づくパケットのマッチが可能になります。例 えば次のようになります。 ipfw add deny ip from any to any out recv ed0 xmit ed1 recv インタフェースは到着または送出パケットのどちらかについて検査 することができますが、 xmit インタフェースは送出パケットのみにつ いて検査することができます。したがって xmit を使用する場合には out は必須です (そして in は無効となります)。 パケットが受信インタフェースや送信インタフェースを持たないことが あります。ローカルホストから発生したパケットは受信インタフェース を持ちませんし、ローカルホストに到着する予定のパケットは送信イン タフェースを持ちません。 setup src-ip ip-address src-port ports tcpack ack tcpflags spec fin, syn, rst, psh, ack, urg 。 ‘!’ を置くことで特定のフラグが存 在しないという記述ができます。 tcpflags の指定を含むルールは、0 でないオフセットを持つフラグメントパケットには決してマッチするこ とはありえません。フラグメントパケットのマッチについての詳細は frag オプションを参照して下さい。 tcpseq seq tcpwin win tcpoptions spec mss (最大セグメントサイズ), window (TCP ウィンドウ広告), sack (選 択的 ACK), ts (RFC1323 タイムスタンプ), cc (RFC1644 T/TCP コネク ションカウント)。 ‘!’ を置くことで特定のオプションが存在しないと いう記述ができます。 uid user 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 つ組もしく はホスト名で指定された) ベースアドレス addr と masklen ビット幅のマスクで 表されるアドレスすべてにマッチします。 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-state や limit ルールにマッチ したときで、その結果、与えられた protocol を持ち、 src-ip/src-port dst-ip/dst-port のアドレスの組の間のパケット全てのみにマッチする 動的ルー ルが生成されます (src と dst はここでは最初にマッチしたアドレスを区別する ためにのみ使用しています。その後、両者は完全に等価になります)。動的ルール は最初に 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
ポリシの効率的な変種で す。 実際の使い方として、 pipe を使い、フローが取り得るバンド幅にハードリミッ トを設けることができます。一方で、 queue を使い、異なるフローがどのように して利用可能なバンド幅を山分けするかを決定することができます。 pipe と queue の設定コマンドは次の通りです。 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 次のパラメータをキューに対して設定できます。 pipe pipe_nr weight weight 最後に、次のパラメータをパイプやキューに対して設定できます。 buckets hash-table-size mask mask-specifier このようにして、
動的パイプを使用するとき、フローそれぞれはパイプで
指定したものと同じバンド幅を得ます。一方、
動的キューを使用する時、
フローそれぞれは、同じキューにより生成された他のフローと、親パイプ
のバンド幅を均等に山分けします
(異なる重みを持つ他のキューが同じパ
イプに接続される場合があることに注意して下さい)。 dst-ip mask, src-ip mask, dst-port mask, src-port mask, proto mask, all 最後の指定子は、すべてのフィールドのすべてのビットが検査されること を意味しています。 noerror plr packet-loss-rate queue {slots |
sizeKbytes} red | gred
w_q/min_th/max_th/max_p net.inet.ip.dummynet.red_lookup_depth net.inet.ip.dummynet.red_avg_pkt_size net.inet.ip.dummynet.red_max_pkt_size チェックリスト |
ルールを構成する際に考慮すべき重要な点をいくつか述べます。 |
• かならず送信パケットと受信パケットの両方のパケットをフィルタリングします。ほとんどのネットワークコネクションではパケットが双方向に流れることが必要です。
• テストは細心の注意を払って行ないます。テストの際にはコンソールの近く にいるのがよいでしょう。コンソールに近寄れない場合、 /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 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 net.inet.ip.dummynet.max_chain_len: 16 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 net.inet.ip.fw.autoinc_step: 100 net.inet.ip.fw.curr_dyn_buckets:
net.inet.ip.fw.dyn_buckets net.inet.ip.fw.debug: 1 net.inet.ip.fw.dyn_buckets: 256 net.inet.ip.fw.dyn_count: 3 net.inet.ip.fw.dyn_keepalive: 1 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 net.inet.ip.fw.enable: 1 net.inet.ip.fw.one_pass: 1 net.inet.ip.fw.verbose: 1 net.inet.ip.fw.verbose_limit: 0 net.link.ether.ipfw: 0 net.link.ether.bridge_ipfw: 0 FreeBSD 4.x で IPFW2 を使う |
ipfw2 は、 FreeBSD 5.x と 6.0 で標準となっていますが、 FreeBSD 4.x では、 カーネルを options IPFW2 を付けてコンパイルし、 /sbin/ipfw と /usr/lib/libalias を -DIPFW2 を付け (buildworld の前に /etc/make.conf に IPFW2=TRUE を追加しておくことで同じ効果を得ることができます) 再コンパイ ル、再インストールしない限り、今でも ipfw1 を使用します。 |
IPFW2 拡張
このセクションでは ipfw2 で導入され、 ipfw1 には存在しなかった機能の一覧 を示します。ここではルールセットを記述する際に影響が大きいと思われる順に 示します。より効果的なやり方でルールセットを記述するためにこれらの機能を 使用したいと思うかもしれません。 |
文法とフラグ
ipfw1 は、-n フラグ (文法チェックのみ) をサポートしませんし、コン マの後の空白をサポートしませんし、単一引数中での全ルールフィール ドをサポートしません。 ipfw1 では -p フラグ (プリプロセッサ) とと もに -f フラグ (強制) を指定することはできません。 ipfw1 は -c ( コンパクト) フラグをサポートしません。 非 IPv4 のパケットの取り扱い ipfw add 1 allow layer2 not mac-type ip layer2 オプションは冗長であるように見えますが、必要です。レイヤ 3 からファイアウォールを通るパケットは MAC ヘッダを持たないので、 mac-type ip パターンはレイヤ3のパケットに対して常に失敗します。つ まり、 not オペレータをおくと全てを通過させるルールになってしまい ます。 宛先 ポートの指定 最後に、 ipfw1 では最初のポートエントリを port:mask と指定するこ とができました。ここで mask は任意の 16 ビットマスクが使用可能で す。この文法が有用であるかどうかは疑問なので ipfw2 ではもはやサ ポートされていません。 論理和ブロック キープアライブ ルールセット MAC ヘッダによるフィルタとレイヤ 2
のファイアウォール オプション 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 オプション 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 |
トラフィックシェイパ |
次のルールは、 ipfw と dummynet(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, 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 |