[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

load-balancing outgoing connections openned by the firewall on 3.6



Hi,

Daniel Hartmeier recommends the use of the following type of filter rule
to load-balance outgoing connections opened by a firewall with multiple
external connections:

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 the default gateway, where all 
connections will go out through by default. This way, half of 
them would be re-routed out on $ext_if2.

Now with this kind of pass rule, NAT rules (if used) should be rewritten
so that packets re-routed could have the source address replaced by that
of new interface's IP address:

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

First of all, one might be wondering why someone would want to 
load-balance outgoing connections opened by the firewall itself. My idea 
is to use this together with transparent squid.

I have been working on a setup like that for quite a while and have not 
managed to get it working yet. Here is my setup:

int_if1=rl1
IP=192.168.1.254

ext_if1=rl0(default)
IP=200.177.74.64
GW=200.177.74.1

ext_if2=vr0
IP=200.157.248.134
GW=200.157.248.1

After some unsuccessful tests with 3.5, I started to play with 3.6 stable
(I was informed that filtering had changed from 3.5 to 3.6).  Indeed
the outcome of the tests was different. However, it is still far from
working.

In one of the tests, I tried to establish a SMTP (telnet to port 25)
connection from the firewall to an Internet server.

Here is the output of tcpdump -nettti on the pflog0 interface:

Mar 14 17:06:05.198351 rule 4/0(match): pass out on rl0: 
200.177.74.64.28660 > 217.22.55.50.25: S 3040936729:3040936729(0) 
win 16384 <mss 1460,nop,nop,sackOK,[|tcp]> (DF) [tos 0x10]

Mar 14 17:06:05.198413 rule 4/0(match): pass out on vr0: 
200.177.74.64.28660 > 217.22.55.50.25: S 3040936729:3040936729(0) 
win 16384 <mss 1460,nop,nop,sackOK,[|tcp]> (DF) [tos 0x10]

Mar 14 17:06:11.190081 rule 4/0(match): pass out on rl0: 
200.177.74.64.28660 > 217.22.55.50.25: S 3040936729:3040936729(0) 
win 16384 <mss 1460,nop,nop,sackOK,[|tcp]> (DF) [tos 0x10]

Mar 14 17:06:11.190105 rule 4/0(match): pass out on vr0: 
200.177.74.64.28660 > 217.22.55.50.25: S 3040936729:3040936729(0) 
win 16384 <mss 1460,nop,nop,sackOK,[|tcp]> (DF) [tos 0x10]

Although pflog reports that packets were sent out through $ext_if2(vr0), 
the output of tcpdump -nettti on vr0 interface showed nothing at all. 
Also, notice that the source address of the "re-routed" packet is still 
wrong.


Below is the route table as shown by the command netstat -rnf inet:

Internet:
Destination        Gateway            Flags     Refs     Use    Mtu  
Interface
default            200.177.74.1       UGS         1      244      -   rl0
127/8              127.0.0.1          UGRS        0        0  33224   lo0
127.0.0.1          127.0.0.1          UH          3        0  33224   lo0
192.168.1/24       link#2             UC          0        0      -   rl1
200.157.248/24     link#3             UC          1        0      -   vr0
200.157.248.1      0:5:9a:d2:34:54    UHLc        0        0      -   vr0
200.157.248.134    127.0.0.1          UGHS        0        0  33224   lo0
200.177.74/24      link#1             UC          1        0      -   rl0
200.177.74.1       0:5:9a:d2:34:54    UHLc        1        0      -   rl0
200.177.74.64      127.0.0.1          UGHS        0        0  33224   lo0
224/4              127.0.0.1          URS         0        0  33224   lo0


I still think I am doing something wrong here. But I have run out of ideas 
on how to debug this problem. 

Any help is welcome.

Thanks in advance.

Regards,

Emilio

-------------------
# macros

ext_if1="rl0"
gw_if1="200.177.74.1"
gw_if2="200.157.227.1"
ext_if2="vr0"
int_if="rl1"
lan_net=$int_if:network

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

icmp_types = "echoreq"

# logging and pfstat

set debug urgent
set loginterface $int_if

# scrub

scrub in all

# nat/rdr

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

# filter rules

# default deny

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

# loopback 

pass quick on lo0 all

# from internal net to external services

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

# this is rule 4 mentioned above

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

# 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