Access a Service from Anywhere with DuckDNS
This article focuses on allowing to access any of your internal services (a service running on a machine in your intranet) from anywhere in the world.
The situation is the classic one where you may have installed a new system (that could be an Home Assistant, a Cloud System, a webcam… or anything else really) and you would like now to use it when you are out and about around the world, outside your local home network.
The steps that we’ll follow to achieve this will be essentially 2:
- Configure your router to allow connection from outside
- Use a dynamic DNS system to find our home IP in order to connect to it
Configure your router
This step is mandatory and required any time you want to access a resource in your private LAN from outside.
It’s very simple and everything it really does is registering a port (8123 for example) telling our router (that connects us to the external world) to send any request from outside, requested to that specific port, to a well defined device in our internal network (and to a specific port that could even be different if we really want)
This is called Port Forwarding.
That said though, the routers are all different and there is no way for me to show where this configuration is precisely located on your router.
Despite this, it should not be difficult to locate.
First of all you need to access your router.
On Windows you can use the command “ipconfig /all” and look for the “DNS Servers” line.
On Mac you can try to use “cat /etc/resolv.conf” or other methods. You can easily find it out with a minimum search on the web.
Otherwise look at your IP and you can try to substitute the last number with “1” or “254”. So for example things like: 192.168.0.1, 192.168.0.254 or 192.168.1.1, 192.168.1.254.
Once you have the router configuration page in front of you, you need to find the section where you can setup the port forwarding .
It is generally inside a section of the router that will probably require you to access it using an admin account.
Check the manual, search the web or simply look for the port forwarding section and create a new port forwarding.
Set the port 8123 as the only port to forward, select the TCP protocol, and select the system with the Home Assistant installed as the destination computer.
As a reference, this is an example of how it could look like:
search “myip” on google and you should receive the information about your public IP.
grab that address (let’s call it a.b.c.d) put it in your browser with the port 8123 (a.b.c.d:8123).
at this point your Service page should be visible in the same way it was when you accessed it within your LAN.
Let’s now see how can we make it practical and reliable.
Setup a DNS
This is the step that will allow to use a friendly address name (such as myawesomeservice.com as an example) and have it translate into the public IP of our home.
Can I use the IP directly?
Well yes, you could… but it’s not very practical nor “elegant”.
In theory, once you know your public IP you could use that one to connect to your machine (still need a little bit of work, but it’s minimal).
The problem with this direct approach is both that you need to know and remember the numbers of your IP and also the fact that your internet provider will probably change your public IP periodically… so you’ll need to find out your new IP in order to been able to connect again.
It’s undeniable that is much better to been able to remember an internet address (such as www.google.com or mycoolservice.com) that never changes, in order to connect to our machine.
So, if you’re ready, let’s start!
Now… as you can imagine, discovering your IP every time is not very practical, considering that it could easily change! (aside from the fact that, as we mentioned, having to remember that 4 numbers is not ideal).
To avoid this we want to use a DNS system that will allow us to type something likemycoolservice.com for example and automatically resolve it into the IP that will bring us back home (literally).
The service we’ll configure and use is called DuckDNS: https://www.duckdns.org/
Decide one of the offered method of registering/signing-in and you can immediately decide your very own domain for free!
This is the UI that offer you this:
Register a domain in DuckDNS
Pick one sub domain and click on the “add domain”.
At this point you are ready!
One extra thing you just need to keep track of is a couple of data that we’ll need later on in order to update the IP associated with our new domain.
From the page with your domain (I highlighted some important part to look at):
You can check that the current IP is the one you can find with google (as shown previously).
In particular now keep track of:
At this point we have a system that from anywhere in the world will allow us to open a web address like “yourDomain.duckdns.org” and redirect this connection to our home IP.
The only problem is that as it stands, this will work until our IP will remain the same. As soon as our internet provider will change our public IP, this redirection will fail, still pointing to our old IP address!
To solve this we’ll need set something up somewhere… I know it can sound vague, but the reality is that this can be achieved in several ways. We could configure our home router to take care of this (if this is a feature available on it), or we could have the specific Service we are using to update this… again, if it’s something that the service can do for us.
Ultimately, we can take care of it personally if we don’t have any of the other automatic options available, or simply we want full control over this as well.
Let’s do this now.
Update DuckDNS with cron
What we want to achieve is setup an automatic task that will execute at a specific interval of time and that will contact DuckDNS for us to update the IP associated with our domain.
DuckDNS gives us the exact list of commands to follow in order to achieve this.
You can find it clicking on the “Install” link at the top of the page:
and then select “pi” (for example):
and lastly selecting the domain we want to update from the dropdown list:
at this point the website will tell us exactly how to proceed.
In summary these are the steps.
Create an update script
I’ll put my one in a folder called “duckdns“:
pi@raspberrypi:~ $ mkdir duckdns
pi@raspberrypi:~ $ cd duckdns/
Let’s name it “duck.sh” and edit it:
with the content:
echo url="https://www.duckdns.org/update?domains=YOUR_DOMAIN&token=YOUR_TOKEN&ip=" | curl -k -o ~/duckdns/duck.log -K -
where naturally you’ll have to use your domain (in “YOUR_DOMAIN“) and token (in “YOUR_TOKEN“) as reported on the site.
When this script will be executed, it will contact DuckDNS to update the IP address associated with the domain specified.
Make it executable
Add the execution permission:
chmod 700 duck.sh
Add a cron job
Now we want to automate the process of periodically execute that script, at a specific interval that we decide.
For this we’ll use cron:
Add this at the end of the file:
*/5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1
Note: we used “*/5” to have the system updating the IP every 5 minutes. You can change this (or the full string of “*/5 * * * *”) to chose exactly when you want it to be executed.
We can test that the script works as expected, executing it (and checking the log):
pi@raspberrypi:~/duckdns $ ./duck.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2 0 2 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0
pi@raspberrypi:~/duckdns $ cat duck.log
Let’s ensure the cron service is running:
sudo service cron start
and we are good to go.
All done! At this point you should be able to reach your Service from anywhere in the world just reaching the web address:
The browser will contact DuckDNS and find out your latest public IP. It will then contact your home Router at the requested port that will in turn redirect the call to the machine with the Service on it… beautiful!
but wait… there is more…
Despite we achieved our goal there is an extra step that is generally recommended:
Right now our connection is http (non-secure). This means that we are potentially open to attacks or more vulnerable in general.
In order to avoid this, it’s good practice to secure the connection with SSL and HTTPS.
I’ll cover this in another article.
If you enjoyed this article, found it interesting or just learned something new (or simply liked it) please share it, comment or feel free to if you think I deserved it or you simply want to show your appreciation :). In any case thanks for passing by and until next time!