I've developed an application that is essentially just a little ftp server with the ability to specify which directory you wish to share on startup. I'm using ftplib for the server because it's sick easy. The only issue I'm having is that if you are behind a router you have to manually forward the ports on your router and I'm finding that it's a little too complicated for my users (aka co-workers/clients).
So I've been looking for a simple solution to open ports but I'm finding that most APIs are too broad and way over my head. Does someone know of a solution that would be relatively simple to implement?
Note: It will really only be used on windows although cross-platform compatibility would be welcomed. If there is a windows only solution that is simpler then I would opt for that.
Thanks!
Universal Plug and Play (UPnP) is a network protocol that allows compliant devices to automatically set port forwarding rules for themselves. These devices can be personal computers, printers, security cameras, game consoles or mobile devices that communicate with each other and share data over your network.
UPnP, therefore, is not inherently dangerous if your router is up to date and has all the latest firmware updates, and your connected devices are free of malware. UPnP becomes an issue if a connected device is infected with malware, as it can spread to your local devices.
UPnP (Universal Plug and Play) is a networking protocol that enables devices to discover each other and connect without the need for manual configuration or user intervention. The protocol automates all the steps necessary for recognition and communication between devices on the same network.
Simple example for miniupnp. It creates a mapping on the discovered gateway from external port 43210 to the interface connected to port 43210 on the interface connected to the discovered gateway.
import miniupnpc
upnp = miniupnpc.UPnP()
upnp.discoverdelay = 10
upnp.discover()
upnp.selectigd()
port = 43210
# addportmapping(external-port, protocol, internal-host, internal-port, description, remote-host)
upnp.addportmapping(port, 'TCP', upnp.lanaddr, port, 'testing', '')
The protocol you want is called IGD (for Internet Gateway Device) and is based on UPNP. It allows a client program (yours) to discover the router on the network (using UPNP) and then ask it to forward a specific port.
This is supported by most home routers, and the technique is used by a lot of services like BitTorrent or multiPlayer games, bit it's a bit complicated to use or implement. There are several open source libraries that support IGD and one of the simplest one (which is also cross-platform) is "miniupnp": see http://miniupnp.free.fr/
Looks like there are a few options, one being miniupnp. There are also python bindings for GNUPnP here. For windows minupnp will work, or you could go pure python with miranda-upnp.
There is a nice example of the python GNUPnP bindings being used to open ports on a router here. In that example the lease time is set to 0, which is unlimited. See here for the definition of add_port.
A simple example might be:
#! /usr/bin/python
import gupnp.igd
import glib
from sys import stderr
my_ip = YOUR_IP
igd = gupnp.igd.Simple()
igd.external_ip = None
main = glib.MainLoop()
def mep(igd, proto, eip, erip, port, localip, lport, msg):
if port == 80:
igd.external_ip = eip
main.quit()
def emp(igd, err, proto, ep, lip, lp, msg):
print >> stderr, "ERR"
print >> stderr, err, proto, ep, lip, lp, msg
main.quit()
igd.connect("mapped-external-port", mep)
igd.connect("error-mapping-port", emp)
#igd.add_port("PROTO", EXTERNAL_PORT, INTERNAL_IP, INTERNAL_PORT, LEASE_DURATION_IN_SECONDS, "NAME")
igd.add_port("TCP", 80, my_ip, 8080, 86400, "web")
main.run()
There is an article explaining how to use the Windows IGD COM object with win32com.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With