Last active
December 10, 2015 13:49
-
-
Save pboos/4443466 to your computer and use it in GitHub Desktop.
Script to update dns on Route 53. Original script by Johan Lindh with some changes to allow root A record update with "" for hostname.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# This script will perform a DynDNS-like function for Amazon's Route 53 | |
# | |
# Author: Johan Lindh <[email protected]> | |
# http://www.linkdata.se/ | |
# | |
# Script requirements: | |
# | |
# wget | |
# grep | |
# sed | |
# dig | |
# cut | |
# openssl | |
# base64 | |
# | |
# Most if not all of these come standard on *nix distros. | |
# | |
if [ "$#" != "5" ]; then | |
echo "Usage: dnsupdate.sh <awsid> <awskey> <zoneid> <hostname> <domain>" | |
echo "Sample: dnsupdate.sh 12345678901234 m29a39sk349a/as03/asdf Z0000000000 home domain.com" | |
exit 1 | |
fi | |
# The domain and host name to update | |
# and the desired TTL of the record | |
Domain=$5 | |
Hostname=$4 | |
NewTTL=600 | |
# The Amazon Route 53 zone ID for the domain | |
# and the Amazon ID and SecretKey. Remember to | |
# ensure that this file can't be read by | |
# unauthorized people! | |
ZoneID=$3 | |
AmazonID=$1 | |
SecretKey=$2 | |
# Enter the URL used to check extern IP | |
CheckIPURL='http://checkip.dyndns.com/' | |
# Enter some static text that immediately preceeds the current IP in the HTML output | |
# Note that you'll probably need to look at the actual HTML code to find this | |
CheckIPText='Current IP Address:' | |
############################################################### | |
# You should not need to change anything beyond this point | |
############################################################### | |
DNSFullName="$Hostname.$Domain" | |
DNSFullNameForGrep="$Hostname\.$Domain" | |
if [ "$Hostname" = "" ]; then | |
DNSFullName="$Domain" | |
DNSFullNameForGrep="$Domain" | |
fi | |
# Retrieve the current IP | |
CurrentIP=$(wget "$CheckIPURL" -o /dev/null -O /dev/stdout | grep "$CheckIPText" | sed 's/.*[^0-9]\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)[^0-9].*/\1/') | |
# Find an authoritative AWS R53 nameserver so we get a clean TTL | |
AuthServer=$(dig NS $Domain | grep -v ';' | grep -m 1 awsdns | grep $Domain | cut -f 6) | |
if [ "$AuthServer" = "NS"]; then | |
# For short domains like pes.ch it is cut-f 7 | |
AuthServer=$(dig NS $Domain | grep -v ';' | grep -m 1 awsdns | grep $Domain | cut -f 7) | |
fi | |
if [ "$AuthServer" = "" ]; then | |
echo The domain $Domain has no authoritative Amazon Route 53 name servers | |
exit 1 | |
fi | |
# Get the record and extract its parts | |
Record=$(dig @$AuthServer A $DNSFullName | grep -v ";" | grep "$DNSFullNameForGrep") | |
OldType=$( echo $Record | cut -d ' ' -f 4 ) | |
OldTTL=$( echo $Record | cut -d ' ' -f 2 ) | |
OldIP=$( echo $Record | cut -d ' ' -f 5 ) | |
# Make sure it is an A record (could be CNAME) | |
if [ "$Record" != "" -a "$OldType" != "A" ]; then | |
echo $DNSFullName has a $OldType record, expected 'A' | |
exit 1 | |
fi | |
# Changeset preamble | |
Changeset="" | |
Changeset=$Changeset"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
Changeset=$Changeset"<ChangeResourceRecordSetsRequest xmlns=\"https://route53.amazonaws.com/doc/2010-10-01/\">" | |
Changeset=$Changeset"<ChangeBatch><Comment>Update $DNSFullName</Comment><Changes>" | |
if [ "$OldIP" != "" ]; then | |
# Add a DELETE request to the changeset | |
Changeset=$Changeset"<Change>" | |
Changeset=$Changeset"<Action>DELETE</Action>" | |
Changeset=$Changeset"<ResourceRecordSet>" | |
Changeset=$Changeset"<Name>$DNSFullName.</Name>" | |
Changeset=$Changeset"<Type>A</Type>" | |
Changeset=$Changeset"<TTL>$OldTTL</TTL>" | |
Changeset=$Changeset"<ResourceRecords>" | |
Changeset=$Changeset"<ResourceRecord>" | |
Changeset=$Changeset"<Value>$OldIP</Value>" | |
Changeset=$Changeset"</ResourceRecord>" | |
Changeset=$Changeset"</ResourceRecords>" | |
Changeset=$Changeset"</ResourceRecordSet>" | |
Changeset=$Changeset"</Change>" | |
fi | |
# Add CREATE request to the changeset | |
Changeset=$Changeset"<Change>" | |
Changeset=$Changeset"<Action>CREATE</Action>" | |
Changeset=$Changeset"<ResourceRecordSet>" | |
Changeset=$Changeset"<Name>$DNSFullName.</Name>" | |
Changeset=$Changeset"<Type>A</Type>" | |
Changeset=$Changeset"<TTL>$NewTTL</TTL>" | |
Changeset=$Changeset"<ResourceRecords>" | |
Changeset=$Changeset"<ResourceRecord>" | |
Changeset=$Changeset"<Value>$CurrentIP</Value>" | |
Changeset=$Changeset"</ResourceRecord>" | |
Changeset=$Changeset"</ResourceRecords>" | |
Changeset=$Changeset"</ResourceRecordSet>" | |
Changeset=$Changeset"</Change>" | |
# Close the changeset | |
Changeset=$Changeset"</Changes>" | |
Changeset=$Changeset"</ChangeBatch>" | |
Changeset=$Changeset"</ChangeResourceRecordSetsRequest>" | |
if [ "$OldIP" != "$CurrentIP" ]; then | |
# Get the date at the Amazon servers | |
CurrentDate=$(wget -q -S https://route53.amazonaws.com/date -O /dev/null 2>&1 | grep Date | sed 's/.*Date: //') | |
# Calculate the SHA1 hash and required headers | |
Signature=$(echo -n $CurrentDate | openssl dgst -binary -sha1 -hmac $SecretKey | base64) | |
DateHeader="Date: "$CurrentDate | |
AuthHeader="X-Amzn-Authorization: AWS3-HTTPS AWSAccessKeyId=$AmazonID,Algorithm=HmacSHA1,Signature=$Signature" | |
# Submit request | |
Result=$(wget -nv --header="$DateHeader" --header="$AuthHeader" --header="Content-Type: text/xml; charset=UTF-8" --post-data="$Changeset" -O /dev/stdout -o /dev/stdout https://route53.amazonaws.com/2010-10-01/hostedzone/$ZoneID/rrset) | |
if [ "$?" -ne "0" ]; then | |
echo "Failed to update $DNSFullName: "$Result | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment