Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am trying to rotate outgoing IPs using iptables. I want to rotate outgoing connections between three IPs, one by one. Here is what I'm doing with iptables:

root@server:~# iptables -t nat -I POSTROUTING -m state --state NEW -p tcp --dport 80 -o eth0 -m statistic --mode nth --every 3 --packet 0 -j SNAT --to-source XXX.XXX.XXX.133
root@server:~# iptables -t nat -I POSTROUTING -m state --state NEW -p tcp --dport 80 -o eth0 -m statistic --mode nth --every 3 --packet 0 -j SNAT --to-source XXX.XXX.XXX.134
root@server:~# iptables -t nat -I POSTROUTING -m state --state NEW -p tcp --dport 80 -o eth0 -m statistic --mode nth --every 3 --packet 0 -j SNAT --to-source XXX.XXX.XXX.135

It seems like it's kind of working, but something is not reliable about it. The ordering of the outgoing IPs is not quite predictable, and it sometimes distributes them unevenly.

This is on a completely bare Ubuntu install so I don't think there are any other outgoing connections on this port, but I could be wrong.

Does anyone know how to make this more reliable? Or is it already doing the right thing and I'm interpreting the results wrong?

I want the IPs distributed perfectly evenly and reliably, one after another.

Here's what the results are:

{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.134","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.134","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.134","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.134","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.134","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.135","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
{"ip":"XXX.XXX.XXX.133","about":"/about","Pro!":"http://getjsonip.com"}root@server:~# curl jsonip.com
share|improve this question
2  
Do this in your application. –  Michael Hampton Mar 24 '13 at 3:05
1  
@MichaelHampton I would if I could, but I can't. I don't have access to the code. :) –  Mike Mar 24 '13 at 3:23
add comment

1 Answer

What happens if you try

--mode nth --every 3 --packet 0
--mode nth --every 2 --packet 0
--mode nth --every 1 --packet 0

I ask because I've seen several references to the fact that the counters are not global.

This is a common misunderstanding - the counters are not shared and since the rules are all terminal, the second rule will only see the packets not caught by the first rule etc. So the proportions need to be adjusted for the "missing" packets

In the old days before nth was part of the statistics module --every 2 --packet 0....--every 2 --packet 1 would have been correct. Now there is no global counter and it is reset per rule. So, I needed to do --every 2 --packet 0.... --every 1 --packet 0 instead. Now it works perfectly.

That's what other people trying to do what you are have discovered at least.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.