Created
January 26, 2017 22:05
-
-
Save venator85/0b677e535dd35e2cd02c54ed445221ed to your computer and use it in GitHub Desktop.
Custom AsusWRT DDNS script for AWS Route53
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 | |
# note: when debugging on PC/MAC, this script must be run with bash | |
# Custom AsusWRT DDNS script for AWS Route53 - v1.0 | |
# Author: Alessio Bianchi <[email protected]> | |
# Credits: http://czak.pl/2015/09/15/s3-rest-api-with-curl.html | |
ACCESS_KEY_ID="XXXXXXXXXXXXXXXXXXXX" | |
SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
# These keys can be associated to a IAM user with the following policy: | |
# { | |
# "Version": "2012-10-17", | |
# "Statement": [ | |
# { | |
# "Sid": "Stmt1440351730000", | |
# "Effect": "Allow", | |
# "Action": [ | |
# "route53:ChangeResourceRecordSets", | |
# "route53:GetHostedZone", | |
# "route53:ListHostedZones", | |
# "route53:ListResourceRecordSets" | |
# ], | |
# "Resource": [ | |
# "*" | |
# ] | |
# } | |
# ] | |
# } | |
REGION="us-east-1" # fixed for route53 | |
SERVICE="route53" | |
API_HOST="route53.amazonaws.com" | |
HOSTED_ZONE_ID="ZXXXXXXXXXXXX" | |
NAME="my.domain.com." | |
RESOURCE_TYPE="A" | |
TTL=300 | |
MAILGUN_API_KEY="key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
MAILGUN_DOMAIN="domain.com" | |
MAILGUN_FROM_ADDRESS="[email protected]" | |
MAILGUN_TO_ADDRESS="[email protected]" | |
# ---- | |
IFS= | |
DATE=$(date -u +"%Y%m%dT%H%M%SZ") | |
DATE_SHORT=$(date -u +"%Y%m%d") | |
OPENSSL="openssl" | |
SED="sed" | |
os=$(uname) | |
if [ "$os" == "Darwin" ]; then # for debugging on macOS | |
OPENSSL="/usr/local/Cellar/openssl/1.0.2j/bin/openssl" # from HomeBrew: brew install openssl | |
SED="gsed" # from HomeBrew: brew install gnu-sed | |
fi | |
EXTERNAL_IP="$1" | |
sha256() { | |
data="$1" | |
echo -n "${data}" | ${OPENSSL} dgst -sha256 | sed 's/^.* //' | |
} | |
hmac_sha256() { | |
key="$1" | |
data="$2" | |
echo -n "${data}" | ${OPENSSL} dgst -sha256 -mac HMAC -macopt "${key}" | sed 's/^.* //' | |
} | |
buildSigningKey() { | |
service="$1" | |
dateKey=$(hmac_sha256 "key:AWS4${SECRET_ACCESS_KEY}" "${DATE_SHORT}") | |
dateRegionKey=$(hmac_sha256 "hexkey:${dateKey}" "${REGION}") | |
dateRegionServiceKey=$(hmac_sha256 "hexkey:${dateRegionKey}" "${service}") | |
hmac_sha256 "hexkey:${dateRegionServiceKey}" "aws4_request" | |
} | |
buildCreq() { | |
HTTPMethod="$1" | |
CanonicalURI="$2" | |
CanonicalQueryString="$3" | |
CanonicalHeaders="$4" | |
SignedHeaders="$5" | |
Payload="$6" | |
hashedPayload=$(sha256 "${Payload}") | |
printf "%s\n%s\n%s\n%s\n\n%s\n%s" "${HTTPMethod}" "${CanonicalURI}" "${CanonicalQueryString}" "${CanonicalHeaders}" "${SignedHeaders}" "${hashedPayload}" | |
} | |
buildSts() { | |
creq="$1" | |
scope="$2" | |
CanonicalRequestHash=$(sha256 "${creq}") | |
printf "AWS4-HMAC-SHA256\n%s\n%s\n%s" "${DATE}" "${scope}" "${CanonicalRequestHash}" | |
} | |
signSts() { | |
sts="$1" | |
signingKey="$2" | |
hmac_sha256 "hexkey:${signingKey}" "${sts}" | |
} | |
bodyTemplate='<ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/"><ChangeBatch><Changes><Change><Action>UPSERT</Action><ResourceRecordSet><Name>%s</Name><Type>%s</Type><TTL>%d</TTL><ResourceRecords><ResourceRecord><Value>%s</Value></ResourceRecord></ResourceRecords></ResourceRecordSet></Change></Changes></ChangeBatch></ChangeResourceRecordSetsRequest>' | |
body=$(printf "${bodyTemplate}" "${NAME}" "${RESOURCE_TYPE}" "${TTL}" "${EXTERNAL_IP}") | |
canonicalHeaders=$(printf 'host:%s\nx-amz-date:%s' "${API_HOST}" "${DATE}") | |
signedHeaders="host;x-amz-date" | |
req="/2013-04-01/hostedzone/${HOSTED_ZONE_ID}/rrset" | |
creq=$(buildCreq "POST" "${req}" "" "${canonicalHeaders}" "${signedHeaders}" "${body}") | |
#echo -e "creq:\n${creq}\n" | |
scope="${DATE_SHORT}/${REGION}/${SERVICE}/aws4_request" | |
sts=$(buildSts "${creq}" "${scope}") | |
#echo -e "sts:\n${sts}\n" | |
signingKey=$(buildSigningKey ${SERVICE}) | |
#echo -e "signingKey:\n${signingKey}\n" | |
signature=$(signSts "${sts}" "${signingKey}") | |
#echo -e "signature:\n${signature}\n" | |
authorizationHeader=$(printf "Authorization: AWS4-HMAC-SHA256 Credential=%s/%s, SignedHeaders=%s, Signature=%s" "${ACCESS_KEY_ID}" "${scope}" "${signedHeaders}" "${signature}") | |
#echo -e "authorizationHeader:\n${authorizationHeader}\n" | |
req_output=$(curl -i "https://${API_HOST}${req}" -d "${body}" -H "${authorizationHeader}" -H "x-amz-date: ${DATE}" -H "Content-Type: application/xml" 2>&1) | |
status_code=$(echo ${req_output} | grep 'HTTP/1.1' | ${SED} -r 's/.*? ([0-9]+) .*?/\1/g') | |
if [ ${status_code} -ne 200 ]; then | |
mailMsg=$(printf "There was an error updating %s to IP address %s.\n\n%s" "${NAME}" "${EXTERNAL_IP}" "${req_output}") | |
curl -i --user "api:${MAILGUN_API_KEY}" \ | |
https://api.mailgun.net/v3/${MAILGUN_DOMAIN}/messages \ | |
-F from="AsusWRT Route53 DDNS <${MAILGUN_FROM_ADDRESS}>" \ | |
-F to="${MAILGUN_TO_ADDRESS}" \ | |
-F subject="[${NAME}] Route53 DDNS update failure" \ | |
-F text="${mailMsg}" 2>&1 | logger | |
/sbin/ddns_custom_updated 0 | |
else | |
/sbin/ddns_custom_updated 1 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment