2

I am trying to do dnat using iptables like below

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

Is it possible to mention output interface also using iptables or routing table is the only way?

2 Answers 2

4

It's not possible to do this, as the command would tell (Can't use -o with PREROUTING), and here's the reason:

  • DNAT happens in nat/PREROUTING, and as the name implies, before the routing decision.
  • before the routing decision, the routing stack hasn't been used to determine what will be the output interface (if it's not the host itself, where iptables' filters won't have an output interface at all). So this information is not available to nat/PREROUTING and that's why it's not allowed to specify an output interface: you can't match (meta-)data you don't have.

Here's a schematic explaining how it's working:

Packet flow in Netfilter and General Networking

The routing decision is never done by netfilter or iptables, but by the routing stack. So for specific routing, the routing stack (ip route ...) must be used. Sometimes you can nudge the routing stack in the right direction by setting marks on packets with iptables, if it can't be done without it. But the routing part can become quite tricky then.

If you have specific needs, these needs should be asked in the question: the question should also explain why and not only how you want to do this, to avoid an XY problem.

2
  • for example you can use the original destination IP instead (this would be useful if the DNAT system is already routing such traffic and is doing this for a kind of transparent proxy). But without telling why the output interface was thought to be needed it's a bit difficult to guess.
    – A.B
    Commented May 31, 2020 at 16:33
  • This is possible with nft btw, using FIB EXPRESSIONS. Something like nft add rule ip mytable mynatprerouting iif eth0 fib daddr oif eth2 tcp dport 9000 dnat to 10.0.0.1:9000 which would perform the dnat only if the packet would have initially been routed through eth2 (and because of this rule can be routed elsewhere). This happens before the routing decision, but queries the routing stack to ask the information: this requires a specific (kernel) nftables module. As usual in nat, the whole flow will be affected.
    – A.B
    Commented Jun 28, 2021 at 10:51
-1

seems that you cant

 iptables -t nat -A PREROUTING -i eth0 -o eth0 -p tcp --dport 9000 -j DNAT --to-destination 10.0.0.1:9000
 iptables v1.8.4 (nf_tables): Can't use -o with PREROUTING

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .