~/Blog

Brandon Rozek

Photo of Brandon Rozek

PhD Student @ RPI studying Automated Reasoning in AI and Linux Enthusiast.

Temporary Port Forward using UPnP in Linux

Published on

3 minute reading time

I don’t know about you, but I don’t particularly enjoy logging onto my router. Especially since the web UI differs between router models. Unfortunately, a common step of hosting a multiplayer game server at home is to set up a port forward.

This tells your router to take traffic coming in at a specified external port, and forward it to one of your computer’s internal IP address at a specified local port.

Port Forward Diagram

What if I tell you that instead of having to login to your router interface every time you want to set up a port forward, you can programatically perform it from your Linux machine? This is where Universal Plug and Play (UPnP) comes in. Some games even automatically manage this for you!

Since router configurations vary widely, we’ll assume that you already have UPnP enabled. Not all routers, however, support this. Look up the model of your router with UPnP to see if yours does. For example, here’s how to set it up within pfSense.

Enabling UPnP by default means allowing any computer in your network to modify port forwarding. For security reasons, you’ll likely want to restrict this to a few trusted machines, i.e. game consoles and laptops.

In order to manage UPnP from a Linux machine, we’ll need the upnpc command. This can be found in the miniupnpc package on Fedora.

sudo dnf install miniupnpc

From here, we can check if we’ve enabled UPnP by querying for its status

upnpc -s

If it returns the following, then UPnP is not properly set up!

No IGD UPnP Device found on the network !

Otherwise you’ll get a lot of information including:

Found valid IGD : <REDACTED URL>

Assuming everything is setup correctly, we’ll run through an example. Say that we want to run a Starbound server. This typically runs on port 21025.

export INTERNAL_PORT=21025

We’ll need to know our computer’s internal IP address. Assuming that 1.0.0.0 will take you to the Internet and not some virtual private network, we can run the following to get our internal IP address

export INTERNAL_IP=$(ip route get 1 | awk '{print $7}')

For the external port that our friends will connect to, we’ll need to pick an arbitrarily high number that’s not already assigned. This number can be between 1024-65535 depending on your UPnP configuration.

For example,

export EXTERNAL_PORT=60821

Lastly, we need to know whether our game server accepts TCP or UDP requests. Starbounds expects TCP requests.

export PROTOCOL=TCP

Now we can issue a command to our router using upnpc to forward traffic on the external port to our local computer at the specified internal port.

upnpc -a $INTERNAL_IP $INTERNAL_PORT $EXTERNAL_PORT $PROTOCOL

From here, people outside of your network should be able to send traffic to your local computer! They’ll need to know your external IP address.

upnpc -s | grep Ext

If your friends are having trouble connecting to your external IP address and port, double check that your local computer’s firewall isn’t blocking the traffic and check the UPnP routing list.

upnpc -l

When you’re done, don’t forget to delete the rule from UPnP.

upnpc -d $EXTERNAL_PORT $PROTOCOL

Other than gaming, another use case for this is file transfer. Say you want to receive a file from a friend. To not repeat details, assume we’re using the same variables from above and you already added the port forward to UPnP.

On your local machine, use netcat to listen for traffic and write the bytes received to a file.

nc -l $INTERNAL_PORT > file_received.txt

Your friend can now send you a file.

nc $EXTERNAL_IP $EXTERNAL_PORT < file_to_send.txt
Reply via Email Buy me a Coffee
Was this useful? Feel free to share: Hacker News Reddit Twitter