[OpenBSD]

[前に戻る: アンカーと名前付き (サブ) ルールセット] [目次] [次に進む: アドレスプールと負荷分散 (Load Balancing)]

PF: パケットキューイングと優先順位付け


目次


キューイング

何かをキューに入れるということは、それが処理を待つ間、順序に従って、 それを蓄積するということです。コンピュータネットワークでは、データパケットが ホストから送出される際、それらはオペレーティングシステムによって処理されるのを待つ間、 キューに入れられます。そして、オペレーティングシステムは、どのキューに入れられている、 どのパケットを処理すべきであるのかを決定します。オペレーティングシステムが選択した、 処理すべきパケットの順序は、ネットワークの性能に影響を与えます。 たとえば、SSH と FTP という、ふたつのネットワークアプリケーションを実行する ユーザのことを想像してみてください。理想的には、時間に敏感な SSH の性質のため、 SSH のパケットは FTP のパケットより先に処理されるべきでしょう。 たとえば、SSH クライアントで鍵がタイプされた場合には、直ちに反応することが 期待されますが、数秒の余計な遅延を発生させる FTP 転送が、何らかのメッセージの 原因となることはほとんどありません。しかし、このような接続のハンドリングを行うルータが、 SSH 接続の処理の前に FTP 接続からの大量のパケットの塊を処理する場合、 どのようなことが起きるでしょうか ? SSH 接続のパケットはキューに取り残されるので (あるいは、ルータがすべてのパケットを保持するのに十分大きなキューがない場合には、 このようなパケットは廃棄されてしまうかも知れません)、 SSH の接続は遅延し、動きが悪くなったように見えるかも知れません。そこで、 使用されているキューイングの戦略を変更することによって、異なるアプリケーション、ユーザ、 そしてコンピュータの間で、ネットワークの帯域幅を適正に共有することができるようになります。

キューイングは、送出方向のパケットに対してのみ役に立つということに 注意してください。いったん、着信方向のパケットがインターフェイスに到着した時点で、 このパケットのキューイングするのはもう既に遅過ぎるのです。なぜなら、このパケットは、 これを受信するインターフェイスに到着するまでに、既にネットワーク帯域を 消費してしまっているからなのです。これに対する解決策は、近隣のルータの キューイングを有効化するか、パケットをルータに送出する内部インターフェイスの キューイングを有効化することだけです。

スケジューラ

スケジューラは、処理すべきキューとその中の順序を決定します。 デフォルトでは、OpenBSD は FIFO (First In First Out) スケジューラを使用します。 FIFO キューは、スーパーマーケットや銀行における人の行列と同じように動きます。 つまり、キューに入れられた最初の要素は最初に処理されることになります。新しい パケットが到着すると、それはキューの最後に追加されます。もし、キューが一杯になると、 新しく到着したパケットは廃棄されます。これはテイルドロップとして知られています。

OpenBSD では FIFO 以外に以下のふたつのスケジューラをサポートしています。

CBQ (Class Based Queueing)

CBQ (Class Based Queueing) は、複数のキューやクラスの間で、ネットワーク 接続の帯域幅の分割を行うキューイングアルゴリズムです。それぞれのキューは、 送信元あるいは送信先のアドレスやポート番号、プロトコルなどに基づいて 割り当てられるトラフィックを持っています。ひとつのキューは、オプションとして 親キューの使用率が低い場合に、親キューから帯域幅を借りるよう構成されている かも知れません。キューはまた、SSH のような会話的なトラフィックを含む場合に、 FTP のような巨大なトラフィックを含むキューに先立ってそのパケットが処理される 優先権を与えられているかも知れません。

CBQ のキューは階層的な方法で配置されます。階層の最上位には、 利用可能な帯域幅の総量を定義するルート (root) キューが 位置しています。子キューがルートキューの下に生成され、その それぞれに、ルートキューの帯域幅の一部が割り当てられています。 たとえば、キューが以下のように定義されているとしましょう。

ルートキュー (2Mbps)
キュー A (1Mbps)
キュー B (500Kbps)
キュー C (500Kbps)

この場合、利用可能な総帯域幅は 2Mbps に設定されています。 そして、この帯域幅は 3 個の子キューの間で分割されています。

この階層は、キューの中にキューを定義することで、さらに拡張することができます。 異なるユーザの間で帯域幅を均等に分割し、そして、あるプロトコルが他のトラフィックの 帯域幅を枯渇させることがないように彼らのトラフィックをクラス化することで、 たとえば、以下のようなキューイング構造を定義することができます。

ルートキュー (2Mbps)
ユーザ A (1Mbps)
ssh (50Kbps)
バルク (950Kbps)
ユーザ B (1Mbps)
オーディオ (250Kbps)
バルク (750Kbps)
http (100Kbps)
その他 (650Kbps)

それぞれのキューに割り当てられた帯域幅の合計が、親キューに 割り当てられた帯域幅以上にはならないことに注意してください。

他の子キューに利用されていない利用可能な帯域幅を、親キューが過剰に 持っている場合に、その親キューから帯域幅を借りるようにキューの設定を 行うことができます。たとえば、以下のようなキューの構成を考えてみます。

ルートキュー (2Mbps)
ユーザ A (1Mbps)
ssh (100Kbps)
ftp (900Kbps、借用)
ユーザ B (1Mbps)

ここで、ftp 用のキューのトラフィックが 900Kbps を超え、ユーザ A のキューのトラフィックが (ssh は、それ用のキューに割り当てられた 100Kbps 未満の帯域しか使用していないので) 1Mbps 未満なら、ftp 用のキューは超過した帯域幅をユーザ A から借用することができます。 このように、ftp 用のキューは、それが過負荷に直面した場合に、 それ用に割り当てられた帯域幅以上を使用することができるのです。もし、ssh の負荷が増加した場合には、借用した帯域幅は返却されることになります。

CBQ はそれぞれのキューに優先度を割り当てます。より高い優先度を持つキューは、 より低い優先度を持つキューと同じ親を共有する限りにおいて (換言すれば、 両方のキューが階層構造の中の同じ枝に位置している限りにおいては)、 輻輳の際により低い優先度を持つキューに優先します。また、同一の優先度を持つ キューは、ラウンドロビン方式で処理されて行きます。たとえば、以下において、

ルートキュー (2Mbps)
ユーザ A (1Mbps、優先度 1)
ssh (100Kbps、優先度 5)
ftp (900Kbps、優先度 3)
ユーザ B (1Mbps、優先度 1)

CBQ は、ユーザ Aユーザ B 用のキューをラウンドロビン方式で 処理します。つまり、どちらのキューも他方に優先することはありません。 ユーザ A 用のキューが処理されている間、CBQ はその子キューの処理も行います。この場合、ssh 用のキューはより高い優先度を持ち、ネットワークが輻輳している場合に、 ftp 用のキューより優先的な待遇が与えられることになります。 ユーザ A 用とユーザ B 用のキューと比較して、ssh 用と ftp 用のキューは、どのような優先度も持っていないことに注意してください。 なぜなら、これらは、階層構造の中ですべてが同じ枝に位置しているわけではないからです。

より詳細な CBQ 関連の理論を知りたい場合には、 CBQ に関するリファレンスを参照してください。

PRIQ (Priority Queueing)

PRIQ (Priority Queueing) は、それぞれのキューに固有の優先度が与えられた 複数のキューを、ネットワークインターフェイスに割り当てます。 より高い優先度を持つキューは、常により低い優先度のキューより先に 処理が行われます。

PRIQ のキューイング構造は均一です。つまり、キューの中に キューを定義することはできません。利用可能な帯域幅の 総量を設定したルートキューが定義され、その下にサブキューが 定義されます。以下の例について考えてみましょう。

ルートキュー (2Mbps)
キュー A (優先度 1)
キュー B (優先度 2)
キュー C (優先度 3)

ルートキューは、2Mbps の利用可能な帯域幅を持つものとして定義され、 その下に 3 個のサブキューが定義されています。最も高い優先度のキュー (優先順位の番号が最高のもの) は最初に処理されます。いったん、キューの 中のすべてのパケットが処理されるか、あるいはキューが空になると、PRIQ は次に高い優先度を持つキューに処理を移します。与えられたキューの中では、 パケットは FIFO (First In First Out) 方式で処理が行われます。

PRIQ を使用する場合、キューイングの計画を非常に慎重に行わなければならないことに 注意することが非常に重要です。これは、PRIQ が、常により高い優先度のキューを より低い優先度のものより先に処理するからであり、より高い優先度のキューが定常的な ストリームのパケットを受信している場合には、このより高い優先度のキューが、より低い 優先度のキューを遅延させたり、あるいはパケットが廃棄される原因になったりすることが あるからなのです。

RED (Random Early Detection)

RED (Random Early Detection) は輻輳回避アルゴリズムです。その仕事は、 キューが一杯にならないことを確実にすることで、ネットワークの輻輳を 回避することです。これは、キューの平均的な長さ (サイズ) を連続的に計算し、 それをふたつの閾値、つまり下限の閾値および上限の閾値と比較することによって 行われます。もし、平均的なキューのサイズが下限の閾値を下回っている場合には、 パケットが廃棄されるようなことはまったくありません。しかし、平均値が上限の 閾値を上回っているような場合には、新しく着信するすべてのパケットが 廃棄されてしまいます。もし、平均値がこれらふたつの閾値の間の値であれば、 平均的なキューのサイズから計算された確率に基づいて、パケットは廃棄される ことになります。これは換言すれば、平均的なキューのサイズが上限の閾値に 近付けば近付くほどパケットはより多く廃棄されることになるということです。 パケットを廃棄する場合には、RED はパケットを廃棄する接続をランダムに選択します。 これは、より大きな帯域幅の総量を使用している接続ほど、パケットが廃棄される 確率がより高いということになります。

RED は、global synchronization 問題として知られる状況を回避することができますし、 また、爆発的なトラフィックに対応することもできますので、非常に役に立つものです。 global synchronization は、いくつかの接続から同時にパケットを廃棄してしまうため、 全体的なスループットの低下を招いてしまうものでず。たとえば、10 個の FTP 接続を 中継するルータで輻輳が発生し、(FIFO キューイングの場合のように) すべての (あるいはほとんどの) これらの接続が廃棄された場合には、全体的なスループットが 著しく低下してしまうことになります。 もちろん、これは、すべての FTP 接続がそのスループットを低下させてしまうことに なりますし、また、ネットワークはもはやその能力を十分に活用できない状態になって しまいますので、とても理想的な状態であるとは言えなくなってしまいます。 RED は、すべての接続を選択する代わりに、パケットを廃棄する接続をランダムに 選択することによって、このような状況を回避します。より大きな帯域幅の総量を 使用している接続は、そのパケットを廃棄される可能性がより高くなります。 このようにして、大きな帯域幅を消費する接続が減速されることで輻輳が回避され、 全体的なスループットの著しい低下は発生しなくなるのです。さらに、RED は、 キューが一杯になる前にパケットの廃棄を開始するため、爆発的な トラフィックにも対応することができます。爆発的なトラフィックがやって来た場合にも、 キューには新しいパケットを受信するのに十分なスペースが残されているはずです。

RED は、ネットワークからの輻輳通知に対して、トランスポートプロトコルが応答できる 場合にのみ使用することができます。ほとんどの場合において、これは UDP や ICMP のトラフィックではなく、TCP トラフィックをキューイングする場合に RED を使用すべきであるということを意味します。

より詳細な RED 関連の理論を知りたい場合には、 RED に関するリファレンスを参照してください。

明示的輻輳通知

明示的輻輳通知 (ECN: Explicit Congestion Notification) は、通信経路が 輻輳状態にあるネットワーク上で通信中の 2 台のホストにそれを通知するため、RED とともに動作します。これは、パケットを廃棄するのではなく、パケットヘッダ中の フラグをセットするために RED を有効化することによって行われます。送信中の ホストが ECN をサポートしていると仮定した場合、そのホストがこのフラグを読み、 そのネットワークトラフィックをそれに従って減速することで行われます。

ECN についてのより詳しい情報は、 RFC 3168 を参照してください。

キューイングの設定

OpenBSD 3.0 から ALTQ (Alternate Queueing) のキューイングの実装が基本システムの一部として 組み込まれました。また、OpenBSD 3.3 からは、ALTQ は PF に統合されました。OpenBSD の ALTQ の実装は、CBQ (Class Based Queueing) と PRIQ (Priority Queueing) スケジューラを サポートしています。また、OpenBSD の ALTQ は、RED (Random Early Detection) と 明示的輻輳通知 (ECN: Explicit Congestion Notification) もサポートしています。

ALTQ は PF にマージされたので、キューイングを動作させるためには PF を 有効化しなければなりません。PF をどのようにして有効化させるのかに関しては、 はじめに を参照してください。

キューイングは、 pf.conf で設定されます。キューイングの設定には、以下のような ふたつのタイプのディレクティブが使用されます。

altq on ディレクティブのシンタクスは以下のとおりとなっています。

altq on interface scheduler bandwidth bw qlimit qlim \
   tbrsize size queue { queue_list }

たとえば、

altq on fxp0 cbq bandwidth 2Mb queue { std, ssh, ftp }
の場合は、インターフェイス fxp0 上で CBQ を有効化しています。また、利用可能な全帯域幅は 2Mbps に設定されています。そして、stdssh および ftp という 3 個の子キューが定義されています。

queue ディレクティブのシンタクスは以下のとおりとなっています。

queue name [on interface] bandwidth bw [priority pri] [qlimit qlim] \
   scheduler ( sched_options ) { queue_list }

上記の例の続きを以下に示します。

queue std bandwidth 50% cbq(default)
queue ssh { ssh_login, ssh_bulk }
  queue ssh_login priority 4 cbq(ecn)
  queue ssh_bulk cbq(ecn)
queue ftp bandwidth 500Kb priority 3 cbq(borrow red)

ここでは、以前に定義された子キューのパラメータを設定しています。 std キューは、ルートキューの帯域幅 (または 1Mbps) の 50% の帯域幅が割り当てられ、デフォルトキューとして設定されています。 ssh キューには、ssh_loginssh_bulk という、ふたつの子キューが定義されています。ssh_login には ssh_bulk よりも高い優先度が与えられており、どちらも ECN が有効化されています。また、ftp キューには 500Kbps の帯域幅が割り当てられ、優先度 3 が与えられています。そしてこれは、 余力がある場合には帯域幅の借用も可能となっていて、RED も有効化されています。

キューへのトラフィックの割り当て

キューにトラフィックを割り当てるためには、PF の フィルタルール とともに queue キーワードを使用します。たとえば、 以下のような行を含むフィルタルールの設定を考えてみましょう。

pass out on fxp0 from any to any port 22

パケットは、queue キーワードを使用して、 特定のキューに割り当てられたルールにマッチします。

pass out on fxp0 from any to any port 22 queue ssh

queue キーワードが block ディレクティブとともに使用された場合、 その結果として、TCP RST や ICMP Unreachable パケットが指定されたキューに 割り当てられます。

altq on ディレクティブで定義されたインターフェイス以外の、 インターフェイス上でキューの指定が行われる可能性があることに注意してください。

altq on fxp0 cbq bandwidth 2Mb queue { std, ftp }
queue std cbq(default)
queue ftp bandwidth 1.5Mb

pass in on dc0 from any to any port 21 queue ftp

キューイングは fxp0 上で有効化されていますが、タグ付けは dc0 上で行われます。もし、インターフェイス fxp0 から出てきた、pass ルールにパケットがマッチする場合、これらのパケットは、ftp キューにキューイングされるはずです。この方式のキューイングは、 ルータに取っては非常に役に立つものです。

通常は、ひとつのキュー名だけが queue キーワードに与えられますが、 もし、ふたつ目の名前が指定されている場合には、そのキューは、低遅延のための ToS (Type of Service) パケットか、データのペイロードのない TCP ACK パケットのために使用されます。 この良い例が、SSH を使用している場合になります。SSH のログインセッションは、 低遅延のために ToS を設定していますが、SCP や SFTP のセッションには これが設定されていません。PF は、非ログイン接続以外の異なるキューの中のログイン 接続に属するパケットをキューイングするために、この情報を使用することができます。 これは、ファイル転送のパケットよりログイン接続のパケットを優先させるのに役立ちます。

pass out on fxp0 from any to any port 22 queue(ssh_bulk, ssh_login)

これは、SSH のログイン接続に属するパケットを ssh_login キューに割り当て、SCP や SFTP 接続に属するパケットを ssh_bulk キューに割り当てています。ssh_login キューは、 より高い優先度を持っているので、SSH ログイン接続のパケットは、 SCP や SFTP 接続に優先して処理されるようになります。

TCP ACK パケットをより高い優先度を持つキューに割り当てることは、たとえば ADSL 回線のように、アップロードとダウンロードの帯域幅が異なっているような、 非対称の接続において便利なものです。ADSL 回線では、アップロードのチャネルが 非常に混雑している場合にダウンロードが始まると、アップロードチャネルを通して TCP ACK パケットを送信しようとする際に、輻輳している中に それを送信しなければならないため、 ダウンロードも影響を受けることになってしまいます。 最良の結果を得るためにテストを行って、アップロードのキューの帯域幅を、 その能力より小さな値に設定すべきです。実際には、アップロードの最大値が 640Kb の ADSL 回線の場合ですと、ルートキューの帯域幅を 600Kb のような値に設定することで、より良い性能を得られるようになります。 そして試行錯誤を行うことで、最良の帯域幅の設定を得られるはずです。

以下のように、keep state が指定されたルールに対して queue キーワードを使用する場合、

pass in on fxp0 proto tcp from any to any port 22 flags S/SA \
   keep state queue ssh

PF は、状態を持つ接続にマッチした、fxp0 から出て行くパケットが、 最後に ssh キューに入るよう、その状態テーブルのエントリにキューを登録します。 queue キーワードが着信トラフィックをフィルタリングするルールに対して 使用されているにも関わらず、その目的が関係する送出トラフィックのためのキューを 指定するためであるということに注意してください。上記のルールは、 着信パケットをキューイングするためのものではないのです。

例 #1: 小規模事務所、家庭内ネットワーク

  
    [ Alice ]    [ Charlie ]
        |             |                              ADSL
     ---+-----+-------+------ dc0 [ OpenBSD ] fxp0 -------- ( Internet )
              |
           [ Bob ]

この例では、OpenBSD は 3 台のワークステーションが接続された、小規模な家庭内 ネットワークのインターネットゲートウェイとして使用されています。このゲートウェイは、 パケットフィルタリングと NAT の仕事を行っています。ADSL 回線を使用した インターネット接続は、下りが 2Mbps で上りが 640Kbps となっています。

このネットワークのキューイングのポリシーは以下のとおりです。

以下は、このネットワークポリシーに適合するルールセットです。上記のポリシーに 直接的に適用される pf.conf のディレクティブだけが存在していることに 注意してください。natrdrオプションなどは、 これには含まれていません。

# enable queueing on the external interface to control traffic going to
# the Internet. use the priq scheduler to control only priorities. set
# the bandwidth to 610Kbps to get the best performance out of the TCP
# ACK queue.

altq on fxp0 priq bandwidth 610Kb queue { std_out, ssh_im_out, dns_out, \
	tcp_ack_out }

# define the parameters for the child queues.
# std_out      - the standard queue. any filter rule below that does not
#                explicitly specify a queue will have its traffic added
#                to this queue.
# ssh_im_out   - interactive SSH and various instant message traffic.
# dns_out      - DNS queries.
# tcp_ack_out  - TCP ACK packets with no data payload.

queue std_out     priq(default)
queue ssh_im_out  priority 4 priq(red)
queue dns_out     priority 5
queue tcp_ack_out priority 6

# enable queueing on the internal interface to control traffic coming in
# from the Internet. use the cbq scheduler to control bandwidth. max
# bandwidth is 2Mbps.

altq on dc0 cbq bandwidth 2Mb queue { std_in, ssh_im_in, dns_in, bob_in }

# define the parameters for the child queues.
# std_in      - the standard queue. any filter rule below that does not
#               explicitly specify a queue will have its traffic added
#               to this queue.
# ssh_im_in   - interactive SSH and various instant message traffic.
# dns_in      - DNS replies.
# bob_in      - bandwidth reserved for Bob's workstation. allow him to
#               borrow.

queue std_in    cbq(default)
queue ssh_im_in priority 4
queue dns_in    priority 5
queue bob_in    bandwidth 80Kb cbq(borrow)


# ... in the filtering section of pf.conf ...

alice         = "192.168.0.2"
bob           = "192.168.0.3"
charlie       = "192.168.0.4"
local_net     = "192.168.0.0/24"
ssh_ports     = "{ 22 2022 }"
im_ports      = "{ 1863 5190 5222 }"

# filter rules for fxp0 inbound
block in on fxp0 all

# filter rules for fxp0 outbound
block out on fxp0 all
pass  out on fxp0 inet proto tcp from (fxp0) to any flags S/SA \
	keep state queue(std_out, tcp_ack_out)
pass  out on fxp0 inet proto { udp icmp } from (fxp0) to any keep state
pass  out on fxp0 inet proto { tcp udp } from (fxp0) to any port domain \
	keep state queue dns_out
pass  out on fxp0 inet proto tcp from (fxp0) to any port $ssh_ports \
	flags S/SA keep state queue(std_out, ssh_im_out)
pass  out on fxp0 inet proto tcp from (fxp0) to any port $im_ports \
	flags S/SA keep state queue(ssh_im_out, tcp_ack_out)

# filter rules for dc0 inbound
block in on dc0 all
pass  in on dc0 from $local_net

# filter rules for dc0 outbound
block out on dc0 all
pass  out on dc0 from any to $local_net
pass  out on dc0 proto { tcp udp } from any port domain to $local_net \
	queue dns_in
pass  out on dc0 proto tcp from any port $ssh_ports to $local_net \
	queue(std_in, ssh_im_in)
pass  out on dc0 proto tcp from any port $im_ports to $local_net \
	queue ssh_im_in
pass  out on dc0 from any to $bob queue bob_in

例 #2: 企業ネットワーク


  ( IT Dept )  [ Boss's PC ]
       |          |                                   T1
     --+----+-----+---------- dc0 [ OpenBSD ] fxp0 -------- ( Internet )
            |                         fxp1
         [ COMP1 ]    [ WWW ]         /
                         |           / 
                       --+----------' 

この例では、OpenBSD のホストを、企業ネットワークのファイアウォールとして稼働させています。 この会社では、その顧客が FTP で顧客の web サイトをアップロードするため、 この会社のネットワークの DMZ で WWW サーバを運用しています。IT 部門では、 自身のネットワークを基幹ネットワークに接続して使用しています。また、社長は、 電子メールや web サーフィンに使用するための PC を、自分の机に持っています。 インターネットへは、上下方向ともに 1.5Mbps の T1 回線を使用して接続しています。 その他のすべてのネットワークセグメントは、Fast Ethernet (100Mbps) を使用しています。

ネットワーク管理者は以下のようなポリシーを決定しました。

以下は、このネットワークポリシーに適合するルールセットです。上記のポリシーに 直接的に適用される pf.conf のディレクティブだけが存在していることに 注意してください。natrdrオプションなどは、 これには含まれていません。

# enable queueing on the external interface to queue packets going out
# to the Internet. use the cbq scheduler so that the bandwidth use of
# each queue can be controlled. the max outgoing bandwidth is 1.5Mbps.

altq on fxp0 cbq bandwidth 1.5Mb queue { std_ext, www_ext, boss_ext }

# define the parameters for the child queues.
# std_ext        - the standard queue. also the default queue for
#                  outgoing traffic on fxp0.
# www_ext        - container queue for WWW server queues. limit to
#                  500Kbps.
#   www_ext_http - http traffic from the WWW server
#   www_ext_misc - all non-http traffic from the WWW server
# boss_ext       - traffic coming from the boss's computer

queue std_ext        cbq(default)
queue www_ext        bandwidth 500Kb { www_ext_http, www_ext_misc }
  queue www_ext_http priority 3 cbq(red)
  queue www_ext_misc priority 1
queue boss_ext       priority 3

# enable queueing on the internal interface to control traffic coming
# from the Internet or the DMZ. use the cbq scheduler to control the
# bandwidth of each queue. bandwidth on this interface is set to the
# maximum. traffic coming from the DMZ will be able to use all of this
# bandwidth while traffic coming from the Internet will be limited to
# 1.0Mbps (because 0.5Mbps (500Kbps) is being allocated to fxp1).

altq on dc0 cbq bandwidth 100% queue { net_int, www_int }

# define the parameters for the child queues.
# net_int    - container queue for traffic from the Internet. bandwidth
#              is 1.0Mbps.
#   std_int  - the standard queue. also the default queue for outgoing
#              traffic on dc0.
#   it_int   - traffic to the IT Dept network.
#   boss_int - traffic to the boss's PC.
# www_int    - traffic from the WWW server in the DMZ.

queue net_int    bandwidth 1.0Mb { std_int, it_int, boss_int }
  queue std_int  cbq(default)
  queue it_int   bandwidth 500Kb cbq(borrow)
  queue boss_int priority 3
queue www_int    cbq(red)

# enable queueing on the DMZ interface to control traffic destined for
# the WWW server. cbq will be used on this interface since detailed
# control of bandwidth is necessary. bandwidth on this interface is set
# to the maximum. traffic from the internal network will be able to use
# all of this bandwidth while traffic from the Internet will be limited
# to 500Kbps.

altq on fxp1 cbq bandwidth 100% queue { internal_dmz, net_dmz }

# define the parameters for the child queues.
# internal_dmz   - traffic from the internal network.
# net_dmz        - container queue for traffic from the Internet.
#   net_dmz_http - http traffic.
#   net_dmz_misc - all non-http traffic. this is also the default queue.

queue internal_dmz      # no special settings needed
queue net_dmz        bandwidth 500Kb { net_dmz_http, net_dmz_misc }
  queue net_dmz_http priority 3 cbq(red)
  queue net_dmz_misc priority 1 cbq(default)


# ... in the filtering section of pf.conf ...

main_net  = "192.168.0.0/24"
it_net    = "192.168.1.0/24"
int_nets  = "{ 192.168.0.0/24, 192.168.1.0/24 }"
dmz_net   = "10.0.0.0/24"

boss      = "192.168.0.200"
wwwserv   = "10.0.0.100"

# default deny
block on { fxp0, fxp1, dc0 } all

# filter rules for fxp0 inbound
pass in on fxp0 proto tcp from any to $wwwserv port { 21, \
	> 49151 } flags S/SA keep state queue www_ext_misc
pass in on fxp0 proto tcp from any to $wwwserv port 80 \
	flags S/SA keep state queue www_ext_http

# filter rules for fxp0 outbound
pass out on fxp0 from $int_nets to any keep state
pass out on fxp0 from $boss to any keep state queue boss_ext

# filter rules for dc0 inbound
pass in on dc0 from $int_nets to any keep state
pass in on dc0 from $it_net to any queue it_int
pass in on dc0 from $boss to any queue boss_int
pass in on dc0 proto tcp from $int_nets to $wwwserv port { 21, 80, \
	> 49151 } flags S/SA keep state queue www_int

# filter rules for dc0 outbound
pass out on dc0 from dc0 to $int_nets

# filter rules for fxp1 inbound
pass in on fxp1 proto { tcp, udp } from $wwwserv to any port 53 \
	keep state

# filter rules for fxp1 outbound
pass out on fxp1 proto tcp from any to $wwwserv port { 21, \
	> 49151 } flags S/SA keep state queue net_dmz_misc
pass out on fxp1 proto tcp from any to $wwwserv port 80 \
	flags S/SA keep state queue net_dmz_http
pass out on fxp1 proto tcp from $int_nets to $wwwserv port { 80, \
	21, > 49151 } flags S/SA keep state queue internal_dmz

[前に戻る: アンカーと名前付き (サブ) ルールセット] [目次] [次に進む: アドレスプールと負荷分散 (Load Balancing)]


[back] www@openbsd.org
Originally [OpenBSD: queueing.html,v 1.18 ]
$Translation: queueing.html,v 1.9 2004/01/19 05:55:02 toshi Exp $
$OpenBSD: queueing.html,v 1.10 2004/02/25 18:31:45 jufi Exp $