The following will redirect anything going from client1:port1
to server:ports
to be delivered to the client2:port2
, where it appears as coming from the server:ports
:
iptables -t nat -A PREROUTING -p udp -s client1 --sport port1 -d server --dport ports -j DNAT --to-destination client2:port2
iptables -t nat -A POSTROUTING -p udp -s client1 --sport port1 -d client2 --dport port2 -j SNAT --to-source server:ports
The first rule changes the destination from server:ports
to client2:port2
(because it is DNAT
rule), the second rule changes the source from client1:port1
to server:ports
. By the time packet is going through second rule, it has the destination already changed, but source isn't, so the matches in the rule might look strange. Replies will undergo the reverse translation automatically.
If you want conversations initiated on client2 (not replies) to work similarly, you need to add the mirror rules:
iptables -t nat -A PREROUTING -p udp -s client2 --sport port2 -d server --dport ports -j DNAT --to-destination client1:port1
iptables -t nat -A POSTROUTING -p udp -s client2 --sport port2 -d client1 --dport port1 -j SNAT --to-source server:ports
If server has any filtering, you'll need to add rules permitting forwarded packets to pass:
iptables -t filter -A FORWARD -p udp -s client1 --sport port1 -d client2 --dport port2 -j ACCEPT
iptables -t filter -A FORWARD -p udp -s client2 --sport port2 -d client1 --dport port1 -j ACCEPT
Addresses appear half-translated here too, because the packets always traverse the firewall in the following order: PREROUTING
, FORWARD
, POSTROUTING
.
Now the client1 will be in the full confidence that it talks with server:ports
(at least, on the network level; of course packets could contain something that hints on who is really answering). The same is true for client2, who'll be sure that it talks with server:ports
.
Also remember, that once the conversation had begun, the firewall remembers its state; the removal or addition of rules won't have any immediate effect on established connections, because the nat
table is always traversed only by the first packet in the connection; the result of the translation is stored in the state table which is used to translate replies and subsequent packets. That state table could be seen by cat /proc/net/nf_conntrack
or using utilities from the conntrack-tools
package. In case of UDP, the "connection" is defined by the addresses, ports and timeout in the conversation, and "ends" when no packet is seen in any direction for a certain amount of time, 30 seconds by default.
I also want to state this in clear: the forwarding or routing is never performed by the iptables. The routing and forwarding will be performed regardless of any iptables rules in place, according to the routing policy database rules and routing tables contents. It is simply incorrect to say "iptables's ip forwarding", as iptables only sets translations. It configures the in-kernel firewall filtering rules and network address and port translation rules, e.g. how the kernel will change addresses in packets, which apparently could influence its routing decisions (because routing decisions are based on addresses).