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?
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 theFORWARD
chain is reached after theDNAT
rules are applied.EDIT
Given the requirement for
SNAT
: as long as you're happy with the way theDNAT
rule is matching packets, then you can precede that with amangle
rule that marks those same packets:Then all your
SNAT
rule has to do is match those marked packets:If you need to identify multiple, separate streams, you should be able to vary the mark in script along with
$SRC
.