Update Cloudflare DNS entry
When a system is behind a NAT device that also has a dynamic WAN IP address, it may be necessary to dynamically update a DNS entry on your DNS server. This article shows how to do it by using a simple bash script.
For systems behind a NAT-ed IP, to dynamically change the DNS entry, follow these steps.
Step-by-step guide
- Create a script:
#!/bin/bash
# A bash script to update a Cloudflare DNS A record with the external IP of the source machine
# Used to provide DDNS service for my home
# Needs the DNS record pre-creating on Cloudflare
# Proxy - uncomment and provide details if using a proxy
#export https_proxy=http://<proxyuser>:<proxypassword>@<proxyip>:<proxyport>
# Cloudflare zone is the zone which holds the record
zone=domain.com
# dnsrecord is the A record which will be updated
dnsrecord=name.domain.com
## Cloudflare authentication details
## keep these private
[email protected]
cloudflare_auth_key=somekey
# 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 "X-Auth-Email: $cloudflare_auth_email" \
-H "X-Auth-Key: $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 "X-Auth-Email: $cloudflare_auth_email" \
-H "X-Auth-Key: $cloudflare_auth_key" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$dnsrecord\",\"content\":\"$ip\",\"ttl\":1,\"proxied\":true}" | jq
- run the script with:
bash scriptname.sh
- If successful, results will be similar to thi:
Current IP is XXX.XXX.XXX.XXX
Zoneid for domain.com is zoneid
DNSrecordid for name.domain.com is dnsrecordid
{
"result": {
"id": "id",
"zone_id": "zoneid",
"zone_name": "domain.com",
"name": "name.domain.com",
"type": "A",
"content": "XXX.XXX.XXX.XXX",
"proxiable": true,
"proxied": true,
"ttl": 1,
"locked": false,
"meta": {
"auto_added": false,
"managed_by_apps": false,
"managed_by_argo_tunnel": false,
"source": "primary"
},
"created_on": "2021-01-08T23:57:39.632266Z",
"modified_on": "2021-01-08T23:57:39.632266Z"
},
"success": true,
"errors": [],
"messages": []
}
Following variables/parameters need to be adapted based on the CloudFlare API
keys and DNS
records settings:
zone=domain.com
- this is the domain you want to update
dnsrecord=name.domain.com
- this is the entry that you want to update
[email protected]
- this is the email address used to register an account with CloudFlare
cloudflare_auth_key=somekey
- this is your domain Global API key
Member discussion