# Load Balancing Single Session Different IPS



## Sabrtooth (Jul 7, 2011)

I've set up a FreeBSD 7.2 router on my network and migrated to PF 4.1 today using this manual.

So I have ten IP addresses, five on each connection. One DSL (re0), one Cable (re2).



```
################ Macros ####################################
lan_net = "{192.168.22.0/24, 127.0.0.8/8, 192.168.12.0/24, 10.0.64.0}"
int_if1 = "re1"
int_if2 = "re3"
all_int = "{ re1, re3 }"
ext_if1 = "re0"
ext_if2 = "re2"
all_ext = "{ re0, re2 }"
ext_gw1 = "A.A.A.A"
ext_gw2 = "B.B.B.B"
```

Here are my Load Balancing Rules:


```
# pass in quick any packets destined for the gateway itself
pass in quick on $int_if1 from $lan_net to $int_if1
pass in quick on $int_if2 from $lan_net to $int_if2
# load balance outgoing tcp traffic from internal network.
pass in on $int_if1 route-to \
{ ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
proto tcp from $lan_net to any flags S/SA modulate state
pass in on $int_if2 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_if1 route-to \
{ ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin \
proto { udp, icmp } from $lan_net to any keep state
pass in on $int_if2 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
```

I've set load balancing up, round-robin, successfully and am pleased. I'm antsy to get to tweaking and making it work more efficiently.

Thanks to my last thread, I am accepting connections on both interfaces.

My problem now is that whenever I connect to some sites, they get upset when requests for a single session come from different IP addresses. 

Each interface has 5 static IP addresses on it. I also run Squid. I've got some ideas, but I was wondering about suggestions.

I know I can do this in Squid, but that would limit it to one connection/IP for all web browsing. I am thinking that I write specific rules with route-to's for protocols that are affected by this.

Suggestions? I'd optimally like to have all web traffic load balance over both connections (not necessarily all 10 IPs) but have protocols that get cranky favor one connection. I'll put up what I come up with as I do it. Thanks in advance!


----------



## Sabrtooth (Jul 7, 2011)

One thing that may be missing here is my NAT commands:


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

To start, I wanted to add the source-hash command so I set up everything in a CIDR configuration:

```
#nat on $ext_if1 from $lan_net to any -> A.A.A.98/29 source-hash
#nat on $ext_if2 from $lan_net to any -> B.B.B.35/29 source-hash
```

This seems to break outgoing connectivity, but connections I initiate outside the network to servers behind the firewall are maintained (no change).


----------



## Sabrtooth (Jul 7, 2011)

To be lazy, I even tried just straight up redirecting outgoing connections on port 80/443 to test:


```
#rdr on $all_int proto tcp from $lan_net to any port 443 -> A.A.A.98 source-hash
#rdr on $all_int proto tcp from $lan_net to any port 80 -> A.A.A.98 source-hash
```

I even modified the A.A.A.98 to have a /29 to test.

Both just flat out break outgoing connections on those ports.


----------



## Sabrtooth (Jul 9, 2011)

Ok,

So I have this figured out, stay tuned as I'm shaping it all up tomorrow. I will intend to supply documentation Monday or Tuesday at the best.

The long and short of it is that I needed to modify the rule set to use source-hash. To be honest, I'm not even sure what system round-robin would work well for without source-hash in there somewhere. But I'll post my theory later.

here's the code:


```
nat on $ext_if1 from $lan_net to any -> a.a.a.98/29 source-hash
nat on $ext_if2 from $lan_net to any -> b.b.b.35/29 source-hash
```


```
# Choose the connection Lan Traffic will leave on.
#pass in quick log on $int_if1 route-to ($ext_if1 $ext_gw1) source-hash \
#proto tcp from $lan_net to any flags S/SA modulate state
#pass in quick log on $int_if1 route-to ($ext_if1 $ext_gw1) source-hash \
#proto{ udp, icmp } from $lan_net to any keep state
pass in quick log on $int_if1 route-to ($ext_if2 $ext_gw2) source-hash \
proto tcp from $lan_net to any flags S/SA modulate state
pass in quick log on $int_if1 route-to ($ext_if2 $ext_gw2) source-hash \
proto{ udp, icmp } from $lan_net to any keep state
```


----------



## overmind (Jul 11, 2011)

What happens if you unplug line from one of the routers?

Do you have some kind of failover?


----------



## Sabrtooth (Jul 13, 2011)

Hey Overmind,

This is NOT failover, it's just load balancing. I'm working on the failover, but you do it through scripting. 

If you unplug one of the cords, any time a connection is attempted on that pool it will fail.


----------



## overmind (Jul 13, 2011)

I am looking for a smarter solution, rather than a script that ping both ISPs and then do failover.


----------



## Sabrtooth (Jul 14, 2011)

I'm certain they're out there! 

I've not even begun to research, but let me know if you find anything. 

Thanks!


----------

