Fast dynamic DNS with cron, PHP and DuckDNS

ducky_icon_mediumMy home connection has a 200 mbit cable Internet connection with 20 mbit up. Great for running a server, but every two days my ISP changes my IP address. When this happens I cannot connect to my home network anymore using VPN. Annoying, but certainly a (programming) challenge to me. The simple solution for this is to use a dynamic DNS solution. The name DynDNS popped up in my head, but apparently they are not free anymore (bummer). That’s why I chose to use the free dynamic DNS service “DuckDNS“. Then I realized that I do want a fast update of my dynamic DNS entry when my IP address changes, but I do not want to hammer DuckDNS. That’s why I wrote a small script to achieve this. You find it below.

DuckDNS PHP script to avoid hammering

On my website I installed the following PHP script that will call DuckDNS if the IP address of the caller has changed. It is must be called with a post request that holds a shared secret. This will avoid bots (or hackers) to change the DNS entry. Note that additionally HTTPS (SSL) is used to guarantee confidentiality.

<?php
// settings
$domains = 'cable-at-home'; // cable-at-home.duckdns.org
$token = 'eb1183a2-153b-11e5-b60b-1697f925ec7b';
$ip = $_SERVER['REMOTE_ADDR'];
$file = '/tmp/duckdns.txt';
$secret = 'VeryHardToGuess';
// compare secret
if (!isset($_POST['secret']) || $_POST['secret']!=$secret) { http_response_code(403); die(); }
// compare with current ip
if ($ip==file_get_contents($file)) { http_response_code(304); die('OK'); }
// create url
$url = "https://www.duckdns.org/update?domains=$domains&token=$token&ip=$ip";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
// if success update current ip
if ($result!='OK') { http_response_code(400); die($result); }
file_put_contents($file,$ip);
die('OK');

Install this script somewhere in your Apache “DocumentRoot” and name it “duckdns.php”.

Cron script that runs every minute

I installed the following cron job on my server that runs in my home and is connected with cable to the Internet using the “crontab -e” command:

* * * * * /usr/bin/curl -X POST -d 'secret=VeryHardToGuess' https://somedomain.com/duckdns.php

Every minute this cron job executes a curl call to the duckdns.php PHP script on my website (somedomain.com). Only if the IP address is changed the call to DuckDNS (https://www.duckdns.org/update) is made to update the IP address. This avoids hammering the DuckDNS service, but also allows you to get the fastest response to an IP address change.

Installation

Note that in order to make this work you have to create an account at DuckDNS and then modify the “$domains” and “$token” parameters in the PHP script accordingly. You need to change “somedomain.com” in the cron job with the URL of your website. Also do not forget to replace “VeryHardToGuess” in both the PHP script as the cron job with a real secret. Any questions? Use the comments below!

Share

Leave a Reply

Your email address will not be published. Required fields are marked *