IN SHORT: I need a port redirection on a connection-oriented protocol, just like it would be for TCP – but I need that it work for UDP. I have a custom connection-oriented protocol using UDP for transport.
In particular:
- The machine to be configured is listening on port 5005 UDP.
- UDP packets are expected to come from, say, 10.1.2.10.
- This machine should forward this packet to, say, 10.1.2.20 port 5010.
- … and the other way around!
For 4, more precisely: when a packet comes from 10.1.2.10, it is assigned a random port, say, 52000. Then, THIS machine receives packet on UDP port 5005 and forwards it to 10.1.2.20:5010 having also some randomly-selected source port, say, 52001. Now, when there's coming a packet from 10.1.2.20 port 5010 to THIS machine port 52001, it should redirect it also to 10.1.2.10 port 52000.
Moreover, if there's coming a packet from another port on 10.1.2.10, the port assignment and according rule for reverse-direction packet redirection should apply as well. It may be set 10s timeout for any traffic, after which the backward track rule is removed.
If this cannot be done using iptables, I'm fine with it – I'll fall back to a userspace solution. But with iptables it will simplify the deployment.
Best Answer
Your proxy server is thus doing a double NAT, masquerading (by hiding the other real peer) both ways.
It has to be configured as a router on its (single) interface or nothing will be forwarded. Let's say the interface name is eth0, and its IP is 10.1.2.50:
Now because of the double NAT, the transformations in
PREROUTING
and/orPOSTROUTING
prevent matching the flow just using again the same filter. So inPREROUTING
aCONNMARK
is used to mark the flow which can then be reused immediately inPREROUTING
(and avoiding duplicating the specific test for easier management) and later inPOSTROUTING
. Note-p udp
is still needed because we askSNAT
and/orDNAT
to alter UDP ports. After that conntrack will handle all future exchange, as long as it doesn't time out (usually 30s for first reply, then 3mn)If it's really a requirement that you also alter the source port, instead of having conntrack do it only when needed, change the 3rd rule into:
(usual range taken from
/proc/sys/net/ipv4/ip_local_port_range
, and--random-fully
is needed else nothing is done because the original port is already in range).You could also change
SNAT
toMASQUERADE
(and not have to state server IP) but only--random
is available.UPDATE: while the above rules work as intended, usually the
connmark
match and theCONNMARK
target are intended for interaction withmark
andMARK
for a more complex usage as described in this blog. They are not needed for the simple usage here. Simply replace them all with resp.mark
andMARK
. Here netfilter's connection tracking already takes care of the flow once the first packet is handled (creating a conntrack entry inNEW
state) without having to ask it to mark it in the conntrack entry. A mark is just put in the (first) packet (thenat
table sees only packets inNEW
state):Example captures, including errors (service not running etc.):
Please note that, you can replace all of this with this simple socat line (and you don't get any 30s/3mn timeout but you lose ICMP handling):