OpenWrt Forum Archive

Topic: Issues with port forwarding UDP on trunk/r49066 (DNAT vs REDIRECT)

The content of this topic has been archived on 9 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Edit: This post has been significantly changed since the original posting, trying to offer a lot more clarity.

Got an interesting challenge here related to port forwarding UDP on Trunk to the local router.  This started out rather complicated, but I've been able to cut pieces out to reduce complexity and here's what I'm looking at:

Default out-of-the-box trunk configuration on a WRT1900AC (no keep settings, etc.), OpenWrt Designated Driver r49066 / LuCI Master (git-16.081.38806-6b9a743), Kernel is 4.4.6 (build from yesterday, 3/22)

Running a lightweight server (think NCat) on UDP 444 on the OpenWRT router.  I'm trying to expose that server to the WAN interface via port 443 (again a simplified example, in reality the server is more substantial than NCat, but I've cut that piece out and been able to reproduce with NCat).

This Rule doesn't work:

firewall.@redirect[2]=redirect
firewall.@redirect[2].enabled='1'
firewall.@redirect[2].target='DNAT'
firewall.@redirect[2].src='wan'
firewall.@redirect[2].dest='lan'
firewall.@redirect[2].proto='udp'
firewall.@redirect[2].src_dport='443'
firewall.@redirect[2].dest_ip='192.168.1.1'
firewall.@redirect[2].dest_port='444'
firewall.@redirect[2].name='ExternalUDP1'

But this Rule does:

firewall.@redirect[3]=redirect
firewall.@redirect[3].enabled='1'
firewall.@redirect[3].target='DNAT'
firewall.@redirect[3].src='wan'
firewall.@redirect[3].dest='lan'
firewall.@redirect[3].proto='udp'
firewall.@redirect[3].src_dport='443'
firewall.@redirect[3].dest_port='444'
firewall.@redirect[3].name='ExternalUDP3'

The first rule emits a DNAT to the local device IP (192.168.1.1), while the second rule emits a redirect (maybe related to the change committed here: http://git.openwrt.org/?p=project/firew … b1da92eb6)

Hits on both rules (attempting to open the port) result in an increase in the hit count so I know it's registering the hit, but the DNAT rule that includes the device IP doesn't actually function (can't pass data over NCat, and my more advanced software also doesn't work) while the second REDIRECT rule with no destination IP does.

It's worth noting that this exact setup worked flawlessly on a trunk build from last spring, so I'm thinking something may have changed in the way UDP packets are handled which is causing drops to occur (Firewall3 updates here: http://git.openwrt.org/?p=project/firew … =summary).

At this point, I've got it working as a redirect, but I'd love to figure out if the failing DNAT rule is actually a result of something that is now broken, or understand if it's intended functionality for some reason.

Thanks

(Last edited by OperatorOverload on 23 Mar 2016, 22:10)

Why don't you just set the service to listen on the WAN interface, port 443? Port forwarding is normally used to expose devices that are behind NAT, the router isn't behind NAT, as it's the device doing NAT - so it can be exposed directly. I have OpenVPN listening on my WAN interface, and just have a rule to accept traffic:

firewall.@rule[11]=rule
firewall.@rule[11].target='ACCEPT'
firewall.@rule[11].src='wan'
firewall.@rule[11].dest_port='11443'
firewall.@rule[11].name='OpenVPN'
firewall.@rule[11].proto='udp'

Your second rule works because it takes traffic from WAN destined to port 443, and redirects it to port 444 on the same interface, i.e. WAN - where the listening service receives it. You could probably make the first rule work, you might want to look into enabling NAT loopback, although this isn't the typical application of NAT loopback. I'm not even sure this is a kind of loopback, I don't know what to call it really, besides very unusual.

Stepping back, is there a particular reason you need the service to listen only on the LAN interface of the router, and accept connections to the service from WAN? Or is this just what you thought you needed? I'm trying to determine if it's the firewall or the service architecture that needs to be fixed.

That's a fair question, but I'll say in this case my scenario is contrived a bit to simplify the results.  I've got a piece of software that can't be told what interface to listen on (listens on all always) running on port 443 already, so I want to pick up traffic incoming over the WAN and bump it over to 444.

The other interesting thing here is the same thing with TCP instead of UDP works in both iterations, so both of the following work flawlessly when NCat is listening on TCP instead.

firewall.@redirect[2]=redirect
firewall.@redirect[2].enabled='1'
firewall.@redirect[2].target='DNAT'
firewall.@redirect[2].src='wan'
firewall.@redirect[2].dest='lan'
firewall.@redirect[2].proto='tcp'
firewall.@redirect[2].src_dport='443'
firewall.@redirect[2].dest_ip='192.168.1.1'
firewall.@redirect[2].dest_port='444'
firewall.@redirect[2].name='ExternalUDP1'
firewall.@redirect[3]=redirect
firewall.@redirect[3].enabled='1'
firewall.@redirect[3].target='DNAT'
firewall.@redirect[3].src='wan'
firewall.@redirect[3].dest='lan'
firewall.@redirect[3].proto='tcp'
firewall.@redirect[3].src_dport='443'
firewall.@redirect[3].dest_port='444'
firewall.@redirect[3].name='ExternalUDP3

Regardless of whether this is the best way to do it (and in fact it might not be), the fact that it works on TCP but not UDP points to one of two seemingly being true:
1. Either I don't understand something about the way UDP operates that makes it inherently different for this, in which case I'd like to learn.  The odd thing here is both methods (DNAT and REDIRECT) work in a build from last Spring, so I'm leaning more to...

2. Something has changed with respect to UDP functionality in this case which worked differently last Spring (the production build I've been running dates to then).  Note I said changed, not necessarily broken, but I'm trying to understand what changed and ultimately whether it is correct.

So I'll say definitely not trying to defend the service architecture (agree with you there is a better way to do it, and I'm working on improving the software in question to make that possible), but I would really like to understand why what's happening is happening.  Appreciate the response and the guidance thus far.

Hi, just to say I'm having the same problem where UDP port-forwards to the router's LAN interface fail to work on OpenWrt 15.05 and OpenWrt 15.05.1 but TCP port-forwards are fine. This bug report talks about the issue: https://dev.openwrt.org/ticket/18057

Apparently the change in the firewall3 package that broke this functionality has been reverted but the fix happened after the 15.05.x CC release.

The discussion might have continued from here.