1

I'm working on an application that should relay udp packets from one host to another according to some rules. It is basically NAT.

I negotiate UDP ports with both hosts and after that I need to receive from host A and send to host B with the negotiated ports.

So i'm dinamically adding and removing iptables rules.

# my address is 10.1.1.1
# A is 10.10.10.10:30590 - 10.1.1.1:36232 
# B is 10.20.20.20:30588 - 10.1.1.1:36230 

# A to B
iptables -t nat -A PREROUTING -s 10.10.10.10/32 -i eth0 -p udp -m udp --sport 30590 -j DNAT --to-destination 10.20.20.20:30588
iptables -t nat -A POSTROUTING -d 10.20.20.20/32 -p udp -m udp --dport 30588 -j SNAT --to-source 10.1.1.1:36232

# B to A
iptables -t nat -A PREROUTING -s 10.20.20.20/32 -i eth0 -p udp -m udp --sport 30588 -j DNAT --to-destination 10.10.10.10:30590
iptables -t nat -A POSTROUTING -d 10.10.10.10/32 -p udp -m udp --dport 30590 -j SNAT --to-source 10.1.1.1:36230

And this works most of the time, however, sometimes the first packets start to arrive before the rules are added. Clearing UDP "connections" makes the rules work ( conntrack -D -p udp ).

I've triyed to disable connection tracking using rules like:

iptables -t raw -A PREROUTING -j NOTRACK
iptables -t raw -A OUTPUT -j NOTRACK

# or 
iptables -t raw -A PREROUTING -j CT --notrack
iptables -t raw -A OUTPUT -j CT --notrack

But none of these seem to work.

Will the only solution be to clear the UDP connection tracking for every stream?

I need to support thousands of concurrent streams, and several being added and removed every second.

2

Disabling connection tracking is not suitable as NAT depends on connection tracking, so NAT will stop working.

You must clear any relevant existing connection tracking records after the NAT rules are inserted, so that any subsequent arriving packets will check the nat table for the new DNAT/SNAT rules instead of just looking up the 'cached' result.

However, you can target it to be more specific than conntrack -D -p udp which affects all udp connection tracking records; for example, conntrack -D -p udp --src <ip> --sport <port> --dst <ip> --dport <port> would let only clear records for the specific src/dst ip and port pairs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.