A few years back I subscribed to a discounted dynamic DNS service - which has been very useful tbh. It was time to renew (or keep updating those hosts manually each month), then realized I could do my own thing for a fraction of the service subscription cost (and the domain name would be mine for as long as I needed).
My solutions consists on a AWS account making use of route53, a domain purchased from namescheap and a cron job. For dynamic dns on surveillance cameras or storage appliances this might not work out of the box.
First thing, the domain. I wanted something super cheap and found an offer of less than a euro per year for a ".site" domain:
Went straight for 5 years, which was something around 5 euros.
I already had a working AWS account, if not you can find the steps in Amazon Web Services site.
Create a route53 public zone, with the name of the domain you purchased:
Configure your hosting to make use of the DNS servers provided by AWS (red box):
Now we have to configure an IAM user capable of updating the DNS records. Go to IAM accounts, groups, create a new one (i.e. dnsupdater) and provide a security policy similar to this one (depending on your needs):
{Create a user, get the keys and add it to the group.
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:Get*",
"route53:List*",
"route53:Update*",
"route53:ChangeResourceRecordSets",
"route53:TestDNSAnswer"
],
"Resource": [
"*"
]
}
]
}
In your computer, install AWS cli tools with pip install awscli and follow the console instructions to use your credentials.
Setting up the script, I have two files in the folder; template.json and updatedns.sh
The template looks as follows:
{
"Comment": "Updated record",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "home.mytest.site",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "XXX.XXX.XXX.XXX"
}
]
}
}
]
}
You'll have to enter your zone ID in the script:
#!/bin/bash
hostname="home.mystest.site"
current=`host home.mytest.site | awk '{ print $4}'`
external_ip=`curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//'`
template="/opt/scripts/dns/template.json"
zone_id="/hostedzone/<enter your zone ID>"
dns_template="/opt/scripts/dns/template.json"
echo "My DNS: $current"
echo "My IP: $external_ip"
if [ $current != $external_ip ]; then
echo "updating zone!"
sed -i -E "s/\"Value\"\: \".+\"/\"Value\": \"$external_ip\"/g" $dns_template
aws route53 change-resource-record-sets --hosted-zone-id $zone_id --change-batch file://$dns_template
fi
Then add it as a cronjob:
$ crontab -l
*/30 * * * * /opt/scripts/dns/updatedns.sh > /dev/null
All set !