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?
It's not possible to do this, as the command would tell (Can't use -o with PREROUTING
), and here's the reason:
Here's a schematic explaining how it's working:
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.
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.
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