This tutorial will show you how to configure ddclient on Raspbian and Ubuntu. Many tutorials don't explain what to do if your server is behind a router, but this one will. I recently set up a backup server on an internet connection that has a dynamic IP address. So far, I've been spoiled at home because my ISP (PlusNet) makes switching to a static IP address easy and cheap, so obviously I did that. This time though, I didn't have that option, and I didn't want to configure a dynamic dns client on that router either, so I had to set it up on the server itself.
Some DNS providers offer their own dynamic DNS clients, but most of them are proprietary. The one I am going to use is called ddclient, it's free and open source, and written in Perl. Use this command to install ddclient:
sudo apt-get install ddclient
Enable dynamic DNS with your DNS provider
If you're not using namecheap, then this section will be different, but the concept is the same regardless of DNS provider. Log into namecheap and select the relevant domain, then choose "Dynamic DNS" under Miscellaneous settings. Use the radio buttons to enable dynamic DNS, and then make a note of the password. It should go without saying, but be really careful what you do with this password - anyone with access to it could change any DNS record for your domain that they wanted to. Unfortunately, namecheap doesn't let you restrict the dynamic DNS to just one subdomain. Next, navigate to "All host records" add a DNS A record for your domain (use the @ symbol for this), or subdomain. Use the dummy IP address
127.0.0.1 for now, the first time we run ddclient this will be updated to your actual Wide Area Network (WAN) IP address.
Now you have everything you need to configure ddclient. The main configuration file for ddclient is at
/etc/ddclient.conf, you can open this file to edit it with a text editor of your choice - this command will open it in nano:
sudo nano /etc/ddclient.conf
Here is a sample "normal" configuration file for ddclient:
protocol=namecheap server=dynamicdns.park-your-domain.com login=yourdomain.com password='password' subdomain
- protocol is set by your dynamic DNS provider. For namecheap the value is "namecheap"
- server is the hostname of the dynamic DNS server. The dynamic DNS servers used by namecheap are located at "dynamicdns.park-your-domain.com"
- login is your domain name
- password is the string we obtained earlier from the namecheap web interface. Leave the single quotation marks around the string.
- The last line is the subdomain to be modified. In my case this was backup, for backup.samhobbs.co.uk. If you wanted to update your root domain, you would put an @ symbol on this line instead
WAN IP discovery
The above configuration would work fine if ddclient was installed on a router, since the router knows your WAN IP address. However, it doesn't work if your server is behind a router because the server only knows its Local Area Network (LAN) IP address. There is a configuration parameter called
use, which determines the method ddclient uses to find the WAN IP. - if you specify this parameter, it must go above the rest of the configuration in the file. If you specify it below, it won't work! This caused me quite a lot of grief. The default value for
if, which uses information from the netwrok interface (think
ifconfig). If you have multiple network interfaces, you can specify which one like
use=if, if=eth0 for ethernet,
if=lo for the loopback address,
if=wlan0 for wireless LAN etc. However, none of these will work for us because none of them will give the WAN IP. There are two more types of value you can set:
web, and router firmware values like
Getting your WAN IP from your router's status page
Although I haven't opted for the router firmware method, I think it's quite interesting and worth discussing. Router firmware settings look something like this:
use=fw, fw=192.168.1.1/status.htm, fw-login=admin, fw-password=admin, fw-skip='IP Address'
fw= sets the location of the status page for that particular router containing the WAN IP address. If the status page is not available to unauthenticated users, you must set the username and password to allow ddclient to authenticate with the router.
fw-skip tells ddclient to ignore any IP address on the status page you specified before a certain string, in this case 'IP Address'. Some popular router manufacturers have their own settings for ease of use, for example if you have a Linksys router you can use this line:
use=linksys, fw=linksys, fw-login=admin, fw-password=admin
Note that since a lot of routers won't let more than one user log in as admin at a time, you could potentially prevent ddclient from updating your dynamic IP address if you are logged in yourself at the same time.
Getting your WAN IP address from a web service
web method involves ddclient querying one of the many "what is my ip" type web services on the internet, and extracting your IP address from the page returned. You can tell ddclient to use this method by using this line:
Similarly to other methods, you can also specify which website to use with the
web-skip parameter. Some options with preset values are
loopia, although you can use any site you like. For example, you could use somedomain.com by setting
use=somedomain.com, with an appropriate
web-skip-pattern=foo to ignore IP addresses before the string "foo" if necessary..
Remember how I said anyone with your dynamic dns password can change your DNS records? Sending your password via http (not https) is a bad idea. This parameter will force https:
Again, this needs to go above the
protocol parameter in your config file. For this to work, you need a perl library that can use SSL. Install it with this command:
sudo apt-get install libio-socket-ssl-perl
Testing your configuration
You can check if the pre-defined
use values can detect your WAN IP by running this command:
sudo ddclient -query
If your server is connected with an ethernet cable, the output should look something like this:
use=if, if=lo address is 127.0.0.1 use=if, if=p2p1 address is 192.168.1.119 use=if, if=wlan0 address is NOT FOUND use=web, web=dnspark address is 220.127.116.11 use=web, web=dyndns address is 18.104.22.168 use=web, web=loopia address is 22.214.171.124
To test your ddclient configuration with really verbose output, printing all possible configuration parameters and their values, you can use this command:
sudo ddclient -debug -verbose -noquiet
I won't print a sample output because it's too long, but somewhere near the bottom you should see a line like this:
SUCCESS: updating backup: good: IP address set to 126.96.36.199
While we've got all this information, It's worth checking to make sure you are actually using SSL to connect to your dynamic DNS provider. Look for lines like this:
CONNECT: dynamicdns.park-your-domain.com CONNECTED: using SSL
Run ddclient as a daemon
Since we don't just want the IP address to update once, we still need to set up ddclient to run as a daemon so it can check for a change of IP address periodically and notify the dynamic DNS provider if necessary. To start the daemon we need to open another configuration file,
/etc/default/ddclient and set:
You will notice there is a
daemon_interval parameter there too, I think the default value of 300 seconds (5 minutes) is reasonable, so I didn't change it. Save and close the file, and then run:
sudo service ddclient start
to start the daemon, and:
sudo service ddclient status
to check its status. ddclient keeps a cache of your IP address, and it will only update the record with your dynamic DNS provider if your IP address has changed. Since some ISPs seem to only allocate new IP addresses when the modem is power cycled, and some dynamic DNS providers will time out if you don't update the record in a while, there is one thing left to do - we need to add a cron job to force an update weekly, just in case. Choose whether you want to force an update daily or weekly, and then create a file called ddclient in the relevant directory, e.g.
sudo nano /etc/cron.daily/ddclient
Fill in this information:
#!/bin/sh /usr/sbin/ddclient -force
Then make the script executable:
sudo chmod +x /etc/cron.daily/ddclient
Sam thanks for the great tutorial, which is still helping people like me a longtime since it was first published.
For anyone that uses multiple DDNS providers, they could have a look at the web service "DNS-O-Matic" they are able to update virtually all different DDNS providers from one central DDNS update i.e. ddclient only updates this service, which in turn updates all other configured DDNS service supplies - a great free service once configured on their website.
My Raspberry Pi consistently fails to resolve the hostname of the server I am using in "web" at reboot, but works fine if I run again later.
I happened to reboot my router this morning, and I see a failure in syslog about that time, although I wasn't paying attention to the Pi. It must have been retrying because of the loss of WiFi connectivity.
I see the "normal" config at the top of this article, and at the bottom, the word "Done".
I would like to see the modified config file after "Done", although mine agrees with one in the comments.
This works as a non-demon command line, it works on systemctl start after the Pi is up and connected to WiFi
It never works at boot, and today, it seems it doesn't work after a loss of WiFi when the router is rebooting.
Hello, I'm a new player with RasppberryPi and enjoying a lot stuff with network, connectivity and remote mini-services, as well as self-property.
Absolutely excellent post: the description in each step is clear, the path it is detailed enough to check whether the steps are properly configured and everything it is well explained.
Thanks a lot for your time, I'll keep digging in other tutorial here.
Thank you for great tutorial. I like to point out minor correction: In the section: "Run ddclient as daemon", the below sentence:
"ddclient keeps a cache of your IP address, and it will only update the record with your dynamic DNS provider if your IP address hasn't changed." should read: "...has changed."
Thanks once again for great tutorial and you taking the time to help others
I used this guide successfully for about 6 months. Thank you!
I recently switched to a new modem so I have a new external IP address. I tried to update manually using 'ddclient' command, but I get a permissions error:
SUCCESS: updating @: good: IP address set to x.x.x.x
FATAL: Cannot create file '/var/cache/ddclient/ddclient.cache'. (Permission denied)
I tried to cd into the ddclient folder but I don't have permission for it either. I'm weary to start changing permissions of these folders before goirng further. Any ideas?
I recently submitted a question about manually updating/running the “ddclient” command and running into a permissions error.
Anyway, simply running “sudo ddclient” pushed through my new IP, and once I figured out my router manufacturer uses “virtual servers” instead of “port forwarding”, I was able to get up and running on my new hardware (using ddclient with pivpn here).