Skip to content

Instantly share code, notes, and snippets.

@brandon1024
Last active October 31, 2025 17:37
Show Gist options
  • Select an option

  • Save brandon1024/79f943fb942af6d9d06545e09b676722 to your computer and use it in GitHub Desktop.

Select an option

Save brandon1024/79f943fb942af6d9d06545e09b676722 to your computer and use it in GitHub Desktop.
The Dumbest Dynamic DNS [Route53]

A Dumb Route53 Dynamic DNS Solution

There's really not much to it.

You'll need an AWS Route53 hosted zone and a suitable AWS user. Install and configure AWS CLI. Update ddns-sync.sh variables (DNS_NAME and HOSTED_ZONE_ID) appropriately. Then,

$ cp ddns-sync.sh      ${HOME}
$ cp ddns-sync.service ${HOME}/.config/systemd/user/
$ cp ddns-sync.timer   ${HOME}/.config/systemd/user/
$ systemctl --user enable ddns-sync.service
$ systemctl --user enable ddns-sync.timer
$ systemctl --user start  ddns-sync.timer

If your host's public IP changes, the script will update the DNS route.

Enjoy 😊

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/<YOUR HOSTED ZONE ID>"
]
}
]
}
[Unit]
Description=Sync an AWS Route53 DNS Alias Record to Public Address of Current Host
[Service]
Type=oneshot
ExecStart=%h/ddns-sync.sh
[Install]
WantedBy=default.target
#!/usr/bin/env bash
DNS_NAME=<your ddns name>
HOSTED_ZONE_ID=<your hosted zone id>
# first, fetch current public IPv4 address
RESOLVED_ADDR4="$(dig @8.8.8.8 ${DNS_NAME} +short A)"
ACTUAL_ADDR4="$(curl -s -S -4 https://ipv4.icanhazip.com)"
# next, fetch current public IPv6 address
RESOLVED_ADDR6="$(dig @8.8.8.8 ${DNS_NAME} +short AAAA)"
ACTUAL_ADDR6="$(curl -s -S -6 https://ipv6.icanhazip.com)"
if [[ "${RESOLVED_ADDR4}" == "${ACTUAL_ADDR4}" && "${RESOLVED_ADDR6}" == "${ACTUAL_ADDR6}" ]]; then
exit 0
fi
${HOME}/bin/aws route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID} --change-batch "
{
\"Changes\": [{
\"Action\": \"UPSERT\",
\"ResourceRecordSet\": {
\"Name\": \"${DNS_NAME}\",
\"Type\": \"A\",
\"TTL\": 900,
\"ResourceRecords\":[{
\"Value\": \"${ACTUAL_ADDR4}\"
}]
}
}, {
\"Action\": \"UPSERT\",
\"ResourceRecordSet\": {
\"Name\": \"${DNS_NAME}\",
\"Type\": \"AAAA\",
\"TTL\": 900,
\"ResourceRecords\":[{
\"Value\": \"${ACTUAL_ADDR6}\"
}]
}
}]
}"
echo "info: renewed dynamic DNS records [${DNS_NAME}, hosted zone ${HOSTED_ZONE_ID}]"
echo "info: ip4 [${RESOLVED_ADDR4} -> ${ACTUAL_ADDR4}]"
echo "info: ip6 [${RESOLVED_ADDR6} -> ${ACTUAL_ADDR6}]"
[Unit]
Description=Sync an AWS Route53 DNS Alias Record to Public Address of Current Host
[Timer]
OnBootSec=5min
OnUnitActiveSec=10min
[Install]
WantedBy=timers.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment