5

I'm trying to use iptables to load balance web traffic over multiple DSL lines by marking the packets and routing based on the mark. I'm working with CentOS 6.6, Kernel 2.6.32-504.16.2.el6.x86_64, Iptables v1.4.7.

For now I've done the following, as a proof of concept:

iptables -t mangle -A PREROUTING -j MARK --set-mark 2
iptables -t mangle -A OUTPUT -j MARK --set-mark 2

Plus some logging and failsafe for the remote connection:

iptables -t mangle -A PREROUTING -p tcp --dport 22 -j ACCEPT
iptables -t mangle -A OUTPUT -j LOG --log-prefix "output "
iptables -t mangle -A PREROUTING -j LOG --log-prefix "prerouting "

So iptables -t mangle -L -v gives me

Chain PREROUTING (policy ACCEPT 177 packets, 93050 bytes)
 pkts bytes target     prot opt in     out     source               destination
  164 13112 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ssh
 7687 4287K MARK       all  --  any    any     anywhere             anywhere            MARK set 0x2
 7687 4287K LOG        all  --  any    any     anywhere             anywhere            LOG level warning prefix `prerouting '

Chain INPUT (policy ACCEPT 184 packets, 91203 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 25 packets, 3100 bytes)
 pkts bytes target     prot opt in     out     source               destination
  304 38367 MARK       all  --  any    any     anywhere             anywhere            MARK set 0x2
  304 38367 LOG        all  --  any    any     anywhere             anywhere            LOG level warning prefix `output '

Chain POSTROUTING (policy ACCEPT 25 packets, 3100 bytes)
 pkts bytes target     prot opt in     out     source               destination

I've set up alternative routing tables. ip route show table DSL2 gives me

10.77.0.0/16 via 112.112.224.1 dev eth4
112.112.0.0/16 via 112.112.224.1 dev eth4
default via 10.177.55.33 dev eth2

(112.112.0.0/16 and 10.77.0.0/16 via eth4 is the LAN, 10.177.55.33 via eth2 is one of the DSL routers.)

And I added a policy to use table DSL2 when mark is set to 2. ip rule shows:

0:      from all lookup local
32764:  from all fwmark 0x2 lookup DSL2
32765:  from all fwmark 0x1 lookup DSL1
32766:  from all lookup main
32767:  from all lookup default

(Ignore DSL1 for now. It comes into play when it's working so far.)

The logs show that the mark is being applied: (end of the line)

Jun  1 17:05:03 squidXXX kernel: output IN= OUT=eth4 SRC=112.112.xxx.xxx DST=10.77.xxx.xxx LEN=312 TOS=0x08 PREC=0x00 TTL=64 ID=60789 DF PROTO=TCP SPT=22 DPT=49328 WINDOW=543 RES=0x00 ACK PSH URGP=0 MARK=0x2 

But when I try to connect to an outside address I get a network unreachable reply, both when pinging from the local machine or when connecting to the proxy from another machine. Note: I have a squid proxy running on that machine as well which is working as intended. When I add 10.177.55.33 as the default route in the main routing table I can reach outside networks just fine.

Now I've read about someone having the same problem and solving it be replacing the default route with target net 0.0.0.0/1. Not only is this wrong (any addresses above 128.0.0.0 wouldn't be accessible) but it also doesn't work in my case. Anyways what I get from it is that my routing table could be faulty so it takes the main routing table instead, but I don't see any errors. Or are there known bugs?

Following this lead I tried adding ip rule add from all lookup DSL2 prio 1002 which routes the packets as expected, so that's probably not it.

So it looks to me as if ip rule can't properly read the MARK or not use the table specified. But why?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.