0

I have, among others, the following iptables NAT rules on the machine with IP addresses 192.168.1.71 and a.b.c.d, where a.b.c.d represents a public IP address:

 iptables -t nat -A PREROUTING -p udp --dport 20001 -j DNAT --to-destination 192.168.1.72:20000
 iptables -t nat -A POSTROUTING -p udp -s 192.168.1.72 --sport 20000 -j SNAT --to-source a.b.c.d:20001

When, thru STUN, I try to find the public IP address assigned to the socket with local port 20000 on local machine 192.168.1.72, I do not get 20001, I consistently get 32018. I, however, do get the correct IP address a.b.c.d. What do I need to change in my iptables rules?

UPDATE: The problem was in my computation of the port number from the STUN response. Related question: The rule:

   iptables -A INPUT -p udp -j LOG --log-prefix "iptables: "

does not log the packets for matched packets but does log for other packets. Placing this rule above or below the above two rules did not make a difference.

asinix
  • 125
  • 6
  • Do you mean: "I try to find the public port assigned to the socket?" Is the first UDP packet always sent from inside your network or from a host in public internet? – Tero Kilkanen Jun 08 '20 at 19:46
  • @TeroKilkanen The first UDP packet is always sent from inside the network not from the host in public internet. – asinix Jun 09 '20 at 01:35
  • @TeroKilkanen ...The first packet is a STUN binding request sent from inside the network. – asinix Jun 09 '20 at 02:07
  • @TeroKilkanen There is nothing wrong in the iptables rules. The problem was in my computation of port number from the STUN response. Thanks for taking the time to look into this. – asinix Jun 09 '20 at 03:52
  • 2
    If the first packet is always sent from inside the network, then you only need rule in `POSTROUTING`. Linux connection tracking automatically handles the reverse direction. – Tero Kilkanen Jun 09 '20 at 06:20
  • @TeroKilkanen I was under the impression that the PREROUTING rule was not necessary for TCP (connection-oriented protocol) but I will try without it for UDP. – asinix Jun 09 '20 at 07:32
  • @TeroKilkanen I know this is a different question but the rule: iptables -A INPUT -p udp -j LOG --log-prefix "iptables: " does not make entries for matching packets. The rule is after the above two rules. Placing it before does not log either. If you post your above comment and answer to this query, I would like to accept that as an answer. I have updated the question too. – asinix Jun 09 '20 at 07:35

2 Answers2

1

If the first packet is always sent from inside the network, then you only need rule in POSTROUTING. Linux connection tracking also handles UDP "associations", so it knows how to handle return packets.

For example, DNS over UDP reply packets are relayed to clients behind NAT using Linux connection tracking.

Your LOG rule is put into the INPUT chain in filter table, which is used only for packets where destination is the router itself. The packets handled by PREROUTING / POSTROUTING chains never go to INPUT chain.

Your rules should look like:

iptables -t nat -A POSTROUTING -p udp -j LOG --log-prefix "iptables: "
iptables -t nat -A POSTROUTING -p udp -s 192.168.1.72 --sport 20000 -j SNAT --to-source a.b.c.d:20001

https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg is a comprehensive image how packets flow inside Linux network stack and different IPTables chains / tables.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • Any thoughts on eBPF and its use as a packet filtering/forwarding use? Do you see considerable benefit for use of about 400 NATed ports for realtime communication on a machine? I know this is an unrelated question but it is too short to warrant a new question. Just a quick answer will suffice – asinix Jun 10 '20 at 15:32
  • 1
    I don't have any experience on using eBPF for this kind of purpose, but I guess it could be useful to make forwarding more efficient. – Tero Kilkanen Jun 10 '20 at 15:42
0

I have a quite similar issue with UDP DNAT. In my case, connections are supposed to be initiated from the public internet towards a server. On the server I have a first Linux bridge (with a physical NIC member).

My netfilter rule on the host (a proxmox server) DNAT the UDP port 500 to a second Linux bridge (having a tap NIC member). The tap NIC actually belongs to a VM (an IPsec server). Routing are configured properly (ip forwarding is enabled, netfilter allows all FORWARD packets in any directions...). What is very strange is that similar rules works for TCP connections. For instance I have an OCSP server in the same VM and DNAT works perfectly.

What is even more strange is that if I establish a TCP connection forwarded to any Linux bridge on the host, suddenly UDP DNAT begins to work... But not for ever (just for a while).

What's going on with Linux bridges? Any help would be greatly appreciated.

Regards,

I answer to myself : actually the problem was coming from my testing tool. I was using nmap, but maybe with wrong arguments. I replaced it by netcat and noticed that there is no issues in my configuration :) The netcat command that I used to check the UDP 500 port is:

nc -vz -u <my-public-ip> 500
bugybugy
  • 1
  • 2
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://serverfault.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://serverfault.com/help/whats-reputation), you can also [add a bounty](https://serverfault.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/546864) – fission Mar 24 '23 at 07:10
  • You are right ! It doesn't but it's a similar issue and the solution to the two issues could be the same. By exposing similar issues that are highly bound each to other, the 'brain' may creates connections and therefore the solution ca rises! That's how IT people works... Are you a netfilter expert to write such a comment? – bugybugy Mar 25 '23 at 09:06