Access your Raspberry Pi from anywhere
Raspberry Pi is an ideal platform for setting up personal services, like Git daemon, remote backup server, proxy server… you name it. However, while the device is small and handy it is still not so portable as a server, because conventional server installation usually includes domain name registration, setting up static IP addresses and configuring port forwarding on a router.
In this article I will show you how to utilize DDNS and UPnP technologies, so you will be able to simply plug your Raspberry Pi into an Ethernet port on (almost) any router and then securely access your own services from anywhere. The instructions are also applicable to a wireless connection (just use
wlan0 instead of
eth0 for Wi-Fi).
In a sense, the suggested approach solves the same problem as reverse SSH tunneling, but differently — there’s no need for a “visible” IP address on client side / middle machine (however, the provider’s IP on server side must be accessible), so it’s possible to establish connection with dynamic IPs, router’s NAT on server side and NAT on client side. Besides, this method is not limited to SSH and can handle other types of connections.
The first obstacle that prevents us from accessing the device is dynamic Internet address assignment. Most Internet providers usually assign a new, arbitrary IP address (using DHCP) to a router each time you turn it on (or connect it to a provider network).
Moreover, even static (of “fixed”) IP address will inevitably be different among different Internet providers (and different routers).
To handle this, we will use so called Dynamic DNS (DDNS) to create and dynamically update a mapping between a chosen domain name and an “external” IP address of our Raspberry Pi (i.e. router IP address).
- Register a new user account.
- Choose a desired domain name (like
- Receive a URL with an unique identifier (prefer HTTPS protocol).
After the registration, it’s good idea to verify that dynamic updating works properly.
Let’s fetch the personal URL to associate our chosen domain name with an IP address of the request (in our case, an IP address of Internet router):
curl -ks https://your-personal-url
Query information for your domain name (you may need to install
dnsutils package first):
The response should contain a line like:
Name: your.domain.name Address: 22.214.171.124
Compare this address with an IP address printed after the following request (which displays current “external” IP address of your router):
curl -ks http://checkip.dyndns.org
If the two addresses match, then dynamic DNS works as expected.
UPnP port forwarding
To route “external” (WAN) connections to the Raspberry Pi we will employ port forwarding on a router. Because manual configuration of port forwarding rules on each router is not a portable solution (besides, routers also use DHCP to assign dynamic IP addresses to LAN devices, so a MAC-based DHCP reservation is additionally needed), we will rely on Universal Plug and Play (UPnP) protocol to dynamically configure proper port forwarding rules.
Most todays routers support both port forwarding and UPnP, so in most cases Raspberry Pi will be able to enable external access automatically.
We’ll rely on miniupnpc UPnP client, which can be installed as
miniupnpc package via your OS package manager.
First of all, let’s ensure that our current router supports UPnP:
This command should:
- enumerate all supported UPnP devices on local network,
- display their internal- and external IP addresses,
- list their current port forwarding rules.
If router supports UPnP, we can add a port forwarding (for SSH protocol):
upnpc -e 'SSH on Raspberry Pi' -r 22 TCP
After that, we may verify the result by reissuing
upnpc -l, the output should contain something like:
Compare this IP address with the internal IP address of the device, which can be displayed via:
ip -4 addr show dev eth0
If you need to access other services on Raspberry Pi (besides SSH), you may also configure additional port forwardings.
After both DNS and port forwarding are configured, it should be possible to establish an SSH connection to the Raspberry Pi from the Internet:
However, please keep in mind, that most routers are not able to establish “external” connections from the internal network itself, so a separate Internet connection is needed to fully test the setup.
Now, when all the subsystems are checked, we are ready to setup unattended configuration.
Create a shell script in editor:
sudo nano /usr/local/bin/redirect.sh
insert the following content (don’t forget to specify your real DDNS URL there):
#!/bin/bash curl -ks https://your-personal-url > /dev/null upnpc -e 'SSH on Raspberry Pi' -r 22 TCP > /dev/null
Then configure Cron to periodically run this script (every 30 minutes):
sudo crontab -e
add the following line:
*/30 * * * * /usr/local/bin/redirect.sh
In this way, Raspberry Pi will automatically update both domain IP and port forwarding, so we should be able to access the device from the Internet even after provider / router / IP address change (however, it may take some time before re-configuration happens).
To avoid the delay before re-configuration, we may configure network manager to automatically run our configuration script when Ethernet cable is plugged in.
If you use Debian-based OS (like Raspbian), add
post-up option to
auto eth0 allow-hotplug eth0 iface eth0 inet dhcp post-up '/usr/local/bin/redirect.sh||true'
Interface=eth0 Connection=ethernet IP=dhcp ExecUpPost='/usr/local/bin/redirect.sh||true'
ifplugd service for
sudo systemctl enable firstname.lastname@example.org sudo systemctl start email@example.com
Now the configuration script should be run automatically when Ethernet connection is established.
Enabling global Internet access to your Raspberry Pi device is definitely convenient. However, you should keep in mind, that such access must be always complemented by adequately hardened security, namely:
- Limit root login via SSH.
- Generate a strong SSH key.
- Disable password login via SSH.
- Configure firewall rules.
* Raspberry Pi is a trademark of the Raspberry Pi Foundation