[OpenBSD]

[前に戻る: パケットキューイングと優先順位付け] [目次] [次に進む: パケットのタグ付け]

PF: アドレスプールと負荷分散 (Load Balancing)


目次


はじめに

アドレスプールは、ユーザのグループの間で共有して使用される、ふたつ以上のアドレスを 提供するためのものです。アドレスプールは、rdr ルール中の リダイレクションアドレスとして、あるいは、nat ルール中の 変換アドレスや、フィルタオプションの route-toreply-to および dup-to のターゲットアドレスとして指定することができます。

アドレスプールを使用するには、4 つの方法があります。

round-robin 法を除いて、アドレスプールは CIDR (Classless Inter-Domain Routing) ネットワークブロックとして記述されていなければなりません。round-robin 法では、リストのフォーマットテーブルを使用して複数の個々のアドレスを指定できます。

NAT アドレスプール

アドレスプールは、nat ルールの 変換アドレスとして使用することができます。接続の元の送信元アドレスは、 選択した方法に基づくプールからのアドレスで変換されます。 これは、PF が非常に大規模なネットワークで NAT を実行しているような状況で 役に立つものです。変換アドレスごとの NAT を使用する接続の数は限られているので、 付加的な変換アドレスを追加することは、より多くのユーザにサービスを提供するため、 NAT ゲートウェイがその規模を拡大させることができることを意味します。

この例では、送出されるパケットを変換するために、ふたつのアドレスのプールが 使用されることになります。それぞれの送出される接続のために、 PF はラウンドロビンで使用するアドレスのローテーションを行います。

nat on $ext_if inet from any to any -> { 192.0.2.5, 192.0.2.10 }

この方法のひとつの欠点は、内部ネットワークからの一連の接続に対して、 常に同じアドレスへと変換されるとは限らないということでしょう。 これはたとえば、IP アドレスに基づいてユーザのログインを追跡するような web サイトをブラウジングする際などに、障害となり得るものです。 この代替の方法は、それぞれの内部アドレスが常に同じ変換アドレスへと 変換される source-hash 法を使用することです。 これを使用するためには、アドレスプールは CIDR ネットワークブロックでなければなりません。

nat on $ext_if inet from any to any -> 192.0.2.4/31 source-hash

この nat ルールは、192.0.2.4/31 (192.0.2.4 〜 192.0.2.5) の アドレスプールを、送出パケットの変換アドレスとして使用しています。 それぞれの内部アドレスは、source-hash キーワードによって、 常に同じ変換アドレスへと変換されます。

着信接続の負荷分散

アドレスプールはまた、着信接続の負荷分散のためにも使用することができます。 たとえば、web サーバに着信する接続は、以下のように web サーバの集合に 分散させることができるのです。
web_servers = "{ 10.0.0.10, 10.0.0.11, 10.0.0.13 }"

rdr on $ext_if proto tcp from any to any port 80 -> $web_servers

一連の接続は、ラウンドロビン法で web サーバに リダイレクトされることになります。

NAT の例としては、すべての web サーバが CIDR ネットワークブロック内に 配置されている場合には、与えられた IP アドレスが物理的に同じ web サーバに 常にリダイレクトされるよう、source-hash キーワードを 使用することができます。もう一度言いますが、これは、web サーバのブラウジングの際の セッション情報を保守するために、ときどき必要となるものです。

送出トラフィックの負荷分散

アドレスプールは、(BGP4 のような) 適正な複数経路用のルーティングプロトコルを利用できない場合に、 ふたつ以上のインターネット接続の負荷分散を行うために route-to フィルタオプションと組み合わせて使用することができます。 round-robin 法のアドレスプールとともに route-to を使用することで、外向きの接続は複数の外向きの経路の中で 均等に分散されるようになります。

これは付加的な情報ですが、このようにするためには、それぞれの インターネット接続に隣接するルータの IP アドレスが必要になります。 これは、送出パケットの送信先を制御するため、route-to オプションに供給するためのものです。

以下の例は、ふたつのインターネット接続への送出トラフィックの 負荷分散を行います。

lan_net = "192.168.0.0/24"
int_if  = "dc0"
ext_if1 = "fxp0"
ext_if2 = "fxp1"
ext_gw1 = "68.146.224.1"
ext_gw2 = "142.59.76.1"

pass in on $int_if route-to \
   { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
   from $lan_net to any keep state

route-to オプションは、それぞれのゲートウェイに対してトラフィックの 負荷分散を行うための、送出用のネットワークインターフェイスを指定するため、 内部インターフェイスに着信するトラフィックに対して使用されるものです。 route-to オプションは、それぞれのトラフィックの負荷分散を行う フィルタルールが存在していなければならないということに注意してください。 戻りパケットは、送出されたものと同じ外部インターフェイスに返送されて来て (これは ISP によって行われます)、さらに普通に内部ネットワークへと 転送されて行きます。

$ext_if1 に属する送信元アドレスを持つパケットが、常に $ext_gw1 へと (そして、同様に、$ext_if2$ext_gw2 へと) ルーティングされるのを確実にするため、 以下の 2 行がルールセットに含まれているべきでしょう。

pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 \
   to any
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 \
   to any

最終的に、NAT をそれぞれの送出用インターフェイスに対して使用することができます。

nat on $ext_if1 from $lan_net to any -> ($ext_if1)
nat on $ext_if2 from $lan_net to any -> ($ext_if2)

送出トラフィックの負荷分散を行うための完全な例は、 以下のようなものになるかも知れません。

lan_net = "192.168.0.0/24"
int_if  = "dc0"
ext_if1 = "fxp0"
ext_if2 = "fxp1"
ext_gw1 = "68.146.224.1"
ext_gw2 = "142.59.76.1"

#  nat outgoing connections on each internet interface
nat on $ext_if1 from $lan_net to any -> ($ext_if1)
nat on $ext_if2 from $lan_net to any -> ($ext_if2)

#  default deny
block in  from any to any
block out from any to any

#  pass all outgoing packets on internal interface
pass out on $int_if from any to $lan_net
#  pass in quick any packets destined for the gateway itself
pass in quick on $int_if from $lan_net to $int_if
#  load balance outgoing tcp traffic from internal network. 
pass in on $int_if route-to \
    { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
    proto tcp from $lan_net to any flags S/SA modulate state
#  load balance outgoing udp and icmp traffic from internal network
pass in on $int_if route-to \
    { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
    proto { udp, icmp } from $lan_net to any keep state

#  general "pass out" rules for external interfaces
pass out on $ext_if1 proto tcp from any to any flags S/SA modulate state
pass out on $ext_if1 proto { udp, icmp } from any to any keep state
pass out on $ext_if2 proto tcp from any to any flags S/SA modulate state
pass out on $ext_if2 proto { udp, icmp } from any to any keep state

#  route packets from any IPs on $ext_if1 to $ext_gw1 and the same for
#  $ext_if2 and $ext_gw2
pass out on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any 
pass out on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any 

[前に戻る: パケットキューイングと優先順位付け] [目次] [次に進む: パケットのタグ付け]


[back] www@openbsd.org
Originally [OpenBSD: pools.html,v 1.10 ]
$Translation: pools.html,v 1.6 2004/01/03 05:24:39 toshi Exp $
$OpenBSD: pools.html,v 1.7 2004/01/04 22:47:55 horacio Exp $