A simple utility to update an existing DNS record on Cloudflare when the public IP changes.
The main working is in the ddns
script.
The script gets the public IP from ipinfo.io/ip and conducts a rudimentary IP RegEx check.
The script stores the previously used public IP address in a file called
public-ip-in-use.txt
. (Obviously this file does not exist when the script is
run for the first time.)
The script compares the newly found public IP address and the previously used
IP address stored in public-ip-in-use.txt
. If the IP addresses are the same,
then it does nothing, but if the IP addresses don't match, it replaces the IP
address in the public-ip-in-use.txt
file with the newly found IP address, and
updates it on Cloudflare as well.
A CRON job runs this script every 10 minutes, so that the DNS record on Cloudflare always has the current public IP address.
-
Clone the repository.
$ cd ~ $ git clone https://github.com/HarshKapadia2/dynamic-dns.git
-
On the Cloudflare dashboard, create a new
A
record with a dummy IP address. Turn off Cloudflare's proxying for that DNS record and leave it at 'DNS Only'. -
In the repository, create two files
run-ddns
andlist-all-dns-records
, add content to it as described in therun-ddns
andlist-all-dns-records
sections, and give them executable permissions.$ cd ~/dynamic-ddns $ vim run-ddns # Add content from the 'run-ddns' section below. $ vim list-all-dns-records # Add content from the 'list-all-dns-records' section below. $ sudo chmod +x run-ddns $ sudo chmod +x list-all-dns-records
-
Run the
list-all-dns-records
script and make a note of the Record ID of the DNS record to be updated. Add that to therun-ddns
script. -
Follow the instructions in the 'CRON Script' section to set up a CRON job that will run the
run-ddns
script periodically, so that the DNS record on Cloudflare always has the current public IP address.
This script is used to provide sensitive variables to the ddns
script
and then run it.
NOTE:
- Cloudflare Zone ID
- Cloudflare API Token
- The Cloudflare Record ID can be found by running the
list-all-dns-records
script.
#! /bin/bash
set -Eeuo pipefail
# Set 'dynamic-dns' repository directory path
ddns_repo_path="$(dirname "$0")"
if [[ "${ddns_repo_path}" == "." ]]; then
ddns_repo_path="$(pwd)"
fi
# Provide environment variables and run `ddns` script
CLOUDFLARE_ZONE_ID="<zone_id_here>" \
CLOUDFLARE_AUTH_KEY="<api_token_here>" \
CLOUDFLARE_DNS_RECORD_NAME="<[subdomain.]domainname.tld>" \
CLOUDFLARE_DNS_RECORD_ID="<id_of_record_to_be_updated_here>" \
bash "${ddns_repo_path}/ddns"
In Ubuntu, this script is to be placed at /etc/cron.d/dynamic-dns
. It runs a
CRON job every 10 minutes to run the run-ddns
script.
NOTE: Replace the
HOME
variable with the path to thedynamic-dns
repo location. Also, replace the<username>
with the name of the user that should run the script (root
or any other user).
# This is to set up a public IP address.
SHELL=/bin/bash
HOME=/home/harsh/dynamic-dns
#
*/10 * * * * <username> ./run-ddns
This script lists information about all DNS records. It is used to to get the
Record ID of the DNS record that needs to be updated by the ddns
script.
NOTE:
#! /bin/bash
set -Eeuo pipefail
CLOUDFLARE_ZONE_ID="<zone_id_here>"
CLOUDFLARE_AUTH_KEY="<api_token_here>"
curl --request GET \
--url "https://api.cloudflare.com/client/v4/zones/${CLOUDFLARE_ZONE_ID}/dns_records" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${CLOUDFLARE_AUTH_KEY}"