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" >> $IP_LOG fi; |