On Thu, 22 Apr 2010 17:23:53 +0200 Gabriel Linder <lin...@jeuxvideo.com> wrote:
> Hi, > > I have two ISPs and a LAN. I need to load balance outgoing connections > from the LAN between the ISPs. > > My router is running OpenBSD 4.6-stable, up-to-date. > > ----------------- > | | > ISP 1 ---(isp1 box)---+-ext1_if | > | | > | int_if-+--- LAN > | | > ISP 2 ---(isp2 box)---+-ext2_if | > | | > ----------------- > OpenBSD > > int_if -> interface to LAN > int_net -> 192.168.0.0/24 > > ext1_if -> interface to ISP 1 (192.168.1.2) > ext1_gw -> ISP 1 gateway (192.168.1.1) > > ext2_if -> interface to ISP 2 (192.168.2.2) > ext2_gw -> ISP 2 gateway (192.168.2.1) > > There is no default route (empty /etc/mygate). > > Following http://www.openbsd.org/faq/pf/pools.html#outgoing I ended up > with the following : > > ---sysctl.conf--- > net.inet.ip.forwarding=1 > ---sysctl.conf--- > > ---pf.conf--- > set debug loud > set block-policy return > #set optimization aggressive > #set timeout src.track 300 > set skip on lo > > nat log on $ext1_if from $int_net -> ($ext1_if) > nat log on $ext2_if from $int_net -> ($ext2_if) > > block log > > pass in log on $int_if route-to \ > { ($ext1_if $ext1_gw), ($ext2_if $ext2_gw) } \ > from $int_net > > pass in log on $int_if from $int_net to $int_if > > pass out log > pass out log on $ext1_if route-to ($ext2_if $ext2_gw) from $ext2_if > pass out log on $ext2_if route-to ($ext1_if $ext1_gw) from $ext1_if > ---pf.conf--- > > Everything works fine with this setup but https and some ftp servers > are very sensitive to IP changes, so I did add sticky-address to bind > a connection to an ISP and fix this issue : > > pass in log on $int_if route-to \ > { ($ext1_if $ext1_gw), ($ext2_if $ext2_gw) } sticky-address \ > from $int_net > > This works when only one PC open a connection. When another PC open > a connection the first one has no longer access to the internet. After > some time in tcpdump and /var/log/messages, it seems because packets > are routed to the wrong interface. > > /var/log/messages analysis : > > 192.168.0.78 tries a connection : > /bsd: pf_map_addr: selected address 192.168.2.1 > /bsd: pf_map_addr: selected address 192.168.2.2 > /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.1 > /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.2 > /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.1 > /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.2 > > Looks ok, now 192.168.0.29 tries a connection too : > /bsd: pf_map_addr: selected address 192.168.1.1 > /bsd: pf_map_addr: selected address 192.168.1.2 > /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.1 > /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.2 > /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.1 > /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.2 > > Looks good, now 192.168.0.78 retries a connection : > /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.1 > /bsd: pf_map_addr: selected address 192.168.1.2 > [and that's all] > > This is confirmed by tcpdump (on pflog0, bge0, em0 and em1) : the > packets are routed to the wrong interface. Three SYN are sent, then > client bail out. Tests were quickly done, so there is no state/track > timeout here. > > Is there something I am doing wrong ? > Tried with a recent snapshot of -current, same problem but now the sticky-address option is simply ignored (confirmed with pfctl -vf /etc/pf.conf : only round-robin, no sticky-address). Nobody has a clue for this ? pf.conf says : pass in log on $int_if from $int_net route-to { ($ext1_if $ext1_gw), ($ext2_if $ext2_gw) } sticky-address but pfctl -vf says : pass in log on bge0 inet from 192.168.0.0/24 to any flags S/SA keep state route-to <__automatic_6c41d1cd_0> round-robin OpenBSD 4.7-current (GENERIC.MP) #0: Mon May 24 18:25:54 MDT 2010 dera...@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC.MP