When we think of load balancing, the first thought is about load balancing incoming transactions by using a dedicated load balancer in front of your server. However, there are many practical uses for load balancing outgoing transactions. Practical uses are to distribute HTTP requests (when you are requesting large number of files from an external server) or when sending emails out. Sometimes applications offer a way to bind to multiple IP addresses, for e.g., postfix allows you to specify the additional IP addresses in the /etc/postfix/transport file.
However, the method that I will explore in today’s article is application agnostic. It uses iptables and allows you to configure routing based on the destination port. You could route only HTTP traffic or DNS requests and allow other transmissions (like SSH) to use the primary IP. To set this up, you need a pool of consecutive IPs and make sure you don’t include the server’s primary IP in this pool.
For the purposes of explaining this article, I will show you how to route HTTP & FTP traffic to use multiple outbound IP addresses. The ports that we will Source NAT (SNAT) are TCP 80 (http), 443 (https) and 21 (ftp). You can choose other ports as well based on what your needs are
I will also use the ‘fake’ IP address range 192.168.1.1 to 192.168.1.6, where 192.168.1.1 is the server’s primary IP. As mentioned earlier, your pool must exclude the primary IP so it will start from 192.168.1.2. The final assumption is that the ethernet interface is eth0. To begin, kill the IP connections tracking table, so that the changes we make can take effect.
# iptables -t nat -F
Now we will redirect outbound connections through the eth0 interface for TCP requests for http/https or ftp to use the pool of outbound IP connections.
# iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 443 -j SNAT --to 192.168.1.2-192.168.1.6
# iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 21 -j SNAT --to 192.168.1.2-
Once you enter the above commands the routing becomes active (though they will not survive a reboot and we will come to that). Let’s curl a website that returns the IP address
# curl ifconfig.co
You should see a response like this
# curl ifconfig.co
If you see the primary IP (192.168.1.1 in our example), you need to reset the IP conntrack database via the command iptables -t NAT -F
Running the above curl command different times will return different IP addresses from the URL ifconfig.co. Other sites that provide a similar function are ifconfig.me and ipecho.net/plain
Once you see the different IPs that you needed, you can save these routing rules so that they can be persistent for the next restart
# iptables-save > /etc/sysconfig/iptables
Source NAT also works to help route traffic from internal private IPs to a public facing IP. Source NAT replaces the IP address in the header with the translated IP which is useful when you whitelist IP addresses at the destination (for e.g. for SSH or application administration). In such cases, you can change the SNAT to an individual IP rather than a range. This command helps routing
# iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 22 -j SNAT --to 192.168.1.2
If you have other use cases, feel free to comment below, I would love to hear about it