xmlhttpsoapupnpportforwarding

Is it possible to map a port using UPnP, with SOAP, to bind to a local port where my http server is listening?


Say, I'm behind a router at 192.168.0.1, which leads to external ip which is 192.168.1.64 (a dsl modem) which leads to a public internet address.

Is it possible using uPnP, via SOAP requests to gateway, to map my http server port local to an arbitrary port at that public internet address?

Sorry, I'm totally newbie on this matters. I'm testing using Putty on port 80 on gateway, issueing http with xml.

POST /upnp/control3 HTTP/1.1 Cache-Control: no-cache Connection: Close Pragma: no-cache Content-Type: text/xml; charset="utf-8" User-Agent: Microsoft-Windows/6.1 UPnP/1.0 SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" ... ..

Thanks.


Solution

  • You can see a good example as part of the Coherence DNLA/UPnP framework in a Python module called "Puncher" ("punches" holes in your firewall, duh! :o) which can create port mappings of external ports (like port 8080) to internal ports of your choosing:

    https://gitlab.digitalcourage.de/coherence/puncher/-/blob/develop/puncher/base.py

    The Coherence modules are also available on Debian as the python-coherence package. On Windows as well if you use ActiveState Python.

    I am assuming you want to do this automatically/programmatically as part of something you are creating, which is why I pointed you to the above

    Coherence DNLA/UPnP framework in Python

    If you just want to do this as a one-off manually, there are some excellent command-line and GUI tools to create UPnP port mappings. On Macs, a manual GUI tool is available at Port Map and TCMPortMapper from the creators of SubEtha Edit. On Windows, a manual GUI tool is available at Deusty: UPnP and NAT-PMP PortMapper for Windows.

    I would strongly recommend you play with Coherence in Python, it can be a fun programming experience. Alternatively, many different programs that use the network will have UPnP modules to open up ports and forward/map them to your local machine. For example, µTorrent has one, as does libtorrent/rtorrent, as do many others.

    See also the following libraries, examples, and tools with UPnP client implementations to programmatically forward/map ports on your router, if you are averse to Python (these are in C and Perl):

    Note that the second link, upnp.c in trunk/libtransmission – Transmission, is code from the popular BitTorrent client "Transmission" which uses the miniupnp library (first link).

    I hope this has answered your question. Best of luck with whatever you're doing.

    EDIT: @kaneda: In response to your comment, you are behind two NATs, one by your DSL modem and one by your wireless router, if I understand you correctly. Simple UPnP will not help you here, you need to either be able to UPnP a port mapping on both the DSL modem and the router (probably impossible since your router probably won't let UPnP requests leave its WAN port), OR set either your DSL modem or your router to bridge rather than NAT, so that you are only behind one NAT.

    EDIT 2: @kaneda: Another possible way around the double NATting is to replace your router with a Linux box (such as by using OpenWRT or similar) and to run your upnp code on there to forward the DSL modem port, then also run the miniupnp-based code on your host behind the router to further open the router. At that point, however, since you have control of the router you might as well just create a static port mapping and have it pass-through all UPNP protocol requests to the DSL modem (by telling iptables to selectively forward/NAT those packets back/forth, which is beyond the scope of this answer).