ipf, ipf.conf, ipf6.conf − IP パケットフィルタのルール文法 |
ipf のルールファイルは、どんな名前でも良く、標準入力でもかまいません。 カーネル内部のフィルタリストを表示するとき、 ipfstat は解釈可能なルール を出力しますので、この出力を ipf への入力としてフィードバックするのに使 えます。よって、入力パケットに対する全フィルタを除去するためには、次 の ようにします: # ipfstat −i | ipf −rf − |
ipf がフィルタルール構築に使用するフォーマットは、 BNF を使った文法で次 のように示すことができます: filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ] [ proto ] [ ip ] [ group ]. insert = "@" decnumber . action = block | "pass" | log | "count" | skip | auth | call . in-out = "in" | "out" . options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ] ] . tos = "tos" decnumber | "tos" hexnumber . ttl = "ttl" decnumber . proto = "proto" protocol . ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] . group = [ "head" decnumber ] [ "group" decnumber ] . block = "block" [ return-icmp[return-code] | "return-rst" ] . auth = "auth" | "preauth" . log = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] . call = "call" [ "now" ] function-name . skip = "skip" decnumber . dup = "dup-to" interface-name[":"ipaddr] . froute = "fastroute" | "to" interface-name[":"ipaddr] . protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber . srcdst = "all" | fromto . fromto = "from" [ "!" ] object "to" [ "!" ] object . return-icmp = "return-icmp" | "return-icmp-as-dest" . object = addr [ port-comp | port-range ] . addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] . port-comp = "port" compare port-num . port-range = "port" port-num range port-num . flags = "flags" flag { flag } [ "/" flag { flag } ] . with = "with" | "and" . icmp = "icmp-type" icmp-type [ "code" decnumber ] . return-code = "("icmp-code")" . keep = "keep" "state" | "keep" "frags" . loglevel = facility"."priority | priority . nummask = host-name [ "/" decnumber ] . host-name = ipaddr | hostname | "any" . ipaddr = host-num "." host-num "." host-num "." host-num . host-num = digit [ digit [ digit ] ] . port-num = service-name | decnumber . withopt = [ "not" | "no" ] opttype [ withopt ] . opttype = "ipopts" | "short" | "frag" | "opt" optname . optname = ipopts [ "," optname ] . ipopts = optlist | "sec-class" [ secname ] . secname = seclvl [ "," secname ] . seclvl = "unclass" | "confid" | "reserv-1" | "reserv-2" | "reserv-3" | "reserv-4" | "secret" | "topsecret" . icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" | "timex" | "paramprob" | "timest" | "timestrep" | "inforeq" | "inforep" | "maskreq" | "maskrep" | decnumber . icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" | "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" | "net-prohib" | "host-prohib" | "net-tos" | "host-tos" | "filter-prohib" | "host-preced" | "cutoff-preced" . optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | "addext" | "visa" | "imitd" | "eip" | "finn" . facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" | "lpr" | "news" | "uucp" | "cron" | "ftp" | "authpriv" | "audit" | "logalert" | "local0" | "local1" | "local2" | "local3" | "local4" | "local5" | "local6" | "local7" . priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" | "info" | "debug" . hexnumber = "0" "x" hexstring . hexstring = hexdigit [ hexstring ] . decnumber = digit [ decnumber ] . compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" | "le" | "ge" . range = "<>" | "><" . hexdigit = digit | "a" | "b" | "c" | "d" | "e" | "f" . digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" . flag = "F" | "S" | "R" | "P" | "A" | "U" . この文法は、可読性のためにいくぶん簡略化しています。この文法にマッチ す る 組み合わせであっても、意味をなさないためにソフトウェアが許可しないも のがあります (非 TCP パケットに対する tcp flags など)。 |
「最短」かつ有効なルールは (現在のところ) 無動作と次の形式です: block in all pass in all log out all count in all フィルタルールは順番通りにチェックされ、最後にマッチしたルールがパ ケッ トの運命を決めます (例外: 後述 quick オプションを参照)。 デ フォルトでは、フィルタはカーネルのフィルタリストの最後にインストール されます。ルールの前に @n を付けると、現在のリストの n 番目のエントリと し て挿入するようになります。これは、現在有効なフィルタのルールセットを 修正したりテストする場合に有用です。更なる情報は ipf(8) を参照してく だ さい。 |
ア クションは、フィルタルールの残りの部分にパケットがマッチする場合に、 そのパケットをどのように扱うのかを示します。各ルールは、アクションを 1 つ持つことが「必要です」。次のアクションが認識されます: |
block |
このパケットを、ドロップするように印を付けることを示しま す。パケットをブロックす る こ と に 対 し、 ICMP パ ケッ ト (return-icmp) か、元のパケット送信宛先起源を装う ICMP パケット (return-icmp-as-dest) か、 TCP 「リセット」 (return-rst) の、い ず れ かの返答パケットを返すよう、フィルタに指示できます。 ICMP パケットは、任意の IP パケットの応答として生成でき、そのタイ プ を指定することもできます。 TCP リセットは、TCP パケットに対して 適用されるルールにおいてのみ使用できます。 return-icmp ま た は return-icmp-as-dest を使うとき、到達不可の ’タイプ’ を指定可能 です。このタイプとは、ネットワーク到達不可、ポート到達不可、 権 限 に よ る 禁止のいずれかです。指定方法は、 return-icmp または return-icmp-as-dest の直後に、タイプに関連する ICMP コードを 括 弧で括るというものです。例えば |
block return-icmp(11) ... |
とすると、Type-Of-Service (TOS) ICMP 到達不可エラーを返します。 |
pass |
このパケットを、そのままフィルタを通過させるように印を付 けます。 |
||
log |
このパケットのログを取ります (後述のロギング節 参 照)。 パ ケットがフィルタを通過可能か否かには、影響を与えません。 |
||
count |
このパケットを、フィルタのアカウンティング統計に含めま す。パケットがフィルタを通過可能か否かには、影響を与えませ ん。 統計は ipfstat(8) にて閲覧可能です。 |
||
call |
このアクションは指定されたカーネル内関数を呼び出すために 使用されます。カーネル内関数は、特定の呼び出しインタフェース を 満 す必要があります。カスタマイズしたアクションとセマンティクス を実装し、利用可能なアクションを補うことができます。知識があ る ハッ カー が 使用する機能であり、現在のところ文書化されていませ ん。 |
skip <n> |
フィルタに、次の n フィルタルールをスキップさせます。スキップさ れる範囲のルールに挿入または除去があった場合、 n の値は適切に調 整されます。 |
auth |
これにより、ユーザ空間プログラムを実行して正当性を確認 す る パケット情報を待つことにより、認証できます。プログラムがカー ネルに対してパケット通過を許すか否かの実際の フラグを返すまでの 間、 パケットは内部バッファに保持されます。パケット通過を許す前 または認識されない送信元からのパケットをカーネルに落すよう指 示 す る前に、このようなプログラムは、送信元アドレスを見るかもしれ ませんし、ユーザからの (パスワード等の) ある種の認証を求める か もしれません。 |
preauth |
こ のクラスのパケットに対しては、更なる明確化のために既に認証さ れたリストを見るべきであると、フィルタに指示します。更にマッ チ す るルールが見付からないと、パケットは落とされます (FR_PREAUTH は FR_PASS と同じではありません)。更にマッチするルールが見付 か る と、その結果が使用されます。これが使用される状況は、ユーザが ファイアウォールにログインし、このユーザに関する一時的なルー ル を設定するような場合です。 |
次の語は in か out のいずれかである必要があります。カーネル内部を通過す るパケットは、内向き (インタフェースにて受信されたばかりで、カーネル の プ ロトコル処理部に向って移動している) か、外向き (プロトコルスタックに より送出または転送され、インタフェースに向かっている) かのいず れ か で す。 各フィルタルールが入出力のどちら側に適用されるのかを、明示的に示す 必要があります。 |
オプションの一覧は短く、事実すべて省略可能です。オプションが使用され る と ころでは、ここに示す順序で置かれる必要があります。次のオプションが現 在サポートされています: |
log |
最後にマッチするルールの場合、パケットヘッダが ipl ログ に 書き込まれます (後述のロギング節参照)。 |
||
quick |
フィルタを高速化したり後続のルールよりも優先させるため に、ルールの「ショートカット」を許します。パケットが quick の印 が 付 い た フィ ルタルールにマッチする場合、このルールが最後に チェックされるルールになり、「短絡 (short-circuit)」パスによ り 後 続のルールがこのパケットに対して処理されなくなります。 (現在 のルールが適用された後に) パケットの現在の状態が、パケットが 通 過されるかブロックされるかを決定します。 |
こ の オプションが指定されないと、ルールは「継続(fall-through)」 ルールとされます。つまり、マッチの結果 (ブロック/通過) が保存 さ れ、更なるマッチがあるかをみるため処理が継続されます。 |
on |
マッチ手続きにインタフェース名を組み込みます。インタフェー ス名は "netstat −i" で表示できます。このオプションを使 用 す る と、 指定した方向 (入出力) にこのインタフェースを通過するパケッ トに対してのみ、このルールがマッチします。このオプションが指 定 さ れないと、ルールはこのパケットが置かれたインタフェースに依存 せずに (すなわち全インタフェースに) 適用されます。フィルタ ルー ル セットは全インタフェースに共通であり、各インタフェースに対し てフィルタリストを持つのではありません。 |
このオプションは特に、単純な IP 詐称 (IP spoofing) に対する防 御 として有用です: 指定したインタフェース上で、指定した送信元アドレ スであるとされる入力パケットのみを通し、他のパケットをログしたり ドロップすることができます。 |
dup-to |
パケットをコピーし、複写したパケットを指定したインタ フェースに対して外向きに送ります。また、宛先 IP アドレスを指 定 し て、変更することができます。ネットワークスニファを使用して、 ホスト外でログするために有用です。 |
|
to |
指定したインタフェースにおいて、パケットを外向きキューに 移 動 させます。カーネルのルーティングを回避するために使用でき、パ ケットに対する残りのカーネル処理をバイパスするためにも使用で き ま す (内向きルールに適用された場合)。よって、ルータではなく、 フィルタリングハブやスイッチのように、透過的に動作するファイ ア ウォールを構築することができます。 fastroute キーワードは、この オプションの同義語です。 |
この節に記載されているキーワードは、ルールがマッチするか否かを決定す る と きに、パケットのどの属性を使用するのかを記述するために使用されます。 以下の汎用属性がマッチングに使用でき、この順序で使用する必要があります: |
tos |
異なるサービス型 (Type-Of-Service) 値を持つパケットをフィ ルタできます。この上、個々のサービスレベルや組み合わせでフィ ル タ できます。 TOS マスクに対する値は、16 進数または 10 進数の整 数で表現されます。 |
||
ttl |
パケットを生存時間 (Time-To-Live) 値で選択することもできま す。 フィルタルールで与えられる値は、マッチが行われるパケットの 値と厳密にマッチする必要があります。この値は、10 進数の整数での み与えることができます。 |
||
proto |
特 定 の プロトコルに対してマッチすることができます。 /etc/protocols 中の全プロトコル名が認識されますし、使用可 能 で す。 また、プロトコルを 10 進数で指定することもできます。これに より、あなた独自のプロトコルや新しいプロトコルであるためリス ト が 古くて掲載されていないものに対し、マッチするルールを作成でき ます。 |
TCP または UDP パケットにマッチする、特殊なプロトコルキーワー ド tcp/udp を使用することができます。このキーワードは、同じルールを いくつも書かなくてもよいようにするため、追加されました。 |
from と to のキーワードは、 IP アドレス (および省略可能なポート番号) と マッ チさせるために使用されます。送信元と送信先の「両方の」パラメータを 指定する必要があります。 IP アドレスの指定方法は、次の 2 つのうちのいずれかです: 数値によるア ド レス/マスクまたは、ホスト名 mask ネットマスク。ホスト名は、hosts ファイ ルまたは DNS 中 (設定やライブラリに依存します) の有効なホスト名か、ドッ ト 付 き 数値形式です。ネットワーク指定として特別な記法はありませんが、 ネットワーク名は認識されます。フィルタルールを DNS に依存させると攻撃の 余地を導入してしまうので、勧められません。 ホスト名には特殊な any が許され、0.0.0.0/0 と認識されます (後述のマスク 書式参照)。これは全 IP アドレスにマッチします。 "any" だけがマスクを 暗 黙 的に指定しますので、他の状況では、ホスト名はマスクとともに指定する必 要があります。ホストとマスクに対して "any" を指定できるものの、この言語 においては、意味を持たなくなります。 数 値フォーマット "x/y" は、 1 のビットが MSB から開始して y 個連続する マスクの生成を示します。よって、y の値が 16 である場合に は、0xffff0000 に な ります。シンボリックな "x mask y" は、マスク y がドット付き IP 表 現、または 0x12345678 の形式の 16 進数であることを示します。ビットマ ス ク が示す IP アドレスの全ビットと、パケットのアドレスとが、厳密にマッチ する必要があります; 現在、マッチの意味を反転する方法はありま せ ん し、 ビッ トマスクにて容易に表現可能ではない IP アドレス範囲にマッチさせる方 法もありません (たとえるなら、ここまで実現すると、もはや朝食とは言え な いですね)。 送信元と送信先のどちらかまたは両者に port マッチを含む場合、 TCP と UDP のパケットに対してのみ適用されます。 proto マッチパラメータが無い場合、 ど ちらのプロトコルのパケットも比較されます。これは、"proto tcp/udp" と 等価です。 port の比較を行うときには、サービス名および数値のポート番 号 の どちらでも使用できます。ポートの比較を行う際、数値形式を比較演算子と ともに使用したり、ポート範囲を指定したりできます。ポートが from オ ブ ジェ クトの一部として登場する場合、送信元ポート番号にマッチします。ポー トが to オブジェクトの一部として登場する場合、送信先ポート番号にマッ チ します。更なる情報は使用例を参照してください。 all キーワードは、本質的に、他のマッチパラメータを伴わない "from any to any" の同義語です。 送信元および送信先のマッチパラメータの後に、次の追加のパラメータを使 用 可能です: |
with |
ある種のパケットのみが持つ特殊な属性にマッチする場合に使 用します。一般に、IP オプションが存在する場合にマッチさせ る に は、with ipopts を使用します。完全なヘッダを格納するには短かす ぎるパケットにマッチさせるには、 with short を使用します。断 片 化 さ れ たパケットにマッチさせるためには、with frag を使用しま す。更に、IP オプション固有のフィルタリングに関しては、各 オ プ ションを列挙可能です。 |
with キーワードの後にパラメータを続ける前に、語 not または no を 挿入し、オプションが存在しない場合にのみフィルタルールがマッチす るようにできます。 with 節を連続して記述することが許されます。また、キーワード and を、with の代りに使用することができます。これは、純粋に可読性 向 上 のためです ("with ... and ...")。複数の節を列挙したとき、すべ てがマッチするときに、ルールがマッチします。 |
flags |
TCP フィルタリングにおいてのみ有効です。使用可能なレター は、TCP ヘッダにて設定可能なフラグの 1 つを表現します。関連は次 の通りです: |
F - FIN S - SYN R - RST P - PUSH A - ACK U - URG |
様々なフラグシンボルを組み合わせて使用できますので、 "SA" は パ ケット中の SYN-ACK の組み合わせを表現します。 "SFR" などの組み合 わせの指定を制限するものはありません。この組み合わせは、規 則 を 守っ ている TCP 実装では通常生成されません。しかしながら、異常を 避けるために、どのフラグに対してフィルタリングしているのかを示す 必 要があります。このために、どの TCP フラグを比較するのか (すな わち、どのフラグを重要と考えるか) を示すマスクを指定できます。こ れは、マッチ対象の TCP フラグ集合の後に、"/<flags>" を付けること で実現できます。例えば: |
... flags S |
||||
# "flags S/AUPRFS" になり、SYN フラグ「のみ」 |
||||
# が設定されているパケットにマッチします。 |
||||
... flags SA |
||||
# "flags SA/AUPRFSC" になり、SYN および ACK のフラグ |
||||
# のみが設定されているパケットにマッチします。 |
||||
... flags S/SA |
||||
# SYN-ACK の組のうち、SYN フラグのみが設定されている |
||||
# パケットにのみマッチします。これは共通の「確立」 |
||||
# キーワード動作です。"S/SA" は SYN と ACK の組の |
||||
# 「両方」が設定されているものにはマッチ「しません」 |
||||
# が、"SFP" にはマッチ「します」。 |
icmp-type |
proto icmp とともに使用した場合にのみ有効であり、 flags とと も に 使用しては「なりません」。多くのタイプがあり、この言語で認識 される短縮形や、これに関連付けられた数値で指定できます。セ キュ リティの観点からみて最も重要なものは ICMP リダイレクトです。 |
フィルタルールに設定可能な、最後から 2 番目のパラメータは、パケットの履 歴情報を記録するか否か、およびどのような履歴を保存するかです。以下の 情 報を保存できます: |
state |
通信セッションのフロー情報を保存します。 TCP, UDP, ICMP の各パケットに関して状態が保存されます。 |
||
frags |
断片化されたパケットの情報を保存します。この情報は、後に 断片化する際に使用します。 |
これらにマッチするパケットは素通しし、アクセス制御リストを通しません。 |
パ ラメータの最後の組はフィルタルールの「グルーピング」を制御します。他 のグループが指定されない限り、デフォルトでは、全フィルタルールはグ ルー プ 0 に置かれます。非デフォルトのグループにルールを追加するには、グルー プの「頭 (head)」を作成するところから、グループを開始します。パケットが グ ループの「頭」のルールにマッチする場合、フィルタ処理はそのグループに 切り替わり、そのルールをそのグループのデフォルトとして 使 用 し ま す。 quick を head ルールとともに使用する場合、そのグループの処理から戻るま では、ルール処理は停止しません。 あるルールは、新規グループの頭でありかつ、非デフォルトグループのメン バ で あ る ことが可能です (head と group を同一ルール内で同時に使用可能で す)。 |
head <n> |
新規グループ (番号 n) を作成することを示します。 |
group <n> |
このルールを、グループ 0 ではなく、グループ (番号 n) に置くこと を示します。 |
log アクションまたはオプションにて、パケットのログを行うとき、パケット のヘッダが ipl パケットロギング擬似デバイスに書き込まれます。 log キー ワードの直後に、次の修飾語句を (この順序で) 使用できます: |
body |
パケットの内容の最初の 128 バイトを、ヘッダの後でログする ことを示します。 |
||
first |
ログが "keep" オプションと共に使用される場合、本オプショ ン も指定することを勧めます。これにより、トリガとなるパケットの みをログして、この後に状態情報にマッチする全パケットをログし な いようになります。 |
or-block |
な んらかの理由でフィルタがログを取れない場合 (ログ読み取りが非 常に遅い場合など)、このパケットに対するこのルールのアクションが block であったと解釈させます。 |
level <loglevel> |
こ のパケットの情報ログに、どのログファシリティと優先度を使用す るか、またはデフォルトファシリティでどの優先度を使用するかを 指 定します。情報ログには、ipmon の -s オプションを使用します。 |
こ のデバイスに書き込まれるレコードのフォーマットについては ipl(4) を参 照してください。このログを読み取って整形するには、ipmon(8) を使用 し ま す。 |
quick オプションは次のようなルールに対して都合が良いです: block in quick from any to any with ipopts これは、標準的な長さではないヘッダを持つ (IP オプションを持つ) パケット にマッチし、この先のルール処理を行わずに、マッチが発生したこととパ ケッ トをブロックすべきことを記録します。 次のような「継続」ルールの解釈により: block in from any to any port < 6000 pass in from any to any port >= 6000 block in from any to any port > 6003 範囲 6000-6003 が許され、他は許さないように設定できます。最初のルールの 効果よりも、後続ルールが優先することに注意してください。同じこ と を 行 う、他の (容易な) 方法は次の通りです: block in from any to any port 6000 <> 6003 pass in from any to any port 5999 >< 6004 効果を持たせるためには、 "block" および "pass" の両方をここに書く必要が あります。なぜなら、"block" アクションにマッチしないことが通過を意味 す る わ け ではなく、ルールが効果を持たないことを意味するだけだからです。 ポートが1024未満のものを許すには、次のようなルールを使用します: pass in quick from any to any port < 1024 これは、最初のブロックの前に置く必要があります。 le0/le1/lo0 からのすべ て の内向きパケットを処理し、デフォルトでは内向きの全パケットをブロック する新規グループを作成するには、次のようにします: block in all block in quick on le0 all head 100 block in quick on le1 all head 200 block in quick on lo0 all head 300 そして、le0 で ICMP パケットのみを許すには、次のようにします: pass in proto icmp all group 100 le0 からの内向きパケットのみがグループ 100 で処理されますので、イ ン タ フェー ス名を再度指定する必要がないことに注意してください。同様に、次の ように TCP などの処理を分解できます: block in proto tcp all head 110 group 100 pass in from any to any port = 23 group 110 最終行を、グループを使用せずに記述すると、次のようになります: pass in on le0 proto tcp from any to any port = telnet "port = telnet" と記述したい場合には、"proto tcp" を指定する必要があ る こ と に 注意してください。なぜなら、パーザは自己に基づいてルールを解釈 し、指定されたプロトコルによって全サービス/ポート名を修飾するからです。 |
/dev/ipauth |
ipftest(1), iptest(1), mkfilters(1), ipf(4), ipnat(5), ipf(8), ipfstat(8) |