UPnP says it's working (not really)

I’ve enabled the UPnP service here:

When I launch my client, I can see new entries appear on the “Active UPnP Redirects” list, with the correct IPs and ports. These entries disappear when I close my client, which is good also.

But my client still reports that the port is closed. UPnP says it’s working, but my client thinks it’s not. (I’ve got a different OpenWRT router where this works fine.)

Underwhelming status update: I gave this another try a few days later and … it’s working now? No system changes? That was weird.

Having the same problem.

if you look in the logs (/var/log/messages file) you probably have errors like:

2017-01-22T18:36:06-08:00 err miniupnpd[12848]: PCP MAP: failed to add mapping UDP 5354-> 'PCP MAP 010cc91661b2541f1bbe9b04'
2017-01-22T18:36:06-08:00 err miniupnpd[12848]: addmasqueraderule() : chain MINIUPNPD-POSTROUTING not found
2017-01-22T18:36:06-08:00 notice miniupnpd[12848]: add_redirect_rule2(): addmasqueraderule returned -1

In English what’s going on here is that miniupnpd (which manages upnp on OpenWRT) is complaining that one of the firewall chains it’s expecting to use is not present. How upnp is implemented is that the holes in the firewall are opened by the clients, and then the traffic coming into those opened holes is mapped to the ports that the clients expect to see the traffic on. this particular firewall chain is used by miniupnpd to do the mapping. So without this piece, although the mappings seem to appear in the UI, the traffic isn’t going to the actual clients because not all of the required firewall rules are in place.

Based on an idea from this post I modified /etc/init.d/miniupnpd to add the required firewall chain before miniupnpd is started up, and remove it when it’s shut down. The changes are here:

After " # start firewall " add:

iptables -t nat -A POSTROUTING -o "$ifname" -j MINIUPNPD-POSTROUTING

and after “iptables -t filter -F MINIUPNPD 2>/dev/null” in the stop() section of the script add

iptables -t nat -D POSTROUTING -o "$ifname" -j MINIUPNPD-POSTROUTING

Please back up your old /etc/init.d/miniupnpd before trying this. After I made the changes UPnP worked consistently for me.

I’m going to try to log a bug with the Turris folks to get the change merged.

A potentially better place to add these rules might be in /usr/share/miniupnpd/firewall.include, but I’m trying to understand how that script works before adding there. It looks like these rules are missing there and the other miniupnpd rules are built there.

The OpenWRT developers eventually did fix this more cleanly in /usr/share/miniupnpd/firewall.include. Looking here they modified that file to add the lines

iptables -t nat -N MINIUPNPD-POSTROUTING 2>/dev/null

at the top of the file and

iptables -t nat -I zone_${ext_zone}_postrouting -j MINIUPNPD-POSTROUTING

in the add_extzone_rules() section. This change was made by them last July. This is cleaner than what I was trying to do and has the same effect, so I’d recommend fixing it that way rather than changing /etc/init.d/miniupnpd.

1 Like

Nice debugging :thumbsup: Integrated into nightly, will be part of next big release.