[OpenBSD]

[上一小节: 数据包的列队和优先] [总目录] [下一小节: 数据包标记]

PF: 地址池和负载均衡


目录


介绍

地址池是系统提供给一组用户共享的两个或多个地址。一个地址池可以用 rdr-tonat-toroute-to, reply-to, 以及 dup-to 过滤 选项的形式作为目标地址。

有四种使用地址池的方法:

除了round-robin方法, 地址池必须用一个 CIDR 网段表示。round-robin方法允许用一个listtable表示的多个地址。

sticky-address 选项可以与 randomround-robin 类型的地址池一同使用, 这样可以确保一个特定的源地址总是被映射到同一个转发地址上。

NAT 地址池

一个地址池可以作为 nat-to 规则中的转换地址。多个连接的源地址将基于选择的上述方法被转换成地址池中的一个地址。这在PF为一个非常大型的网络做NAT时很有用。因为每个转换地址被NAT的连接数是有限的, 增加额外的转换地址可以让NAT网关按比例为更多用户提供服务。

这个例子中用一个包含两个地址的地址池转换出站数据包。PF用round-robin方法依次循环地为每个出站连接转换地址。

match out on $ext_if inet nat-to { 192.0.2.5, 192.0.2.10 } 

这种方法的一个缺点是来自同一个内部地址的延续性连接并非总是被转换到同一个的转换地址上。这种情况可能导致冲突, 例如, 当web站点跟踪登录用户的IP地址时, 一个替代方案是使用 source-hash 方法, 这样每个内部地址总是被转换为同一个转换地址。为了完成这个目的, 地址池必须是一个CIDR网段。

match out on $ext_if inet nat-to 192.0.2.4/31 source-hash

规则使用地址池192.0.2.4/31 (192.0.2.4 - 192.0.2.5) 作为出站数据包的转换地址。因为使用了source-hash关键字, 所以每个内部地址将总是被转换成同一个转换地址。

进站连接的负载均衡

地址池也可以用来实现进站连接的负载均衡。例如, 到web服务器的进站连接可以被分配到一组服务器:
web_servers = "{ 10.0.0.10, 10.0.0.11, 10.0.0.13 }"

match in on $ext_if proto tcp to port 80 rdr-to $web_servers \ round-robin sticky-address

延续性的连接将被以round-robin方式重定向到这组服务器, 同时来自同一地址的连接总被分配到固定的同一台服务器上。只要连接还保持着状态, 这种 "粘性连接"将一直存在。一旦状态结束, 粘性连接也不存在了, 这时来自那台主机的更多的连接将按依次循环(round robin)的方式被重新定向到下一台服务器上。

出站通讯的负载均衡

当一个固有的多路径路由协议(像 BGP4) 不可用时, 地址池和 route-to 过滤选项结合使用可以平衡两个以上的Internet链接的负载。通过使用 route-to 和一个 round-robin 型地址池, 出站连接可以被均匀地分配到多个出站路径中。

还需要的一个额外信息是每个Internet连接毗邻路由器的IP地址。这是用来提供给 route-to 选项以控制出站数据包的目的地。

下面的例子均衡两个Internet连接的出站通讯:

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 选项 (它不能与 match 规则一起应用)。

为了确保源地址属于 $ext_if1 的数据包总是被路由到 $ext_gw1 (对 $ext_if2$ext_gw2 也类似) , 下面的两行应该包含在规则集中:

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

最终, NAT 也能被用在每个出站接口上:

match out on $ext_if1 from $lan_net nat-to ($ext_if1)
match out on $ext_if2 from $lan_net nat-to ($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
match out on $ext_if1 from $lan_net nat-to ($ext_if1)
match out on $ext_if2 from $lan_net nat-to ($ext_if2)

#  default deny
block in
block out

#  pass all outgoing packets on internal interface
pass out on $int_if 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 traffic from internal network. 
pass in on $int_if from $lan_net \
    route-to { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } \
    round-robin
#  keep https traffic on a single connection; some web applications,
#  especially "secure" ones, don't allow it to change mid-session
pass in on $int_if proto tcp from $lan_net to port https \
    route-to ($ext_if1 $ext_gw1)

#  general "pass out" rules for external interfaces
pass out on $ext_if1
pass out on $ext_if2

#  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 from $ext_if2 route-to ($ext_if2 $ext_gw2)
pass out on $ext_if2 from $ext_if1 route-to ($ext_if1 $ext_gw1)

[上一小节: 数据包的列队和优先] [总目录] [下一小节: 数据包标记]


[back] www@openbsd.org
$OpenBSD: pools.html, v 1.22 2008/10/31 16:49:34 nick Exp $