Linux – DNAT port range with different internal port range with Iptables

iptableslinuxlinux-networkingnat;

The standard way of DNATing a single port to a different port on an internal network is something like that:

ip(6)tables -t nat -A PREROUTING -i wan0 -p tcp --dport 80 --to-destination 10.0.0.1:8080

If you need a port range you can use -m multiport together with --dports like that:

ip(6)tables -t nat -A PREROUTING -i wan0 -p tcp -m multiport --dports 1000:2000 --to-destination 10.0.0.1

Now what I want to know if you can combine the two techniques to map a port range (for example 1000-2000) to a different one of the same size (for example 12000-13000). Is that possible with Iptables using a kernel no later than Linux 4.1?

Best Answer

To answer your question, yes.

I ran a sample rule on my Debian box...

iptables -t nat -A PREROUTING -i xenbr0 -p tcp --dport 64000:65000 -j DNAT --to 172.16.10.10:61000-62000

... which produced no output, indicating success. I'm running kernel 3.16.0-4-amd64.

Checking the NAT rule via iptables -t nat -vnL PREROUTING, I see the rule is listed...

DNAT       tcp  --  xenbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpts:64000:65000 to:172.16.10.10:61000-62000

MadHatter is correct, you do not need -m multiport for port ranges, only for comma-separated lists of ports. The : is needed in order to specify port ranges for the --dport option, but a - is needed in order to specify port ranges in the DNAT target.

How well this rule will work in practice I cannot say, but theoretically it should accomplish your goal.

More information on DNAT target can be found here.

Hope this helps.