Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a Linux gateway with iptables which does routing and port forwarding. I want the port forwarding to happen independent of the routing.

To port forward, I add this to the nat table:

iptables -t nat -A "$PRE" -p tcp -d $GW --dport $fromPort -j DNAT --to-destination $toHost:$toPort
iptables -t nat -A "$POST" -p tcp -d $toHost --dport $toPort -j SNAT --to $SRC

$PRE and POST are actually destination-specific chains that I jump to from the PREROUTING and POSTROUTING chains respectively so I can keep the iptables clean. $SRC is the IP address I'm SNATing to which is different from the gateway IP $GW.

The problem with this setup is that regular routed packets that were not DNATed but happen to go to the same $toHost:$toPort combo will also be SNATed.

I wish to avoid this. Any clever things I can do?

share|improve this question
up vote 1 down vote accepted

Keep it simple: you don't actually need to SNAT anything. By doing this, every packet will reach the target server appearing to come from your firewall, rather than from the originating client, which in most cases is not what you want.

With the SNAT rule out of the way, you don't have to worry about it matching other traffic.

Note: Your FORWARD rules will have to match against the real source IP and the internal destination IP, since the FORWARD chain is reached after the DNAT rules are applied.


Given the requirement for SNAT: as long as you're happy with the way the DNAT rule is matching packets, then you can precede that with a mangle rule that marks those same packets:

iptables -t mangle -A <mangle chain> -p tcp -d $GW --dport $fromPort -j MARK --set-mark 0x1

Then all your SNAT rule has to do is match those marked packets:

iptables -t nat -A "$POST" -m mark --mark 0x1 -j SNAT --to $SRC

If you need to identify multiple, separate streams, you should be able to vary the mark in script along with $SRC.

share|improve this answer
Thanks, in general you're right but in this particular case I actually I do want to NAT ;-). The routing is for private subnets and the port NAT has to appear to come from within the private subnet. – w00t Jul 3 '12 at 20:10
Marking might server your purpose, then. I'll update my answer. – SmallClanger Jul 3 '12 at 21:40
Or I could combine the current SNAT rule with the mark right? Excellent, didn't know about marking! – w00t Jul 4 '12 at 6:26

Your Answer


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.