Skip to main content

Dynamic DNS

If you don't have a static IP address you'll need to update your DNS records every time your IP address changes. This is called dynamic DNS. There are service providers that offer dynamic DNS services, but it's possible to do it yourself as well.

The process is simple. You write a script that checks your IP address ever x minutes and updates your DNS records accordingly. To make this work, you'll need a programmatic way to update your DNS records. In most cases, this is through an API and most service providers offer a free API. The following is a script that could be used if you're using Cloudflare, but the same general process can be used with any other service provider.

#!/bin/bash

zone=example.com
dnsrecord=node1
cloudflare_auth_key=yOuR_aUtH_kEy-gOes_hEre
ZONEID=some-zone-id

# Get the current external IP address
ip=$(curl -s -X GET https://checkip.amazonaws.com)

echo "Current IP is $ip"

if host $dnsrecord 1.1.1.1 | grep "has address" | grep "$ip"; then
echo "$dnsrecord is currently set to $ip; no changes needed"
exit
fi

# if here, the dns record needs updating

# get the zone id for the requested zone
# zoneid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone&status=active" \
# -H "X-Auth-Email: $cloudflare_auth_email" \
# -H "X-Auth-Key: $cloudflare_auth_key" \
# -H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')

# echo "Zoneid for $zone is $zoneid"

# get the dns record id
dnsrecordid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?type=A&name=$dnsrecord" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')

echo "DNSrecordid for $dnsrecord is $dnsrecordid"

# update the record
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$dnsrecordid" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$dnsrecord\",\"content\":\"$ip\",\"ttl\":1,\"proxied\":false}" | jq

# export DNS_INFO=$(curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records" \
# -H "Authorization: Bearer $CFKEY" \
# -H "Content-Type: application/json" \
# --data '{"type":"A","name":'\""$DNSNAME"\"',"content":'\""$IPADDR"\"',"ttl":3600,"priority":10,"proxied":false}')


# curl -X PUT "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE/dns_records/$CLOUDFLARE_RECORD_ID" \
# -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
# -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
# -H "Content-Type: application/json" \
# --data '{"type":"A","name":"$CLOUDFLARE_HOSTNAME","content":"$LOCAL_IP","ttl":3600,"proxied":false}'