How to set up dynamic DNS for a home computer or server

I recently purchased a mini computer from aliexpress. It's quite powerful, and much more cost effective than renting Amazon EC2 instances. It sits near my router in my apartment, constantly on 24/7, sipping just 10 to 15W.

I have a regular internet service provider (ISP) that I pay monthly. Most importantly, I do not have a static IP address. Usually a static IP either costs more money each month, or is simply not an option.

What's the solution? How can I connect to my home computer/server? Dynamic DNS!

Configuring dynamic DNS

Okay, so I have a domain name, a home internet service provider (ISP), a router, and a home server (the mini computer). I do not have a static IP. But I want to consistently connect to my home computer/server from a remote source (such as from my phone, or from my laptop while traveling).

I registered my domain through Google Domains, so let's start there. You may have to do something similar through the settings wherever you registered your domain.

In the Google Domains section there's an option to set up dynamic DNS for a given domain name. You just specific the subdomain (I named mine 'scooter' as seen below) and pointed it to one of my domain names that I had registered with Google Domains.

Next I went to my home router, which is a TP-LINK Archer C7 and found the section for Dynamic DNS. I was hoping it would be easy enough to just point it to my domain name with the username/password that Google Domains created for me.

Unfortunately TP-LINK isn't very flexible. They expect users to use No-IP, Dyndns, or Comexe for their Dynamic DNS needs.

Fortunately, Google Domains is much more flexible. They let you use a client or their API to update your dynamic DNS.

Okay, so maybe I'll try the DDclient, since that looks to be a supported client.

Using DDclient for Dynamic DNS

You can learn about DDclient here. Since I was running an Ubuntu operating system, I chose to use the apt-get package manager.

Running sudo apt-get install ddclient immediately launched me into a setup wizard.

The only part I was confused about was the network interface.

Running ifconfig -a helped figure that out. Here's the output of running that:

 $ ifconfig -a
 lo        Link encap:Local Loopback
           inet addr:127.0.0.1  Mask:255.0.0.0
           inet6 addr: ::1/128 Scope:Host
           UP LOOPBACK RUNNING  MTU:65536  Metric:1
           RX packets:4207361 errors:0 dropped:0 overruns:0 frame:0
           TX packets:4207361 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:0
           RX bytes:444136775 (444.1 MB)  TX bytes:444136775 (444.1 MB)

 p2p1      Link encap:Ethernet  HWaddr 00:e0:4c:68:26:63
           inet addr:192.168.0.104  Bcast:192.168.0.255  Mask:255.255.255.0
           inet6 addr: fe80::2e0:4cff:fe68:2663/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:81683207 errors:0 dropped:0 overruns:0 frame:0
           TX packets:48801901 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:107403166761 (107.4 GB)  TX bytes:4635165051 (4.6 GB)

 p3p1      Link encap:Ethernet  HWaddr 00:e0:4c:68:26:64
           BROADCAST MULTICAST  MTU:1500  Metric:1
           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

 wlan0     Link encap:Ethernet  HWaddr 48:5d:60:4f:1f:59
           BROADCAST MULTICAST  MTU:1500  Metric:1
           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Based on the amount of traffic, it looks like I want p2p1.

After ddclient installation

After the setup wizard was finished, I expected a generated ddclient.conf file somewhere. According to the docs, there should be one at

/etc/ddclient.conf

But there wasn't. I tried to debug ddclient by running

ddclient -daemon=0 -noquiet -debug

and it showed a file located at

/var/cache/ddclient/ddclient.cache

But then it also showed:

DEBUG:    get_ip: using if, p2p1 reports 192.168.0.104

Which is not the IP address I want!

So I manually created a configuration file at /etc/ddclient.conf

# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf

protocol=dyndns2
use=web
ssl=yes
server=domains.google.com
login=loginname
password='password'
scooter.mydomain.com

Then edit

sudo nano /etc/default/ddclient

Make sure run_daemon=”true”

$ sudo service ddclient status
Status of Dynamic DNS service update utility: ddclient is running.

If it's not running type

$ sudo service ddclient start

Success!

DDclient is a neat piece of software that can detect when my IP address changes (such as when my ISP randomly decides to rotate it). DDclient then transmits the new IP address to Google Domains, so whenever I visit scooter.mydomain.com it knows which IP address to route the traffic to. Yay!

January 2018 update

I've switched internet service providers and domain names a few times since I originally set this up. The original setup is no longer working, so I want to get it functioning again.

Reenable Dynamic DNS on Google Domains

I'll use a "naked" domain so the @ symbol in place of a subdomain. A naked domain is like example.com instead of www.example.com

Note that the data column is blank because the ddclient software hasn't told Google Domains what the IP address is.

dynamic-dns-initial-setup

First I'll confirm that it's installed
stephen@ubuntu:~$ ddclient --version
(lots of help/documentation)
ddclient version 3.8.2

Okay so that's not quite the latest version as of today, which is 3.8.3. Checking the release notes doesn't look like I am missing too much.

Is it running?
stephen@ubuntu:~$ sudo service ddclient status
● ddclient.service - LSB: Update dynamic domain name service entries
   Loaded: loaded (/etc/init.d/ddclient; bad; vendor preset: enabled)
   Active: active (running) since Tue 2018-01-09 21:00:55 PST; 2 days ago
     Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/ddclient.service
           └─828 ddclient - sleeping for 20 second
Jan 09 21:00:55 ubuntu systemd[1]: Starting LSB: Update dynamic domain name service entries...
Jan 09 21:00:55 ubuntu systemd[1]: Started LSB: Update dynamic domain name service entries.
Jan 11 00:09:49 ubuntu ddclient[17650]: FAILED:   updating scooter.domainname.com: nohost: The hos
stephen@ubuntu:~$ 

Okay so it is running, but has old settings.

Update settings
sudo vim /etc/ddclient.conf

# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf

protocol=dyndns2
use=web
ssl=yes
server=domains.google.com
login=abcdef
password=hijklmn
@.mydomain.com

This is the username and password that Google Domains generated. My domain name is at the bottom with the "naked" prefix @. I think I could use the Google Domains protocol since ddclient supports it, but I'll skip that unless I run into issues with the dyndns2 protocol.

Test it out

I'll just run it once (no daemon or service) with the debugging turned on

$ sudo ddclient -daemon=0 -debug -verbose -noquiet
(snip)
=== cache ====
cache{@.mydomain.com}{atime}   : 0
cache{@.mydomain.com}{backupmx} : 0
cache{@.mydomain.com}{custom}  : 0
cache{@.mydomain.com}{host}    : @.mydomain.com
cache{@.mydomain.com}{ip}      : 97.xxx.81.xx
cache{@.mydomain.com}{mtime}   : 1515779480
cache{@.mydomain.com}{mx}      : 
cache{@.mydomain.com}{script}  : /nic/update
cache{@.mydomain.com}{static}  : 0
cache{@.mydomain.com}{status}  : good
cache{@.mydomain.com}{warned-min-error-interval} : 0
cache{@.mydomain.com}{warned-min-interval} : 0
cache{@.mydomain.com}{wildcard} : 0
cache{@.mydomain.com}{wtime}   : 30
(snip)
DEBUG:    proxy  = 
DEBUG:    url    = http://checkip.dyndns.org/
DEBUG:    server = checkip.dyndns.org
CONNECT:  checkip.dyndns.org
CONNECTED:  using HTTP
SENDING:  GET / HTTP/1.0
SENDING:   Host: checkip.dyndns.org
SENDING:   User-Agent: ddclient/3.8.2
SENDING:   Connection: close
SENDING:   
RECEIVE:  HTTP/1.1 200 OK
RECEIVE:  Content-Type: text/html
RECEIVE:  Server: DynDNS-CheckIP/1.0.1
RECEIVE:  Connection: close
RECEIVE:  Cache-Control: no-cache
RECEIVE:  Pragma: no-cache
RECEIVE:  Content-Length: 104
RECEIVE:  
RECEIVE:  <html><head><title>Current IP Check</title></head><body>Current IP Address: 97.xxx.81.xx</bo
dy></html>
DEBUG:    get_ip: using web, http://checkip.dyndns.org/ reports 97.xxx.81.xx
SUCCESS:  @.mydomain.com: skipped: IP address was already set to 97.xxx.81.xx.

Okay, so the logs mention cache{@.mydomain.com}{mtime} : 1515779480 which if we plug into a epoch converter says Friday, January 12, 2018 9:51:20 AM.

And if we check Google Domains:

dynamic-dns-configured

It shows it was modified at 9:51:22 AM, so pretty close. 2 seconds is within the realm of a clock being slow/fast.

Double check cron and services
$ crontab -e
(nothing in there)
$ sudo crontab -e
(nothing in there)

And we'll check the service to see if a daemon is running

stephen@ubuntu:~$ sudo service ddclient status
● ddclient.service - LSB: Update dynamic domain name service entries
   Loaded: loaded (/etc/init.d/ddclient; bad; vendor preset: enabled)
   Active: active (running) since Tue 2018-01-09 21:00:55 PST; 2 days ago
     Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/ddclient.service
           └─828 ddclient - sleeping for 220 second
Jan 09 21:00:55 ubuntu systemd[1]: Starting LSB: Update dynamic domain name service entries...
Jan 09 21:00:55 ubuntu systemd[1]: Started LSB: Update dynamic domain name service entries.
Jan 11 00:09:49 ubuntu ddclient[17650]: FAILED:   updating scooter.mydomain.com: nohost: The hos

It says it's running. If we try to start it again what happens?