DDNS device placed far away

Background

A family member wants to have access to devices on their home network from the internet, and have been using the public IP-address given by the ISP to connect back home. Unfortunately, during certain events, such as power outages, the ISP has a short enough lease that a new IP-address is given. When this happens, the family member can no longer connect to their home network until they have manually changed the IP-address to the new one in the applications they use. It would be adventageous for them to avoid this “debacle” of the things not working and the digging up of the new/current IP-address.
It would also be a bonus if the family member can monitor whatever solution is implemented, for their own sake.

Requirements and Constraints

Since this is a home project; costs, especially monthly/anually ones, should be minimized/reasonable. Therefore a free solution is highly preferred.

Using an existing device on the network may be troublesome:

Research and Resources

DNS and DDNS

DNS is the way to abstract away IP-addresses, and Dynamic DNS (DDNS) is the way to keep periodically changing IP-addresses current in a DNS registrar. What is DDNS? Wipikedia summarizes it adequately:

Dynamic DNS (DDNS) is a method of automatically updating (IP-addresses in*) a name server in the Domain Name System (DNS), often in real time…

Wikipedia page on DDNS

*DDNS can update more than just IP-addresses.

DDNS requires a service to run within the target/local home network on something. This something can be anything from the ISP-provided router, smart home hub, personal computer/device, maybe even the fridge these days, as long as it has LAN access, can reach the internet, and can run some user specified code periodically. The actual piece of code that has to run depends on what the DDNS provider requires, as no established standard exists. However, for the most part, DDNS providers either have an API or a HTTP/HTTPS based protocol (or both) for updating the registrar.
Since I am not looking to do anything fancy with DDNS, I am choosing the path of a HTTP/HTTPS based protocol. Primarily because it is dead simple; a single HTTP/HTTPS request, and Bob’s your uncle. And because of cost; a free DDNS platform is highly preferred.

I settled on these two DDNS providers:

For these reasons:

Support structure

With this device being far away, being able to just zip over and just do something real quick is not an option. We are talking ~24hour round trip by car. Therefore, some kind of support structure has to be in place. In this case I am defining support structure as (most-to-least important):

I could set this all up using existing open source tools and software, however, the part about the family member wanting to “monitor” the implementation falls down this alley. With ssh not being user friendly for someone that is “not good with computers”, I am begrudginly leaning towards some kind of all-in-one IoT platform. Fortunately, or more like unfortunately, I have had the pleasure of working with some of these platforms in my career.
The one I ended up choosing for this project is not one I endorse, but I can not really say I disprove of it either; balena.io It has all the bells and whistles one could ask for, but most importantly for this project: it is free (for this kind of use)

Basic explanation of what balena is and how it works:

Device

I could use an existing device on the local home network, as mentioned before, but this is a one-time cost I am happy to pay. The device I am looking for for this project should match these criterias:

And the winner is, to my great dismay, a Raspberry Pi… ugh

Don’t get me wrong, they are useful for what they are, I just don’t like them. In fact, I really don’t like them, and I will give you some heavily biased reasons why:

Unfortunately, there really is no other competitor that can beat them on price, availability, and support.
I guess I just want something fresh, but for now a Raspberry Pi will do…

Application

Some software is needed for the DDNS implementation. The actual HTTP/HTTPS request is simple, but some more potatoes are needed. Particularly the scheduling and/or triggering of the request periodically. The container shell is also needed.
Luckily, as mentioned before, LinuxServer.io have made a simple free and open source docker image for Duck DNS called docker-duckdns under the GNU general public license.

The same container can be easily modified to work for other DDNS services, such as dynu.

 

Solution

Note: Two devices was used in this project; one for local use, and one to send off. This way, changes can be tested locally before pushing them to the unreachable device. Instructions will reflect this.

Design

DDNS-diagram

Setting up DDNS providers

DuckDNS

  1. Register at duckdns.org. I used GitHub credentials
  2. Add domain(s). I added something similar to this:
    • ProjectName
    • ProjectNameDemo
  3. Copy the token from the site. Keep it for later

Dynu {d}DNS

  1. Register at dynu.com. I used GitHub credentials
  2. Navigate to DDNS Services
  3. Choose whatever option suits you. I chose option 1 (using their domain name)
  4. Add domain(s). I added something similar to this:
    • ProjectName.freeddns.org
    • ProjectNameDemo.freeddns.org
  5. When viewing one particular DNS entry, there is a link at the bottom to set IP Update Password. The same page can be found at Control Panel → Control Panel → My Account → Username/Password
  6. Type in your Current Password, and a different “loosable” in New IP Update Password as well as Confirm New IP Update Password. This new IP password will potentially be sent over HTTP! Hopefully only over HTTPS and hashed, but consider this password as leaked. Misuse is limited to messing with the settable IP of you domain entires.
  7. Navigate to IP Update Protocol via DDNS → IP Update Protocol
  8. This page describes the basics of Dynus updating protocol using HTTP/HTTPS requests instead of their API. Read it if you like.
  9. Dynu can use clear text passwords (please don’t) and MD5 hashed passwords when updating over HTTP/HTTPS. Either hash your password to MD5 using your favorite hasher, or use the hasher on Dynu:
    • Navigate to Dynu Hash via the page for IP Update Protocol or Control Panel → Network Tools → Hash
    • Type the IP Update Password created earlier into the big text box in the center
    • Press the putton for MD5 Hash
    • Copy the output string that appears above the text boy in white with grey background. Keep it for later
    • Close the webpage, as a password in clear text is visible

Support structure

Getting connected with Balena:

  1. Register at Balena-cloud.com. I used GitHub credentials
  2. Create a fleet (read: project). Setting a default device type is required.
  3. Add device. I chose:
    • Device type: default
    • Select OS type: default
    • Select version: default / recommended
    • Select edition: Development
    • Network: Ethernet only
    • Advanced settings: default
  4. Choose Flash or Download balenaOS. I downloaded
  5. Flash the image, either downloaded or from the web, to the SD-card intended for the Raspberry Pi

This is the bare minimum to get the device connected to the Balena platform. You should now skip ahead to setup the device and come back later, somewhere in the DDNS setup, as some of these steps are unavailable until software is pushed to Balena.

Setting up variables in Balena:

The device needs credentials/token and DDNS entry details to connect and update the DDNS entry, and this has to be stored/available for the device to use. To avoid baking these credentials and details into the image of the device, variables in Balena can be used.

There are two types of variables in balena:

In terms of scalability, if multiple devices were to report one IP-address each, then storing this information in the section named Variables will make all devices update the same DDNS entry. The result will be one DDNS entry which constantly changed IP-address from each device, which could not be used to anything. Therefore, each device need at least their own entry/ies to differentiate between devices, IP-addresses, and entries.

Clicking on a specific device will show Device Variables instead. Storing credentials here will allow each device to use the same variable name/path, while still having different values between devices.

Create the following device variables:

Credentials for

Device

Nothing to write home about here:

The device automatically shows up under the project in Balena.io as a new device

DDNS setup

Forking LinuxServer.io - docker-duckdns

Result

Related
Linux · Docker · Script · Software