-
-
Save Tras2/cba88201b17d765ec065ccbedfb16d9a to your computer and use it in GitHub Desktop.
#!/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=example.com | |
# dnsrecord is the A record which will be updated | |
dnsrecord=www.example.com | |
## Cloudflare authentication details | |
## keep these private | |
cloudflare_auth_email=me@cloudflare.com | |
cloudflare_auth_key=1234567890abcdef1234567890abcdef | |
# 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\":false}" | jq |
Hello guys, can someone tell me how to i find the zone?
I would basically your domain(s) that is defined for the API key.
@namnamir Thank you for the updated script, it works like a charm. I needed to update multiple hostnames and some of those had proxy set to true. I made changes to your script to accommodate. Also, for some reason, the script was timing out on the first section where it grabs the ip from ifconfig so I increased the wait time. It is available here.
Thanks, this was all I needed! ddclient was just overly complicated!
Picking up on the above, have made a few changes to fit my requirements.
- Checks for changes
- Logs each check
- Verifies if new "IP" is of correct format (to eliminate errors)
- Updates multiple entries (proxied and not)
- Logs each change
Now running a cronjob to check and update my DNS records (proxied and not) when there is an IP change, see this repo if looking for similar.
Full article can be found here.
Stripped down IPv4 version based on previous scripts. You'll need jq and curl.
#!/usr/bin/env bash
api_token=<CF token>
email=<CF account email>
zone_name=<DNS zone>
dns_record=<A record FQDN>
set -e
user_id=$(curl -s \
-X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer $api_token" \
-H "Content-Type:application/json" \
| jq -r '{"result"}[] | .id')
zone_id=$(curl -s \
-X GET "https://api.cloudflare.com/client/v4/zones?name=$zone_name&status=active" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: $email" \
-H "Authorization: Bearer $api_token" \
| jq -r '{"result"}[] | .[0] | .id')
record_data=$(curl -s \
-X GET "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?type=A&name=$dns_record" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: $email" \
-H "Authorization: Bearer $api_token")
record_id=$(jq -r '{"result"}[] | .[0] | .id' <<< $record_data)
cf_ip=$(jq -r '{"result"}[] | .[0] | .content' <<< $record_data)
ext_ip=$(curl -s -X GET -4 https://ifconfig.co)
if [[ $cf_ip != $ext_ip ]]; then
result=$(curl -s \
-X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$record_id" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: $email" \
-H "Authorization: Bearer $api_token" \
--data "{\"type\":\"A\",\"name\":\"$dns_record\",\"content\":\"$ext_ip\",\"ttl\":1,\"proxied\":false}" \
| jq .success)
if [[ $result == "true" ]]; then
echo "$dns_record updated to: $ext_ip"
exit 0
else
echo "$dns_record update failed"
exit 1
fi
else
echo "$dns_record already up do date"
exit 0
fi
Liked your stripped down version. Added IPV6, config in separate file, logging and many subdomains.
Im just going to leave my take on this script here. It only supports ipv4 but allows to use the https_proxy funcionality of cloudflare.