How to Map Port Ranges with Different Internal Ports Using IPTables DNAT (Linux Kernel ≤4.1)


9 views

When working with IPTables DNAT (Destination Network Address Translation), a common requirement is forwarding external port ranges to internal hosts with different port numbering schemes. While single-port DNAT is straightforward, port range mappings introduce complexity.

The basic syntax for single-port forwarding:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1:8080

For port ranges with identical internal/external numbering:

iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 1000:2000 -j DNAT --to-destination 10.0.0.1

To map external ports 1000-2000 to internal ports 12000-13000 (kernel ≤4.1 solution):

iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 1000:2000 -j DNAT --to-destination 10.0.0.1:12000-13000
  • The ranges must be of equal size (1000 ports in this example)
  • Works with TCP and UDP protocols
  • Requires IPTables 1.4.21+ (matches kernel 4.1 capabilities)

For complex mappings where ranges aren't equal or need arithmetic operations:

# Requires recent kernels (4.2+) and IPTables 1.6.0+
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1000 -j DNAT --to-destination 10.0.0.1:12000
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 1001 -j DNAT --to-destination 10.0.0.1:12001
...

Check NAT rules:

iptables -t nat -L -n -v

Test connectivity:

nc -zv external_ip 1000-2000

For large port ranges (1000+ ports):

  • Prefer the multiport range method
  • Consider conntrack table sizing
  • Monitor NAT performance under load

When working with network address translation (NAT) in Linux, iptables provides powerful tools for redirecting traffic. The standard DNAT rule for a single port is straightforward:

iptables -t nat -A PREROUTING -i wan0 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1:8080

While mapping a single port is simple, mapping an entire range of ports to different internal ports presents a more complex scenario. The -m multiport module allows specifying port ranges:

iptables -t nat -A PREROUTING -i wan0 -p tcp -m multiport --dports 1000:2000 -j DNAT --to-destination 10.0.0.1

For kernels up to 4.1, we can achieve port range mapping with offsets using a combination of iptables modules:

iptables -t nat -A PREROUTING -i wan0 -p tcp -m multiport --dports 1000:2000 \\
-m addrtype --dst-type LOCAL \\
-j DNAT --to-destination 10.0.0.1:12000-13000

1. The port ranges must be of equal size (1000 ports in this example)
2. The --dst-type LOCAL helps match incoming connections
3. Kernel 4.1+ may require additional modules or different syntax

For more complex scenarios, consider using ipset:

ipset create portmap bitmap:port range 1000-2000
iptables -t nat -A PREROUTING -i wan0 -p tcp -m set --match-set portmap dst \\
-j DNAT --to-destination 10.0.0.1:12000-13000

Always verify your rules with:

iptables -t nat -L -v -n

And test connectivity using netcat or similar tools on both source and destination ports.