My almost free dynamic dns replacement (AWS route53)

I use amazon route53 for DNS, it is easy, cheap, portable since it is separate from my domain registrar, and they have a pretty nice API.  There is a nice CLI tool for changing DNS called cli53, the official tool, awscli, would work too but I’d have to make JSON requests my self if I used that over cli53. See the last code block for the final script and you’ll see why cli53 is just easier than aws route53 change-resource-record-sets commands.

Just run

sudo pip install cli53

to get cli53 (install pip first if you’re missing that obviously)
Next login to Amazon Web Services IAM and restrict a new group/user to only have permission to route53 + your domain. My policy looks like this, update with your route53 hosted zone:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:ChangeResourceRecordSets",
                "route53:GetChange",
                "route53:GetHostedZone",
                "route53:ListHostedZones",
                "route53:ListResourceRecordSets"
            ],
           "Resource": [ 
               "arn:aws:route53:::hostedzone/ZENV1B2ABCDEF"
            ]
        },
       {
         "Effect":"Allow",
         "Action":[
            "route53:GetHostedZone",
            "route53:ListHostedZones"
         ],
         "Resource":"*"
      }
    ]
}

Your web host needs a simple application to return external IPs, or you can use a openly free one (the only free one I found was throttled), something like this works on a PHP webserver:

<?php print $_SERVER['REMOTE_ADDR']; ?>

Finally here is the script to do the real work. This will need to be installed on a computer with cli53 and curl installed (sorry, I know a router would be more convenient). I setup a user called dyndns setup cli53’s .boto configuration AWS credentials file, see CLI53’s docs for more on that. Then just put it in the crontab to run every 5 minutes and perform some basic tests to confirm it works. Like deleting the ip_address.log and make sure cron re-generates it…the real test comes when your IP address changes…I suppose I should have tested that before posting 🙂 oh well.

#!/bin/bash
 
SCRIPTPATH=$( cd $(dirname $0) ; pwd -P )
IP_LOG="${SCRIPTPATH}/ip_address.log"
if [ ! -f $IP_LOG ] ; then touch $IP_LOG ; fi;
LAST_IP=`tail -1 ${IP_LOG} | cut -d' ' -f3`
CURRENT_IP=`curl http://yourdomain.com/whatismyip.php`
 
if [ "$CURRENT_IP" != "$LAST_IP" ]; then
cli53 rrcreate yourdomain.com myip A $CURRENT_IP --replace --ttl 300
echo "$(date '+%F %T') $CURRENT_IP" &gt;&gt; $IP_LOG
fi;