Dear All,

Replying to one of my messages back in January about this toppic, Daniel 
Hartmeier suggests:

"Instead of using route-to on $int_if, you can let connections go out
through the one interface to the default gateway, and use route-to on a
'pass out on $ext_if1' rule to re-route the outgoing connection to
another interface. Packets will 'try' to get out on the default
interface, but re-routing occurs before they are actually sent out
through the interface.

  pass out on $ext_if1 route-to { ($ext_if1 $gwy_if1), \
        ($ext_if2 $gwy_if2) } round-robin ... keep state

Where $ext_if1 is the interface to your default gateway, where all
connections will go out through by default. Half of them will be
re-routed out on $ext_if2, and half will go out throuh $ext_if1.

You'd use the same construct if you wanted to load-balance outgoing
connections opened by the firewall itself (say, a DNS server there),
which don't arrive in on any interface at all."

Well, I tried to follow this recommendation, but I noticed that, although
PF indeed changed its behaviour and distributed the traffic between both 
external connections, the packets sent out through the other external 
connection (not the default gateway interface), had the source IP address 
of the default interface. As a result, they get lost or discarded by the 
ISP.

For example, in a setup where I have 

ext_if1:rl0 (default)
IP=200.177.74.209
GW=200.177.74.1

ext_if2:tun0 (vr0)
IP=201.9.168.157
GW=200.164.195.8

When I try to access the web from a client station behind my firewall, if 
the round-robin scheme chooses the default interface, then it all works 
fine. However, if it chooses the other interface, see what pflog shows:

Feb 10 19:50:00.960284 rule 26/0(match): pass out on tun0: 
  200.177.74.209.60024> 129.128.5.191.80: S 1008219106:1008219106(0) 
  win 65535 <mss 1460,nop,nop,sackOK> (DF)

and that can also be confirmed from the output of tcpdump on the vr0 
(tun0) interface:

Feb 10 19:50:07.522986 0:d:87:a3:99:94 0:3:e3:5d:d3:7 8864 70: 
  PPPoE-Session        code Session, version 1, type 1, id 0x1169, 
  length 50        IP: 200.177.74.209.60024 > 129.128.5.191.80: 
  S 1008219106:1008219106(0)

Rule 26 mentioned above is this:

pass out quick log-all on $ext_if1 route-to \
    { ($ext_if1 <gws_if1>) , ($ext_if2 <gws_if2>) } round-robin \
    inet proto tcp from any to any keep state

Now the question is how to tell PF to change the source IP address when it 
decides to send the packet through the other interface ?

Thanks in advance.

Regards,

Emilio

ps. here is the pf.conf file
---------------------------------
ext_if1="rl0"
gw_if1="200.177.74.1"
gw_if2="200.164.195.8"
ext_if2="tun0"
int_if="rl1"
lan_net=$int_if:network

table <gws_if1> { $gw_if1 }
table <gws_if2> { $gw_if2 }

tcp_INservices = "{ 22 }"
icmp_types = "echoreq"

priv_nets =  "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"

scrub in all random-id fragment reassemble

# nat/rdr

nat on $ext_if1 from $int_if:network to any -> ($ext_if1)
nat on $ext_if2 from $int_if:network to any -> ($ext_if2)

# squid

rdr on $int_if inet proto tcp from $lan_net to any port www -> 127.0.0.1 port 
3128

block in log from any to any
block out log from any to any

# loopback

pass quick on lo0 all

block drop in log quick on $ext_if1 from $priv_nets to any
block drop out log quick on $ext_if1 from any to $priv_nets
block drop in log quick on $ext_if2 from $priv_nets to any
block drop out log quick on $ext_if2 from any to $priv_nets

pass in quick log-all on $int_if from $int_if:network to any keep state

pass out quick log-all on $ext_if1 route-to \
    { ($ext_if1 <gws_if1>) , ($ext_if2 <gws_if2>) } round-robin \
    inet proto tcp from any to any keep state

# from internal network to firewall

pass in log-all on $int_if from $lan_net to $int_if flags S/SA keep state

# from firewall to internal network

pass out log on $int_if from $int_if to $int_if:network keep state

# firewall services

pass in log-all quick on $ext_if1 reply-to ($ext_if1 $gw_if1) inet proto tcp 
from any to ($ext_if1) port $tcp_INservices flags S/SA keep state 
pass in log-all quick on $ext_if2 reply-to ($ext_if2 $gw_if2) inet proto tcp 
from any to ($ext_if2) port $tcp_INservices flags S/SA keep state

# icmp

pass in log-all quick on $ext_if1 reply-to ($ext_if1 $gw_if1) inet proto icmp 
all icmp-type $icmp_types keep state
pass in log-all quick on $ext_if2 reply-to ($ext_if2 $gw_if2) inet proto icmp 
all icmp-type $icmp_types keep state 

# outside services

pass out on $ext_if1 proto tcp all flags S/SA keep state
pass out on $ext_if2 proto tcp all flags S/SA keep state

pass out on $ext_if1 proto {udp icmp} all keep state
pass out on $ext_if2 proto {udp icmp} all keep state

Reply via email to