I'm trying to use iptables to:
- Mark packets going to a destination IP
- Detect that mark to change the destination IP
- Detect that mark to change the source IP
These are the commands I'm trying to use to achieve that:
sudo iptables -t mangle -A PREROUTING --destination 192.0.2.0 -j MARK --set-mark 11
sudo iptables -t nat -A PREROUTING -m mark --mark 11 -j DNAT --to-destination ${DESTINATION_IP}
sudo iptables -t nat -A POSTROUTING -m mark --mark 11 -j SNAT --to-source ${SOURCE_IP}
It looks like the first MARK command is not picking up any packets to mark them:
sudo iptables -vL -t mangle
Chain PREROUTING (policy ACCEPT 11892 packets, 1184K bytes)
pkts bytes target prot opt in out source destination
0 0 MARK all -- any any anywhere 192.0.2.0 MARK set 0xb
After that the later rules do not see any marked packets to modify.
Am I right in thinking that pkts
being 0
for that rule means it hasn't matched any packets?
How should I be marking packets to later identify and modify?
Best Answer
Local-originated packets don't pass through
PREROUTING
chain, but throughOUTPUT
. So, if you try to test your rules from the same host, you should add theMARK
rule intomangle/OUTPUT
chain and theDNAT
rule intonat/OUTPUT
chain.In result your rules will look like:
Also, there is a way to avoid marking and refer to the original (before translation) addresses and port numbers.
To get the options list of an iptables match or an iptables target you can use brief built-in help. For example:
When you troubleshoot nat rules, you should know only first packet of new connection passes the
nat
table.Other tools to troubleshoot issues are the
tcpdump
and theconntrack
.