Dear List,
With help from various people here I've composed a pf ruleset that
allows "load splitting" between two (or more) ISP connections
on the basis of the client (internal) IP addressess.
The problem I have with this is when one or more of the ISPs provide
a DHCP assigned address/route. While the (ifn) notation provides for
reading an assigned address for an interface, I can find no way of
dealing with an assigned (route) gateway for the
... route-to { ($ext_if $ext_gw) } ... notation.
Here's the ruleset. Let me know if you have a use for it or know
of some way of getting the DHCP gateway.
Thanks,
Dhu
ext_if1 = "re0"
ext_if2 = "vr0"
ext_gw1 = "xx.xx.xx.xx"
ext_gw2 = "xx.xx.xx.xx"
int_if = "axe0"
int_net = "192.168.117.0/24"
int_clS = "{ 192.168.117.46,192.168.117.45,192.168.117.47 }"
# tcp_services provided by this server on the external interface
tcp_services = "{ 22,123 }"
# 22 ssh
# 25 smtp
# 53 dns
# 80 http
# 110 pop
# 123 ntp
# 443 https
# 587 smtp-submit
# 3389 rdesk
# 8118 privoxy
# 9001 tor external
# 9050 tor
# 9051 tor ctl
# udp_services provided by this server on the external interface
udp_services = "{ 123 }"
# 53 dns
# 69 tftp
# 123 ntp
# 587 smtp_submit
icmp_types = "echoreq"
set skip on lo0
scrub in
# nat outgoing connections on each internet interface
nat on $ext_if2 from $int_net to any -> ($ext_if2)
nat on $ext_if1 from $int_clS to any -> ($ext_if1)
# default deny
block in from any to any
block out from any to any
# pass all outgoing packets on internal interface
pass out log on $int_if from any to $int_net
# pass in quick any packets destined for the gateway itself
pass in log quick on $int_if from $int_net to $int_if
# Pass in tcp_services
pass in log on $ext_if1 inet proto tcp from any to ($ext_if1) port
$tcp_services flags S/SA keep state
pass in log on $ext_if2 inet proto tcp from any to ($ext_if2) port
$tcp_services flags S/SA keep state
# Pass in udp_services
pass in log on $ext_if1 inet proto udp from any to ($ext_if1) port
$udp_services keep state
pass in log on $ext_if2 inet proto udp from any to ($ext_if2) port
$udp_services keep state
# Pass in from int_net
pass in log on $int_if route-to { ($ext_if2 $ext_gw2) } proto tcp from $int_net
to any flags S/SA modulate state
pass in log on $int_if route-to { ($ext_if2 $ext_gw2) } proto { udp, esp, icmp
} from $int_net to any keep state
# Pass in from int_clS
pass in log on $int_if route-to { ($ext_if1 $ext_gw1) } proto tcp from $int_clS
to any flags S/SA modulate state
pass in log on $int_if route-to { ($ext_if1 $ext_gw1) } proto { udp, esp, icmp
} from $int_clS to any keep state
# general "pass out" rules for external interfaces
pass out log on $ext_if1 proto tcp from any to any flags S/SA modulate state
pass out log on $ext_if1 proto { udp, icmp } from any to any keep state
pass out log on $ext_if2 proto tcp from any to any flags S/SA modulate state
pass out log 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 log on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any
pass out log on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any
# Pass ICMPing
pass in log inet proto icmp all icmp-type $icmp_types keep state
pass out log on $ext_if1 proto { icmp } all keep state
pass out log on $ext_if2 proto { icmp } all keep state