Introduction: Quick and Dirty Dynamic DNS Using GoDaddy

Need a quick and dirty answer for a (more or less) free Dynamic DNS provider? Well, if you use GoDaddy to register your domain, you have everything you need to do this.

Why would you need dynamic dns?

Imagine if you have some resources at home that you need to access when you're on vacation, but your ISP (I use Verizon FiOS) changes your IP address from time to time. Some providers, like Cable-based ISPs, change the IPs pretty frequently. Well, your choices are to go in and update your DNS record manually, use one of the free (typically restricted to their domain) or premium Dynamic DNS (DDNS) providers, or set up a simple bash script to detect the change and make the update in your own registered domain.

Plus, its free (free, if you already use GoDaddy).

Prerequisites

  1. GoDaddy-registered and managed domain. These are pretty inexpensive ($14.99/yr) and GoDaddy is the biggest registrar (at least in the US). Chances are if you have a domain name, you're probably using GoDaddy already. Plus, they throw in other features like mail forwarding and DNS zone management for free. They also have a nifty API that allows you to change you DNS records programmatically (more on that later).
  2. Some kind of server at your location that can run a bash script. The script is only a few lines and should be easily portable to php or even PowerShell, so you can make Windows-compatible versions too.

Step 1: Create Your DNS Name

First, you have to create your DNS name in GoDaddy (this assumes you have already registered a domain with GoDaddy).

GoDaddy provides several good resources on how to do this.

Add an A record in GoDaddy

I'm attaching a GIF-video from their web site that shows how easy it is.

For "Type" make sure to use "A" -- CNAME won't work.

For "Host" enter the hostname you'd like to use. I like to use "gateway" because it's how I reach the resources behind the entry point to my home network. FYI, I use ssh and rsa keys to tunnel in. I'm working on moving to a pfSense-based VPN, but that's still a work-in-progress.

For "Points to" you can enter anything you want. I use "1.1.1.1" so that it will be obvious my script is working once I run it. This is the value that will change when your ISP changes you IP address.

For "TTL" choose "Custom" then put in an arbitrarily short timeout. This tells systems that read this DNS record how long they should cache it before getting a new one. Typically, this is long (1 hour) for static DNS entries. It helps reduce DNS traffic on the general internet. For dynamic DNS, I like to use something shorter like 600 seconds (10 minutes). You don't want this to be too long because it governs the "switching" time between your old IP address and your new one. If this is an hour, it could take up to an hour to reach your dynamic resource after an IP change. NOTE: you can always flushdns at the endpoint, but sometimes intermediate DNS servers will cache the reply (again, to save on traffic).

The most important thing is to make sure it's an "A" record.

Step 2: Create a GoDaddy API Key

In order to make programmatic changes to the DNS records, you'll need a GoDaddy API key. Here is some background on the process first:

GoDaddy Developer "Get Started" Guide

The short version is, go to this link GoDaddy API Keys and click "Create New API key"

You'll want to give it a new name (I use "Dynamic DNS") and select an environment. GoDaddy recommends you test with the OTE environment first, then move to Production. You're using my code, so you can probably just create a production key.

Next, you'll see your API key and your key secret. Make sure you copy these down. The API key will still be visible when you come back to this screen, but the secret will never be displayed again and cannot be recovered!! If you lose the secret, you'll have to create a new key. HINT: Don't lose the secret.

Step 3: Create a Script to Update DNS

Here is a quick and dirty script you can use to determine your current IP, compare it to your DNS zone file, and update if needed. It's written for BASH (Un*x):

#!/bin/bash

mydomain="sos-obx.us"
myhostname="gateway"
gdapikey="api_key:key_secret"
logdest="local7.info"

myip=`curl -s "https://api.ipify.org"`
dnsdata=`curl -s -X GET -H "Authorization: sso-key ${gdapikey}" "https://api.godaddy.com/v1/domains/${mydomain}/records/A/${myhostname}"`
gdip=`echo $dnsdata | cut -d ',' -f 1 | tr -d '"' | cut -d ":" -f 2`
echo "`date '+%Y-%m-%d %H:%M:%S'` - Current External IP is $myip, GoDaddy DNS IP is $gdip"

if [ "$gdip" != "$myip" -a "$myip" != "" ]; then
  echo "IP has changed!! Updating on GoDaddy"
  curl -s -X PUT "https://api.godaddy.com/v1/domains/${mydomain}/records/A/${myhostname}" -H "Authorization: sso-key ${gdapikey}" -H "Content-Type: application/json" -d "[{\"data\": \"${myip}\"}]"
  logger -p $logdest "Changed IP on ${hostname}.${mydomain} from ${gdip} to ${myip}"
fi

Replace "mydomain" variable with the domain you registered. For example, if you registered "fredshouse.com" then the line should read:

mydomain="fredshouse.com"

Also replace "myhostname" with your hostname, "api_key" with you api key and "key_secret" with your key secret. It's important to note that the actual contents of "gdapikey" will be your api key followed by a colon (":") followed by the secret as one single string. If you get this wrong, the script will not work. Let's say your api key is "abcdefghijklm" and your key secret is "zyx987rst456" then your "gdapikey" will be "abcdefghijklm:zyx987rst456" -- one string with a colon separating the two parts. Again, this is IMPORTANT.

I saved this as /usr/local/sbin/gd-dyndns. Make sure your chmod 700 to both make it executable and to protect it from prying eyes. My script is owned by root (quick and dirty -- I warned you!!).

This script uses ipify.org to determine your current IP address (they return results in a code-friendly way) then compares to the current IP setting in GoDaddy. If they do not match, it uses the API to change the IP address.

I installed this as a cron job (crontab -e) and it runs every 10 minutes:

*/10 * * * *    /usr/local/sbin/gd-dyndns > /dev/null

You should go back to the GoDaddy DNS manager to verify that it updated properly.

That's it!! Quick and dirty but free if you already use GoDaddy as your registrar.

Step 4: Porting to Other Languages

I've given you the bash version. Porting to php should be super simple (use phpcurl). PowerShell might be a bit more of a challenge, but you should look at Invoke-WebRequest.

If the community likes this instructable but needs a php and/or PowerShell version, I might be inclined to write it and come back to update this article.

UPDATE:

Here is a version that works in PowerShell. You can add to the Task Scheduler.

$mydomain = "sos-obx.us"
$myhostname = "gateway" $gdapikey = "api_key:key_secret" $myip = Invoke-RestMethod -Uri "https://api.ipify.org" $dnsdata = Invoke-RestMethod "https://api.godaddy.com/v1/domains/$($mydomain)/records/A/$($myhostname)" -Headers @{ Authorization = "sso-key $($gdapikey)" } $gdip = $dnsdata.data Write-Output "$(Get-Date -Format 'u') - Current External IP is $($myip), GoDaddy DNS IP is $($gdip)" If ( $gpid -ne $myip) { Write-Output "IP has changed!! Updating on GoDaddy" Invoke-RestMethod -Method PUT -Uri "https://api.godaddy.com/v1/domains/$($mydomain)/records/A/$($myhostname)" -Headers @{ Authorization = "sso-key $($gdapikey)" } -ContentType "application/json" -Body "[{`"data`": `"$($myip)`"}]"; }