Today I received a question about how to distribute the outgoing connections between several IP addresses attached to an interface. Suppose that you have 3 IPs in the eth0 interface and you want to do round robin between that IPs for outgoing connections. With regular iproute commands you can’t. Doing some tricks with fwmarks, ip rule and ip route neither.
The only way that I’ve found to it is using SNAT and statistics to get a real Round Robin balance:
iptables -t nat -A POSTROUTING -m statistic --mode nth --every 3 -j SNAT --to 192.168.1.201
iptables -t nat -A POSTROUTING -m statistic --mode nth --every 2 -j SNAT --to 192.168.1.202
iptables -t nat -A POSTROUTING -m statistic --mode nth --every 1 -j SNAT --to 192.168.1.203
The IPs described in the example should be local IPs.
This is a small HOWTO about doing source routing with Squid and Linux. With Squid you can specifiy the outgoing IP address using ACLs. That means that you can select the outgoing IP using the information inside HTTP messages, thing that you can’t do with a firewall. The syntax is simple:
acl somedomain dstdomain somedomain.com
tcp_outgoing_address 126.96.36.199 somedomain
Those two lines say: “If the request is asking for somedomain.com, go to the world using IP 188.8.131.52”.
Now the Linux part. If you have more than one public IP address and you want to make the Squid configuration to work you need some iproute lines.
ip rule add table 10 from 184.108.40.206
ip route add table 10 default via GW
And those two lines says: “If the source IP of the packaet is 220.127.116.11, go via GW”.
Source routing with Linux is simple. What you do is to create a new table. This table will be used by that packets that match the criteria specified in “ip rule”. The “default table” is the table main, everything goes there if there is no rule. Is the table that you see with “ip route” or “route -n” (please, don’t use the last command anymore).