UPnP port forwarding not working for Windows 10 and Xbox One

I can't get UPnP port forwarding to work properly with Windows 10 or Xbox and OpenWrt 19.07.6 on x86.

Torrenting apps and basic UPnP test programs such as UPnP Wizard work fine, as does Demonware (e.g. for Call of Duty on the Xbox), but UPnP is not working for Xbox live in Windows 10 and on the Xbox - the port forwards never appear in the list of leases.

I've only become aware of this recently, so I'm not sure exactly when it broke, but it was definitely working with miniupnpd 2.1 in 18.0.6 before I upgraded to 19.0.7 (miniupnpd 2.2) a couple of months ago.

I've tried looking at the detailed UPnP logs and packet captures, but I don't really know what I'm looking at :confused:

Does anyone have any ideas about what might be happening, or how I would debug further?

My upnpd config file looks like this:

config upnpd 'config'
        option external_iface 'wan'
        option internal_iface 'lan'
        option port '5000'
        option upnp_lease_file '/var/run/miniupnpd.leases'
        option ext_ip_reserved_ignore '1'
        option enabled '1'
        option uuid 'd5a0cc33-1455-4e1e-ab05-1dc0fd725649'
        option download '1024'
        option upload '512'
        option ipv6_disable '1'
        option serial_number '12345678'
        option model_number 'Q350G4'
        option igdv1 '1'
        option log_output '1'

config perm_rule
        option action 'allow'
        option ext_ports '1024-65535'
        option int_addr '0.0.0.0/0'
        option int_ports '1024-65535'
        option comment 'Allow high ports'

config perm_rule
        option action 'deny'
        option ext_ports '0-65535'
        option int_addr '0.0.0.0/0'
        option int_ports '0-65535'
        option comment 'Default deny'

When I run netsh interface Teredo show state on the Windows machine it reports that UPnP is not available under "NAT Special Behaviour":

Teredo Parameters
---------------------------------------------
Type                    : natawareclient
Server Name             : win1910.ipv6.microsoft.com.
Client Refresh Interval : 20 seconds
Client Port             : unspecified
State                   : qualified
Client Type             : teredo client
Network                 : unmanaged
NAT                     : restricted (port)
NAT Special Behaviour   : UPNP: No, PortPreserving: Yes
Local Mapping           : 192.168.111.229:60416
External NAT Mapping    : [My WAN IP]:60416

I may not be alone. A couple of others have posted similar reports recently:

As far as I can tell by looking at the logs, the Windows machine / Xbox never make any attempt to create the port forward - i.e. there's no AddPortMapping request or similar in the logs, unlike the successful operations with UPnP Wizard.

I can see them retrieving various bits of XML from the router, but it seems that they're not happy with the contents somehow. :thinking:

I built the plugin from updated source from the miniupnpd master repo and have had bugs also.

With the updated source It asks to create mappings and fails with error 501 not just with xbox but also from qbtorrent on my PC, the latest build has a lot more debug info and suggested fixes in the log.

All worked with v18 of openwrt just seems to be an issue with v19 and above.

Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: HTTP REQUEST from [::ffff:192.168.2.189]:57346 : GET /rootDesc.xml (HTTP/1.1)
Thu Jan 21 20:34:51 2021 daemon.debug miniupnpd[6386]: Host: 192.168.2.1:5000
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: HTTP REQUEST from [::ffff:192.168.2.189]:57347 : POST /ctl/IPConn (HTTP/1.1)
Thu Jan 21 20:34:51 2021 daemon.debug miniupnpd[6386]: Host: 192.168.2.1:5000
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: SOAPAction: urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: HTTP REQUEST from [::ffff:192.168.2.189]:57348 : POST /ctl/IPConn (HTTP/1.1)
Thu Jan 21 20:34:51 2021 daemon.debug miniupnpd[6386]: Host: 192.168.2.1:5000
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: SOAPAction: urn:schemas-upnp-org:service:WANIPConnection:1#GetSpecificPortMappingEntry
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: Returning UPnPError 714: NoSuchEntryInArray
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: HTTP REQUEST from [::ffff:192.168.2.189]:57349 : POST /ctl/IPConn (HTTP/1.1)
Thu Jan 21 20:34:51 2021 daemon.debug miniupnpd[6386]: Host: 192.168.2.1:5000
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: SOAPAction: urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: AddPortMapping: ext port 3076 to 192.168.2.189:3076 protocol UDP for: DemonwarePortMapping leaseduration=604800 rhost=
Thu Jan 21 20:34:51 2021 daemon.debug miniupnpd[6386]: UPnP permission rule 0 matched : port mapping accepted
Thu Jan 21 20:34:51 2021 daemon.debug miniupnpd[6386]: Check protocol udp for port 3076 on ext_if eth1 192.168.1.130, 8201A8C0
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: redirecting port 3076 to 192.168.2.189:3076 protocol UDP for: DemonwarePortMapping
Thu Jan 21 20:34:51 2021 daemon.info miniupnpd[6386]: Returning UPnPError 501: ActionFailed

You need to build miniupnpd without IGDv2 support. Unfortunately the runtime option force_igd_desc_v1=yes is not enough. See https://github.com/stintel/openwrt-packages/commit/c3adabe8e44cfc52b6f5fd5557410bbce33f37f9 - you don't need the --debug flag, just drop --igd2.

I can confirm that compiling from the latest miniupnpd source without --igd2 solves the problem for me also.

This obviously isn't a satisfactory long term solution though. I don't want to be compiling miniupnpd myself from now on :slight_smile:

How do we get this investigated properly? Raise an issue here?

It is going to be difficult to keep all users of miniupnpd satisfied. The default with IGDv2 makes sense, as we want to support the latest and greatest. We could make this configurable with a menuconfig option, like https://github.com/openwrt/openwrt/blob/master/package/network/services/lldpd/Config.in#L4, but we would still default to IGDv2, so you'd have to build your own OpenWrt image, as the package built by the buildbot will have IGDv2 enabled, so we're still not able to satisfy all miniupnpd users.

I see two other options:

  • introduce a runtime option in miniupnpd that allows to fully disable IGDv2, and ideally this should be configurable per host or subnet, analog to the permission rules
  • have 2 variants in OpenWrt: miniupnpd-igdv1 and miniupnpd-igdv2, with a virtual package miniupnpd that is satisfied by either, and by default pulls in miniupnpd-igdv2

While I prefer the first option, the second one is probably much easier.

While I prefer the first option, the second one is probably much easier.

Agreed.

WDYT? https://github.com/stintel/openwrt-packages/commit/3e0bf33140d7934df4c447ccca8a53bc60b4ba47

I don't think I'm really qualified to do a proper review, but the parts I understand look sensible. So we'd end up with two packages:

  • miniupnpd
  • miniupnpd-igdv1

Both of which will work with packages that have a dependency on miniupnpd (e.g. luci-app-upnp).

I don't really understand how and when patches flow through to the current OpenWrt release. Would these patches ever be made available for 19.0.7?

I noticed when compiling my own version earlier that miniupnpd now depends on libcap-ng, which doesn't seem to be available in the 19.0.7 repo (I had to compile that as well). That change was made last June but it doesn't seem to have made it into the 19.0.7 packages yet.

I'd suggest raising it upstream https://github.com/miniupnp/miniupnp

I opened a PR: https://github.com/openwrt/packages/pull/14656
It would be nice if you could test it and comment on the PR that it works for you.

It seems that this package doesn't have a maintainer, but previous changes from master have been merged to openwrt-19.07. It also doesn't really change the miniupnpd package, it just introduces a new one, so I think there's little chance for regressions in the existing package.

I've patched the miniupnpd Makefile with your changes, but I can't work out how to build the IGDv1 variant. I assume it's not working for me because miniupnpd-igdv1 isn't in the package feeds?

Hmm. I just checked and miniupnpd-igdv1 is in the package feed.

But when I run:

make V=s package/miniupnpd-igdv1/compile

It fails with:

make[1]: *** No rule to make target 'package/miniupnpd-igdv1/compile'. Stop.

EDIT: Figured it out. I had to run make menuconfig again (after patching the Makefile), and select miniupnpd-igdv1.

Indeed, you need to have this in your .config:

CONFIG_PACKAGE_miniupnpd-igdv1=y

I tested the new miniupnpd-igdv1 package created by your patch, and it works.

1 Like

Sorry to hijack the discussion, but I've recently decided to have a go at UPnP because I simply didn't want to open 20 ports each time I wanted to use a certain application for a few minutes, but by trial and error found out it simply doesn't work (19.07.5). I haven't found enough information how to get this to work, even if I had to compile the package myself (just that I have no idea how do I do this, especially with OWRT). I am using LuCi, but can hop into SSH and FTP if needed.
Any help would be appreciated as that would save me quite a lot of time.

What platform are you running OpenWrt on? I still have the environment that I used to build my package, so I can try to build one for you if you like?

I have a Archer C6 v2 router (CPU: Qualcomm Atheros QCA956X), so I assume it to be ath79? It also seems to say that in the techdata page (Target: ath79). I hope that is what you meant and needed.

Ok, I've built libcap-ng and miniupnpd-igdv1 packages based on this info. I have no way of testing them, so I obviously can't guarantee that they'll work correctly.

The ipk files are here:

libpcap-ng
miniupnpd-igdv1

The easiest way to install them would be to ssh into your router and download them there before installing them. For example:

opkg update
opkg install wget

cd /tmp

wget -O libpcap-ng.ipk https://www.dropbox.com/s/u058jrx61fjnz7u/libcap-ng_0.8.1-1_mips_24kc.ipk?dl=1
opkg install libpcap-ng.ipk
rm libpcap-ng.ipk

opkg remove miniupnpd
wget -O miniupnpd-igdv1.ipk https://www.dropbox.com/s/qb1nhwjm56mfdel/miniupnpd-igdv1_2.2.1-1_mips_24kc.ipk?dl=1
opkg install miniupnpd-igdv1.ipk
rm miniupnpd-igdv1.ipk