Preface
Full tutorial on how to update DigitalOcean’s DNS (Domain Name Servers) by utilizing Bash scripting. You can observe how I will use Bash to update all the domains and subdomains I own in automated way using Crontab. If you have dynamic IP and host a service at home, these will help you to point your hosting service’s DNS records at your home server(s).
Requirements
API Token
Login to Digital Ocean and generate your API key.
Domain Names
Take a note of all the domain names from your account that has to be updated with new public IP.
Collect All The Record IDs For Each Domain
For each domain, eg example1.com, you can have multiple subdomains. It can be the same for example2.com and so on. Grab every record ID for each domain and subdomain with this Bash script.
Create get_record_ids.sh Bash File
Execute this command to create a bash file.
$ nano get_record_ids.sh
Insert the code into the file.
# !/bin/bash
# SpawnTerror 2021
# Get domains record ids from DigitalOcean
# Usage:
# sudo ./get_record_ids.sh YOUR_DOMAIN_NAME
# Igonre all records with NS = nameservers
# Insert all other required record IDs to update_digital_ocean.sh
# Insert all required domain names to update_digital_ocean.sh
# Insert your TOKEN to communicate with DigitalOcean APIv2
# Execute updater:
# sudo ./update_digital_ocean.sh
# Add the update script to crontab -e
#
# Visit nodetwelve.com for more information
[[ -z "$1" ]] && { echo "Usage: sudo ./get_record_ids example.com"; exit 1; }
curl GET -H "Content-Type: application/json" \
-H "Authorization: Bearer INSERT_YOUR_TOKEN_HERE" \
https://api.digitalocean.com/v2/domains/$1/records | json_pp | grep -E "id|name|type"
Execute this command to make it executable and run it.
$ chmod u+x get_record_ids.sh
Collect Record IDs
Execute the file with a parameter for each domain the you have from previous step.
$ ./get_record_ids.sh example1.com
$ ./get_record_ids.sh example2.com
$ ./get_record_ids.sh example3.com
Note down all the required entries of type A record. Do not update the NS (nameserver) types. Here is a sample output:
# ./get_record_ids.sh example1.com
"id" : 117631233, # we don't want SOA (Start Of Authority)
"name" : "@",
"type" : "SOA",
"id" : 117499983, # we don't want NS (nameserver record)
"name" : "@",
"type" : "NS",
"id" : 117636906, # we don't want NS (nameserver record)
"name" : "@",
"type" : "NS",
"id" : 117634913, # we don't want NS (nameserver record)
"name" : "@",
"type" : "NS",
"id" : 117634903, # A record for example1.com
"name" : "@",
"type" : "A",
"id" : 117634912, # A record for www.example1.com
"name" : "www",
"type" : "A",
"id" : 117634283, # A record for blog.example1.com
"name" : "blog",
"type" : "A",
"id" : 117612323, # A record for store.example1.com
"name" : "store",
"type" : "A",
"id" : 117634323,
"name" : "www.blog", # A record for www.blog.example1.com
"type" : "A",
Explanation
We only collect A records for every subdomain and domain. You never update nameserver records. You never update SOA (Start Of Authority) records either.
Create Update Script
With all the data we have:
- 3 domain names (example1.com, example2.com, example3.com
- API token from DigitalOcean
- All the domain and subdomain records
It is time to create update script in bash.
Create update_digital_ocean.sh Bash File
Execute this command to create a bash file.
$ nano update_digital_ocean.sh
Insert the code into the file.
#!/bin/bash
# SpawnTerror 2021
# Update DigitalOcen DNS Records
# Usage:
# Run get_record_ids.sh script to get RECORD IDS of your
# domains/subdomains
# Get API token from DigitalOcean website
# Update TOKEN
# Update DOMAIN… (add more or delete as required)
# Update RECORD… (add more or delete as required)
#
# Visit nodetwelve.com for more information
# Variables
TOKEN="insert_your_TOKEN_here"
LOG_FILE="/home/YOUR_USERNAME/digital_ocean_update_logs.txt"
# Records
DOMAIN1="example1.com"
RECORD_A1="112176990" # example1.com
RECORD_A2="112177021" # www.example1.com
RECORD_A3="113300718" # blog.example1.com
RECORD_A4="127939656" # www.blog.example1.com
RECORD_A5="117087411" # store.example1.com
# add example2.com and so on, if required
# DOMAIN2="example2.com"
# RECORD_B1="107526235" # www.example2.com
# RECORD_B2="107939442" # example2.com
# Get current public IP and compare with last one in the log file
# If not the same, update all records at DigitalOcean.
DETECTED="$(dig +short myip.opendns.com @resolver1.opendns.com)"
PREVIOUS="$(tail -1 $LOG_FILE | awk -F, '{print $2}')"
if [ "$DETECTED" = "$PREVIOUS" ]
then
echo "Previous IP -> ($PREVIOUS)."
echo "Detected IP -> ($DETECTED)."
echo "No change detected, exiting."
else
echo "Previous IP -> ($PREVIOUS)."
echo "Detected IP -> ($DETECTED)."
echo "New public IP detected, updating DigitalOcean records…" && echo
echo "$(date),$DETECTED" >> "$LOG_FILE"
# example1.com
curl -X PUT -H "Content-Type: application/json" -H \ "Authorization: Bearer $TOKEN" -d '{"data":"'"$DETECTED"'"}' \ "https://api.digitalocean.com/v2/domains/$DOMAIN1/records/$RECORD_A1"
# Copy and paste above line changing $RECORD_A1 with all records
# Then change $DOMAIN1 with next one and all records
fi
Execute this command to make it executable and run it.
$ chmod u+x update_digital_ocean.sh
Script is saved and executable.
Initial Run Of Update Script
Run the script first time to create log file. It will throw an error, because the log file doesn’t exist yet.
$ ./update_digital_ocean.sh
Run it again and it will exit normally. That’s it.
Create Cronjob To Automate The Task
One of the options is to create a job in Crontab to automate the updating of DNS records on DigitalOcean backend.
To run the script every 15 minutes, use this command:
*/15 * * * * /path/to/script/update_digital_ocean.sh
Add this command at the bottom of the crontab and save.
crontab -e
Change The Frequency Of The Task
You can use online generator to change 15 minutes to any time you want. I wouldn’t use anything lower than 5 minutes, otherwise it may cause bother to DigitalOcean backend.