Ubuntu Bash Shell Script to update Amazon Route53 for dynamic IP

I host some sites from my home lab (cough cough, one old HP I5 desktop machine), the trouble is, I use amazon route53 and I need to update it when my public IP changes.

I found some information quite a while ago, and with some finessing over time its working nicely, so I thought it would be helpful to share 👍

Overview

  • Save the shell script to something like dynamic_ip.sh
  • Add a crontab job to execute the script and pass in arguments
  • Let it run!

The script

First of all, here is the script:

https://github.com/jcianci12/Route53DynamicIP/blob/main/dynamic_ip.sh

#!/bin/bash
echo "HOSTED_ZONE_ID:$1"
echo "NAME:$2"
echo "TYPE:$3"
echo "TTL:$4"
echo "LOGFILE:$5"

HOSTED_ZONE_ID=$1
NAME=$2
TYPE=$3
TTL=$4
LOGFILE="$NAME.log"

echo "Getting Ip address for $NAME " >> $LOGFILE
#get current IP address
IP=$(curl http://checkip.amazonaws.com/)
echo "IP address is $IP " >> $LOGFILE

#validate IP address (makes sure Route 53 doesn't get updated with a malformed payload)
if [[ ! $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
	exit 1
fi
echo 'IP appears to be valid... proceeding with update'

#get current
echo 'retrieving the current record set from AWS'
aws route53 list-resource-record-sets --hosted-zone-id $HOSTED_ZONE_ID | \
jq -r '.ResourceRecordSets[] | select (.Name == "'"$NAME"'") | select (.Type == "'"$TYPE"'") | .ResourceRecords[0].Value' > /tmp/"$NAME"current_route53_value

cat '/tmp/'$NAME'current_route53_value'
echo 'checking if existing IP address matches actual' >> $LOGFILE
#check if IP is different from Route 53
STOREDIP=$(grep -Fxq "$IP" /tmp/"$NAME"current_route53_value)
echo "Stored ip:"
echo $STOREDIP

echo $STOREDIP >> $LOGFILE

if grep -Fxq "$IP" /tmp/"$NAME"current_route53_value; then
	echo "IP Has Not Changed, Exiting" >> $LOGFILE
	exit 1
fi


echo "IP Changed, Updating Records" >> $LOGFILE

#prepare route 53 payload
cat > /tmp/"$NAME"route53_changes.json << EOF
    {
      "Comment":"Updated From DDNS Shell Script",
      "Changes":[
        {
          "Action":"UPSERT",
          "ResourceRecordSet":{
            "ResourceRecords":[
              {
                "Value":"$IP"
              }
            ],
            "Name":"$NAME",
            "Type":"$TYPE",
            "TTL":$TTL
          }
        }
      ]
    }
EOF

#update records
aws route53 change-resource-record-sets --hosted-zone-id $HOSTED_ZONE_ID --change-batch file:///tmp/"$NAME"route53_changes.json >> $LOGFILE

Usage

You can use this script with the following command (you can run this at the bash prompt):

sh dynamic_ip.sh YOURHOSTEDZONEID YOURDOMAIN.com. A 60

The parameters are as follows:

YOURHOSTEDZONEID

This is the secret id you get from Amazon Route 53

YOURDOMAIN.COM.

This is your domain. notice the . at the end? Its important 😉

A

This is the type of the record in this case we are setting it as A

60

This is the ttl of the record in this case its 60!

Putting it all together with crontab

For scheduling in Ubuntu, crontab is the simple, inbuilt way to go. You can look at your crontab by entering:

crontab -e

Once you are in there you will want to add a line that looks like this (of course, adjust to your own domain details)

* * * * * cd /home/jon && sh sh dynamic_ip.sh YOURHOSTEDZONEID YOURDOMAIN.com. A 60

Once you have made that change, you can exit and save with crontab (usually this is ctrl + x and then make sure you select save changes. Once that is done I usually check by entering crontab -e to make sure the changes have saved.

note -this will run every minute. If you were to change to 1 * * * * this would run the job on the first minute of any hour, day and so on.


Posted

in

,

by

Comments

Leave a Reply

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