DNAT multiple --to-destination gone: why?
According to man iptables:
DNAT...
In Kernels up to 2.6.10 you can add several --to-destination options. For those kernels, if you specify more than one desti- nation address, either via an address range or multiple --to- destination options, a simple round-robin (one after another in cycle) load balancing takes place between these addresses. Later Kernels (>= 2.6.11-rc1) don't have the ability to NAT to multiple ranges anymore.
I'm wondering why this feature was removed?
What are the workarounds/alternatives?
The reason I ask is that I'm using the range feature to DNAT packets round-robin to 5 machines (.101-.105). .103 just had a hard drive failure and when I went to remove it from the iptables config I find I can't do that anymore as the feature was removed! I've worked around the problem by re-IPing a machine but I'm wondering if there is a iptables solution to this so I'll be better prepared in future?
Thanks!
ds
Quoted 17 lines · David Sparks
According to man iptables:
DNAT...
In Kernels up to 2.6.10 you can add several
--to-destination
options. For those kernels, if you specify more than
one desti-
nation address, either via an address range or
multiple --to-
destination options, a simple round-robin (one after
another in
cycle) load balancing takes place between these
addresses.
Later Kernels (>= 2.6.11-rc1) don't have the ability
to NAT to
multiple ranges anymore.
Quoted 1 line
I'm wondering why this feature was removed?
I don't have an answer for this, although perhaps others do.
Quoted 3 lines
What are the workarounds/alternatives?
The reason I ask is that I'm using the range feature to DNAT packets round-robin to 5 machines (.101-.105). .103 just had a hard drive failure and when I went to remove it from the iptables config I find I can't do that anymore as the feature was removed! I've worked around the problem by re-IPing a machine but I'm wondering if there is a iptables solution to this so I'll be better prepared in future?
Here's a workaround that might do what you seek. Optionally, you might consider a DNS-RR instead if it makes sense for your needs.
With the statistic match you can create a round-robin that targets each rule in turn. To do what you seek above you could use this series of rules, with your own additional matches added as required:
iptables -A PREROUTING -t nat -m statistic --mode nth --every 2 -j DNAT 10.0.0.101-102
iptables -A PREROUTING -t nat -j DNAT 10.0.0.104-105
This is conceptually the same (but simpler than) the following series of rules:
iptables -A PREROUTING -t nat -m statistic --mode nth --every 4 -j DNAT 10.0.0.101 iptables -A PREROUTING -t nat -m statistic --mode nth --every 3 -j DNAT 10.0.0.102 iptables -A PREROUTING -t nat -m statistic --mode nth --every 2 -j DNAT 10.0.0.104 iptables -A PREROUTING -t nat -j DNAT 10.0.0.105
Of course, you can continue to add more rules as required.
Signature · 1 line
Josh
Quoted 1 line · Josh Cepek
Here's a workaround that might do what you seek. Optionally, you might consider a DNS-RR instead if it makes sense for your needs.
DNS based load balancing is ok, but it is better in theory. I think something like LVS will do a much better job.
Quoted 3 lines
With the statistic match you can create a round-robin that targets each rule in turn. To do what you seek above you could use this series of rules, with your own additional matches added as required:
iptables -A PREROUTING -t nat -m statistic --mode nth --every 2 -j DNAT 10.0.0.101-102
iptables -A PREROUTING -t nat -j DNAT 10.0.0.104-105
I suppose this would work for a fairly static set of destination servers. Seeing as how you would have to re-write the rules if a back end server was added or removed, this would be a major PITA if the servers were dynamic in nature.
Quoted 7 lines
This is conceptually the same (but simpler than) the following series of rules:
iptables -A PREROUTING -t nat -m statistic --mode nth --every 4 -j DNAT 10.0.0.101 iptables -A PREROUTING -t nat -m statistic --mode nth --every 3 -j DNAT 10.0.0.102 iptables -A PREROUTING -t nat -m statistic --mode nth --every 2 -j DNAT 10.0.0.104 iptables -A PREROUTING -t nat -j DNAT 10.0.0.105Of course, you can continue to add more rules as required.
Ugh. That does not scale very well at all. If you want to remove 102 from above, you would have to re-write all the rules above it.
Grant. . . .
Quoted 11 lines · Grant Taylor
Quoted 7 lines · Josh Cepek
This is conceptually the same (but simpler than) the following series of rules:
iptables -A PREROUTING -t nat -m statistic --mode nth --every 4 -j DNAT 10.0.0.101 iptables -A PREROUTING -t nat -m statistic --mode nth --every 3 -j DNAT 10.0.0.102 iptables -A PREROUTING -t nat -m statistic --mode nth --every 2 -j DNAT 10.0.0.104 iptables -A PREROUTING -t nat -j DNAT 10.0.0.105Of course, you can continue to add more rules as required.
Ugh. That does not scale very well at all. If you want to remove 102 from above, you would have to re-write all the rules above it.
Quite right, and I don't suggest anyone use the above ruleset as it was included to illustrate the process more clearly by using consecutive statistic matches. The hint was that the concept could be expanded upon as needed, such as the following example where $N is the number of ranges needed:
-m statistic --mode nth --every $N -j DNAT $RANGE1
-m statistic --mode nth --every $(($N-1) -j DNAT $RANGE2
...
-m statistic --mode nth --every 2 -j DNAT $RANGE_N-1
-j DNAT $RANGE_N
Rather than introduce a new idea I just kept the IP data provided by the OP. (And yes, for the terribly picky I know that doing this with uneven ranges complicates things further, but I'm pretty sure someone wanting this can read all about the --mode random functionality.)
Signature · 1 line
Josh
Quoted 8 lines · Josh Cepek
With the statistic match you can create a round-robin that targets each rule in turn. To do what you seek above you could use this series of rules, with your own additional matches added as required:
iptables -A PREROUTING -t nat -m statistic --mode nth --every 2 -j DNAT 10.0.0.101-102
iptables -A PREROUTING -t nat -j DNAT 10.0.0.104-105
Quoted 8 lines
This is conceptually the same (but simpler than) the following series of rules:
iptables -A PREROUTING -t nat -m statistic --mode nth --every 4 -j DNAT 10.0.0.101
iptables -A PREROUTING -t nat -m statistic --mode nth --every 3 -j DNAT 10.0.0.102
iptables -A PREROUTING -t nat -m statistic --mode nth --every 2 -j DNAT 10.0.0.104
iptables -A PREROUTING -t nat -j DNAT 10.0.0.105
It is not conceptually the same. NAT will try to use the same address pair (in this case, destination IP) for the same source address, in fact creating a not-so-round-robin. Splitting it up into multiple DNAT rules makes it a true round-robin.