PF 規則の構文は一見、IPF の構文に似ています。
action match-parameter optional-action-1 optional-action-2 ...
ただし、同一の構文の結果が非常に異なる場合があります。IPF 規則は、容易に PF 規則に変換されません。たとえば、次の規則セットは PF と IPF で有効です。ただし、IPF ではクライアント 192.168.1.2 が Secure Shell を使用して 172.16.1.2 に接続できるのに対して、PF ではできません。この解釈の違いは、状態の一致での PF と IPF の違いで説明されています。
block in from 172.16.1.2 to 192.168.1.2 block in from 192.168.1.2 to 172.16.1.2 pass in proto tcp from 192.168.1.2 to 172.16.1.2 port = 22 keep state
PF での規則は、アクション、一致パラメータ、およびオプションのアクションを使用して、パケットを処理し、そのパケットが受け入れられるか、または破棄されるかを判定します。パケットが規則に一致した場合、PF はそのパケットにアクションを適用します。規則は、次の要素を順番に使用して記述します。
その規則をアクションで開始します。リストについては、パケットフィルタ規則のアクションを参照してください。
必要なパラメータを一致させます。リストについては、パケットフィルタ規則の一致パラメータを参照してください。
必要なオプションのアクションを含めます。リストについては、パケットフィルタ規則のオプションのアクションを参照してください。
PF 規則の詳細な文法と構文については、pf.conf(5) のマニュアルページを参照してください。IPF 規則と PF 規則の間でポリシーまたは構文が異なる規則の例については、IPF 規則と比較した PF 規則の例を参照してください。
各規則がアクションを開始します。パケットが規則に一致した場合、PF はそのパケットにアクションを適用します。次のリストには、パケットに適用される一般的に使用されているアクションが含まれています。また、そのアクションが IP フィルタ にもあったかどうかも示されています。
PF にのみあります。さまざまな PF ファイアウォールパラメータを構成します。たとえば、reassemble yes 引数は、IP フラグメントの再構築を有効にします。
set reassemble yes
PF にのみあります。一致するパケットにさらに適用されるべき新しい規則セットを開きます。
パケットはフィルタを通過できません。
## without an in, out, or on match parameter, ## blocks all traffic on all interfaces block all
パケットはフィルタを通過します。すべてのパケット (着信および送信) に適用されます。
pass all
パケットの block または pass 状態を変更することなく、きめ細かいフィルタリングを提供します。
match 規則は、最後に一致した規則についてだけでなく、パケットが規則に一致するたびにパラメータが設定されるという点で、block 規則や pass 規則とは異なります。これらのスティッキパラメータは、明示的にオーバーライドされるまで有効です。影響を受けるパラメータは、nat-to、binat-to、rdr-to、および scrub です。
このリスト内のキーワードは、パケットが規則に一致するかどうかを判定する条件を定義します。
規則がインバウンドパケットに一致した場合にのみ、その規則に適用されます。
pass in from any to any port = 22
規則がアウトバウンドパケットに一致した場合にのみ、その規則に適用されます。
pass out log on net0
指定されたインタフェースを出入りするパケットを一致させます。
set skip on lo0
規則が、指定された発信元 IP アドレスからのパケットに一致した場合にのみ、その規則に適用されます。次の例は、整形式の規則では in、out、または on を使用する必要がないことを示しています。この規則は、ホストのすべてのインタフェース上のすべてのインバウンドおよびアウトバウンドパケットに一致します。
pass from any to any
any キーワードは、すべての発信元からのパケットおよびすべての宛先へのパケットを受け入れるために使用されます。IP アドレスは、ポート番号で変更できます。次の規則の例は、ポート 22 に到着するすべてのインバウンドパケットに一致します。
pass in from any to any port = 22
設定されている TCP フラグに基づいて TCP パケットを一致させます。
この規則は、b のセットのうち a のセットのフラグが設定されている TCP パケットにのみ適用されます。b にないフラグは無視されます。
これらのフラグは、(F)IN、(S)YN、(R)ST、(P)USH、(A)CK、(U)RG、(E)CE、および C(W)R です。
次の例では、いくつかのサンプルのフラグ設定について説明します。
flags S/SA – ステートフル接続のデフォルト設定。
flags any – どのフラグもチェックされされません。
flags S/SS – SYN が設定されます。その他のフラグは無視されます。
SYN と ACK をともにパケットに一致させることはできません。SYN+PSH、SYN+RST、および SYN をパケットに一致させることができますが、SYN+ACK、ACK+RST、および ACK はできません。
flags /SFRA – a のセットが指定されていない場合は、デフォルトで「なし」になります。このフィルタを使用する前に、すべての a フラグを設定解除する必要があります。
さらに詳細な使用方法や、フラグ設定の影響については、pf.conf(5) のマニュアルページを参照してください。
ICMP タイプに基づいてパケットを一致させます。このキーワードは proto オプションが icmp に設定されているときに使用され、flags オプションが指定されているときは使用されません。
特定のプロトコルに対して一致を取ります。/etc/protocols ファイルに指定されている任意のプロトコル名を使用したり、そのプロトコルを表す 10 進数の数を指定したりできます。キーワード tcp/udp は、TCP または UDP パケットを一致させます。
16 進数または 10 進数の整数として表されたサービスタイプの値に基づいてパケットを一致させます。
生存期間の値を基に、パケットの一致を取ります。パケットに格納されている生存期間の値は、そのパケットが破棄される前に移動できるホップの数を示します。
実効グループ ID で着信パケットを一致させます。
実効ユーザー ID で着信パケットを一致させます。
このリスト内のキーワードは、追加のオプションのアクションを定義します。
pass 規則に対して指定されると、パケットに IP オプションまたはルーティング拡張ヘッダーが含まれている場合でも、最後に一致した規則に基づいてそのパケットのフィルタの通過を許可します。allow-opts が指定されていない場合、PF は、IP オプションを含む IPv4 パケットおよびルーティング拡張ヘッダーを含む IPv6 パケットをブロックします。
keep state の省略形。特定の規則に一致するパケットのために保持される情報を決定します。PF での pass 規則はデフォルトで状態を作成するため、keep オプションは、保持される状態のためのオプション (sloppy や if-bound など) をさらに指定するために役立ちます。
パケットが特定のインタフェース上を移動したときに IP アドレスを変更するように指定します。この手法により、変換しているホスト上の 1 つまたは複数の IP アドレスで、内部ネットワーク上のより大きな範囲のシステムのネットワークトラフィックをサポートできます。内部ネットワークのアドレスは、RFC 1918: プライベートインターネットのためのアドレス割り当てで定義されているアドレス範囲に準拠しているべきです。
パケットを別の宛先の、異なっている可能性のあるポートにリダイレクトします。rdr-to は、1 つのポートだけでなくポート範囲を指定できます。
一致するパケットをログに記録します。log が match アクションで使用されていると、状態が保持されない場合でも、match でパケットがただちにログに記録されます。一致する match 規則が複数ある場合は、パケットが複数回ログに記録されます。
パケットが規則に一致する場合は、quick オプションを含む規則を実行します。これ以上の規則チェックは行われません。
一致するパケットを指定されたインタフェース上のアウトバウンドキューに移動します。さらに、route-to は、指定されたインタフェースを経由して、各パケットを異なるインタフェースまたは異なる次のホップに送信できます。ポリシーベースのルーティング (PBR) を実装します。
route-to は、次の引数を受け入れます。(インタフェース名 + 次のホップアドレス) のペアには 2 つの構文バリアントがあります。
interface-name
(interface-name next-hop-address) または next-hop-address@interface-name
{ (interface1-name next-hop1-address), (interface2-name next-hop2-address) [, ...] } または { next-hop1-address@interface1-name, next-hop2-address@interface2-name[, ...] }
複数のインタフェースを指定するときに使用するインタフェースを選択する方法については、http://www.openbsd.org/faq/pf/pools.html を参照してください。
PF には、PF 規則の読みやすさ、拡張性、および再利用性を向上させるためのマクロとテーブルが用意されています。マクロとテーブルは、リストを受け入れます。
マクロ – 1 つまたは複数の項目を 1 つの項目として処理されるように定義します。理解しやすい名前を指定します。たとえば、次の規則は、2 つの理解しやすいマクロを使用しています。
emailserver = 192.1.2.223 email = "{ smtp, pop3, imap }" ## mail services pass in from any to $emailserver port = $email
テーブル – 規則セット全体をリロードすることなく操作できる IP アドレスのリスト。高速な検索を促進します。
テーブルは、規則または規則のセットによって定義されます。あるテーブルを参照するすべての規則が削除された場合、そのテーブルは破棄されます。その規則が削除されても存続するテーブルを作成するには、persist キーワードを使用します。
たとえば、次の clients テーブルはクライアントのリストです。クライアントの範囲内の 1 つのアドレスは許可されません。
table <clients> persist { 192.168.2.0/24, !192.168.2.5 }
この例は、NAT 規則を構築する方法を示しています。この規則は、アウトバウンドパケット内の発信元アドレスを net2 インタフェースにバインドされたアドレスに変換します。これにより、192.168.1.0/24 の発信元アドレスを持つ net2 デバイスから発信されるパケットが書き換えられ、その発信元アドレスが外部に対して net2 として示されます。
## NAT rule that externally shows net2 as source address pass out on net2 from 192.168.1.0/24 to any nat-to (net2)使用例 3 PF でのスパム規則
この例は、PF でのテーブルの使用を示しています。管理者が、迷惑メールを送信する IP アドレスの spam テーブルを作成します。次のファイアウォール規則は、spam テーブル内のすべてのアドレスからの着信パケットをブロックします。
table <spam> { 192.168.1.0/24 } block in from <spam> to any
新しい迷惑メール発信元をブロックするために、管理者は、このテーブルのみを更新します。
# pfctl -t spam -T add 172.16.0.0/16
pfctl コマンドは、規則セットを変更することなくファイアウォール構成を更新します。カーネルで、このテーブルは次のように読み取られます。
table <spam> { 192.168.1.0/24 172.16.0.0/16 }
PF 規則の詳細な文法と構文については、pf.conf(5) のマニュアルページを参照してください。ipadm コマンドの引数については、ipadm(1M) のマニュアルページを参照してください。
PF と IPF では、デフォルトのフィルタリング動作は異なりますが、同様の構文を使用します。PF 構成ファイル内の変更されていない IPF 規則によって、間違ったセキュリティーポリシーが実装される可能性があります。次の例は、相違点のいくつかを示しています。IPF 規則と PF 規則の違いをテストする方法については、IPF 規則を PF 規則に変換するための方針を参照してください。
IPF とは異なり、PF は、デフォルトではループバックインタフェースにバインドされたパケットを処理します。pass all などの単純な規則であっても、PF が有効になっていると、ループバックトラフィックのパフォーマンスが大幅に低下する場合があります。次の 2 つの機能の衝突がパフォーマンス低下の原因です。
PF での pass 規則のデフォルトであるステートフルパケット検査
Oracle Solaris に固有の機能である TCP Fusion
TCP Fusion は、パケット処理を簡略化することによって、ループバックにバインドされた接続のスループットを向上させます。ただし、この簡略化により、状態の検証のために PF が使用する TCP シーケンスの番号付けが壊れます。TCP Fusion で処理されたパケットのシーケンス番号は無効であるため、PF はそのパケットを破棄します。TCP はこれらのパケットを再送信しますが、それらのパケットは引き続き状態の検証に失敗するため、スループットが低下します。
PF 規則でループバックポリシーを実装するには、次の点を明確にする必要があります。ポリシーでループバックパケットを処理しない場合は、ループバックパケットを処理するデフォルトをオーバーライドする必要があります。
## PF version - no filtering of packets on loopback interface set skip on lo0
ポリシーでループバックパケットを処理する場合は、2 つのオプションがあります。
ループバックインタフェースのパケットを処理する pass 規則の状態を保持しない。
## PF version - no state on loopback interface pass in on lo0 from any to any no state
ループバックインタフェースのパケットのステートフル検査を実行する場合は、TCP シーケンス番号を無視する。
## PF version - no TCP sequence number inspection on loopback interface pass in on lo0 from any to any keep state (sloppy)
PF と IPF は、異なる方法で特定のパケットを状態に一致させます。192.168.1.0/24 および 172.16.0.0/16 ネットワーク間でトラフィックを転送するルーター上の次の規則セットを考えてみます。
## Valid rule set in IPF and PF block in from 192.168.1.0/24 to any block in from 172.16.0.0/16 to any pass in from 192.168.1.2 to 172.16.1.2 keep state
これらの規則は両方のファイアウォールに対して有効ですが、これらは異なるポリシーを実装します。
IPF では、192.168.1.2 クライアントは 172.16.1.2 サーバーに到達でき、サーバーの応答パケットはこのクライアントに到達できます。
block 規則は、192.168.1.0/24 および 172.16.0.0/16 ネットワーク間のすべてのトラフィックを阻止します。
pass 規則は、192.168.1.2 クライアントが 172.16.1.2 サーバーに接続することを許可します。
pass 規則内の keep state アクションは、サーバーの応答がこのクライアントに到達することを許可します。
192.168.1.2 から送信された最初の要求パケットが pass 規則に一致するとすぐに、状態が作成されます: 192.168.1.2 -> 172.16.1.2。この状態はまた、サーバーからクライアントに返された逆方向のパケットにも一致します: 172.16.1.2 -> 192.168.1.2。
PF 規則の処理では、192.168.1.2 クライアントは 172.16.1.2 サーバーに接続できません。
PF での状態の検査はより厳格です。pass 規則の in 一致パラメータは、PF にインバウンドパケットのみを一致させるよう指示します。そのため、pass in 規則によって作成される状態は、次の 2 種類のパケットにのみ一致します。
クライアントからサーバーに送信されたインバウンド転送パケット: 192.168.1.2 -> 172.16.1.2
サーバーからクライアントに送信された逆方向のアウトバウンドパケット: 172.16.1.2 -> 192.168.1.2
サーバーから PF ファイアウォールに応答が到着したとき、PF はそのパケットを逆方向のパケットではなく、はじめてのインバウンドパケットとして認識するため、このパケットは pass in 規則によって作成される状態に一致しません。規則の処理は、引き続きそのパケットに一致する規則を探して、そのパケットを転送するか、または破棄するかを判定します。このパケットは 2 番目の block 規則である block in from 172.16.0.0/16 to any に一致するため、PF はサーバーから送信された応答を破棄します。
PF で、IPF の場合と同様にルーティングされるトラフィックに対しては、次の 2 つの規則の構文が考えられます。
転送アウトバウンドパケットに関する状態を作成する規則を追加します。この状態により、サーバーからの逆方向のインバウンドパケットを有効にできます。
## PF rule set1 enforces IPF rule set policy block in from 192.168.1.0/24 to any block in from 172.16.0.0/16 to any pass in from 192.168.1.2 to 172.16.1.2 keep state pass out from 192.168.1.2 to 172.16.1.2 keep state
pass 規則は、次の 2 つの状態を作成します。
192.168.1.2 -> 172.16.1.2 @ in 192.168.1.2 -> 172.16.1.2 @ out
これらの状態は、サーバーからの逆方向のインバウンドパケットを許可します。
in: 172.16.1.2 -> 192.168.1.2
パケットの方向を使用しない、より単純な規則セットを記述します。
## PF rule set2 enforces IPF rule set policy block in from 192.168.1.0/24 to any block in from 172.16.0.0/16 to any pass from 192.168.1.2 to 172.16.1.2 keep state
in パラメータのない pass 規則は、方向には関係なく、クライアントから送信されたパケットに一致します。そのため、192.168.1.2 からのパケットをはじめてのインバウンドパケットとしてインターセプトしたとき、PF は状態を作成します。
192.168.1.2 -> 172.16.1.2 @ in
そのパケットは、ファイアウォールによってルーティングされたあと、PF によって再度、今回はアウトバウンドパケットとしてインターセプトされます。そのパケットが pass 規則に一致すると、PF は 2 番目の状態を作成します。
192.168.1.2 -> 172.16.1.2 @ out
PF の OpenBSD バージョンが RFC 6146 で説明されている NAT-64 をサポートしているのに対して、PF の Oracle Solaris バージョンは、RFC 2663 で説明されている従来の NAT のみをサポートしています。
NAT は通常、プライベートアドレスの範囲を持つネットワークとインターネットの間にマッピングを設定します。NAT を使用すると、プライベートネットワーク内のホストはインターネット上の任意のホストと通信できます。標準的な配備では、このマッピングは 1 対多です。つまり、プライベートネットワーク内の多くのホストが、インターネットサーバーに接続するための 1 つのパブリック IP アドレスを共有します。
PF での NAT 処理は、オプションの規則アクションです。PF での NAT 規則は実質的に、ファイアウォールにアクションタイプ (rdr-to または nat-to) および一致するパケットの方向 (インバウンドまたはアウトバウンド) に応じて IP アドレスを変更するよう指示する状態を作成します。
PF では、nat-to および rdr-to アクションは、パケットが nat-to または rdr-to のオプションのアクションを含む規則に一致するとすぐに実行されます。以降の規則には、すでに変換されたパケットが表示されます。また、どちらのアクションでも、一致するパケットに関する状態が作成されます。
nat-to – 通常、アウトバウンドパケットに使用されます。プライベートネットワーク内のネットワーククライアントがインターネットサーバーと通信できるようにします。nat-to は、規則内の追加のパラメータに従って、一致するパケット内の発信元アドレスとポートを上書きするようファイアウォールに指示します。
たとえば、次の規則は、パケット内の 192.168.1.0/24 のアドレス範囲にあるプライベート発信元アドレスを、net0 インタフェースにバインドされたパブリック IP アドレスに変更します。
pass out on net0 from 192.168.1.0/24 to any nat-to (net0)
rdr-to – 通常、インバウンドパケットに使用されます。rdr-to のオプションのアクションは、インターネット上のクライアントが、プライベート IP アドレスを持つネットワーク内の PF ファイアウォールの背後にあるサーバーと通信できるようにするという点で、nat-to の反対です。rdr-to は、一致するパケット内の宛先アドレスを変更します。
たとえば、次の規則は、インバウンド SMTP トラフィックを、ファイアウォールの背後にあるプライベートネットワーク上の SMTP サーバーの IP アドレスである 172.16.1.2:2525 にリダイレクトします。この規則は、net0 にバインドされたアドレスと同じ宛先 IP アドレスを持ち、かつ宛先ポートが 25 である、net0 インタフェースに到着するすべての TCP インバウンドパケットに一致します。rdr-to アクションは、172.16.1.2:2525 を持つパケット内の宛先アドレスとポートを上書きします。
pass in on net0 inet proto tcp from any to (net0) port = 25 rdr-to 172.16.1.2 port 2525
rdr-to または nat-to アクションからの変更は、影響を受けるパケットが状態を作成する pass または block 規則に一致していないかぎり、以降の規則にただちに表示されます。その場合、PF を離れるパケットは、rdr-to または nat-to オプションには影響されません。log アクションは、引き続きそのパケットをログに記録します。
## Block packets going to 192.168.2.2 match out to 192.168.2.2 nat-to 192.168.2.1 block from 192.168.2.1
pass または block 規則を必要とする match 規則のすべてのパラメータは、状態を作成します。時には、pass 規則は、match と pass 規則を合わせたものと同等になる場合があります。たとえば、次の PF 規則セットは同等です。
webserver = "192.168.2.7" webports = "{ http, https }" emailserver = "192.168.2.5" email = "{ smtp, pop3, imap }" ### Rule set 1 - match action then pass action match in on $ext_if proto tcp to $ext_if port $webports rdr-to $webserver match in on $ext_if proto tcp to $ext_if port $email rdr-to $emailserver pass proto tcp from any to $webserver port $webports pass proto tcp from any to $emailserver port $email pass proto tcp from $emailserver to any port smtp ### Rule set 2 - no match action, only pass action pass in on $ext_if inet proto tcp to $ext_if port $webports rdr-to $webserver pass in on $ext_if inet proto tcp to $ext_if port $email rdr-to $mailserver pass on $int_if inet proto tcp to $webserver port $webports pass on $int_if inet proto tcp to $mailserver port $email