aboutsummaryrefslogtreecommitdiff
path: root/content/blog/2022-03-23-cloudflare-dns-api.org
diff options
context:
space:
mode:
authorChristian Cleberg <hello@cleberg.net>2024-07-28 19:46:20 -0500
committerChristian Cleberg <hello@cleberg.net>2024-07-28 19:46:20 -0500
commit2be43cc479dfd4cfb621f14381330c708291e324 (patch)
tree7ac50f99425c5524c0820360754045b80d1bafcc /content/blog/2022-03-23-cloudflare-dns-api.org
parentafe76ac7d7498b862abaa623790b91410e34574d (diff)
downloadcleberg.net-2be43cc479dfd4cfb621f14381330c708291e324.tar.gz
cleberg.net-2be43cc479dfd4cfb621f14381330c708291e324.tar.bz2
cleberg.net-2be43cc479dfd4cfb621f14381330c708291e324.zip
conversion from Zola to Weblorg
Diffstat (limited to 'content/blog/2022-03-23-cloudflare-dns-api.org')
-rw-r--r--content/blog/2022-03-23-cloudflare-dns-api.org193
1 files changed, 193 insertions, 0 deletions
diff --git a/content/blog/2022-03-23-cloudflare-dns-api.org b/content/blog/2022-03-23-cloudflare-dns-api.org
new file mode 100644
index 0000000..bc17945
--- /dev/null
+++ b/content/blog/2022-03-23-cloudflare-dns-api.org
@@ -0,0 +1,193 @@
+#+date: <2022-03-23>
+#+title: Dynamic DNS with Cloudflare API
+#+description:
+
+
+* DDNS: Dynamic DNS
+:PROPERTIES:
+:CUSTOM_ID: ddns-dynamic-dns
+:END:
+If you're hosting a service from a location with dynamic DNS (where your
+IP may change at any time), you must have a solution to update the DNS
+so that you can access your service even when the IP of the server
+changes.
+
+The process below uses the [[https://api.cloudflare.com/][Cloudflare
+API]] to update DNS =A= and =AAAA= records with the server's current IP.
+If you use another DNS provider, you will have to find a way to update
+your DNS (or find a way to get a static IP).
+
+First, install =jq= since we will use it in the next script:
+
+#+begin_src sh
+sudo apt install jq
+#+end_src
+
+Next, create a location for your DDNS update scripts and open the first
+script:
+
+#+begin_src sh
+mkdir ~/ddns
+nano ~/ddns/update.sh
+#+end_src
+
+The following =update.sh= script will take all of your domains and
+subdomains and check Cloudflare to see if the current =A= and =AAAA=
+records match your server's IP address. If not, it will update the
+records.
+
+#+begin_src sh
+# file: update.sh
+#!/bin/bash
+
+# Update TLDs
+domains=(example.com example.net)
+
+for domain in "${domains[@]}"
+do
+ echo -e "\nUpdating $domain..."
+ zone_name=$domain /home/<your-username>/ddns/ddns.sh
+done
+
+# Update subdomains for example.com
+domain=example.com
+subdomains=(photos.example.com)
+
+for subdomain in "${subdomains[@]}"
+do
+ echo -e "\nUpdating $subdomain..."
+ zone_name=$domain dns_record=$subdomain /home/<your-username>/ddns/ddns.sh
+done
+#+end_src
+
+Next, open up the =ddns.sh= script. Paste the following into the script
+and update the =api_token= and =email= variables.
+
+#+begin_src sh
+nano ~/ddns/ddns.sh
+#+end_src
+
+*Note*: If you want your DNS records to be proxied through Cloudflare,
+find and update the following snippet: ="proxied":false}"= to say =true=
+instead of =false=.
+
+#+begin_src sh
+# file: ddns.sh
+#!/bin/bash
+# based on https://gist.github.com/Tras2/cba88201b17d765ec065ccbedfb16d9a
+# initial data; they need to be filled by the user
+## API token
+api_token=<YOUR_API_TOKEN>
+## email address associated with the Cloudflare account
+email=<YOUR_EMAIL>
+
+# get the basic data
+ipv4=$(curl -s -X GET -4 https://ifconfig.co)
+ipv6=$(curl -s -X GET -6 https://ifconfig.co)
+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'
+ )
+
+echo "Your IPv4 is: $ipv4"
+echo "Your IPv6 is: $ipv6"
+
+# check if the user API is valid and the email is correct
+if [ $user_id ]
+then
+ 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'
+ )
+ # check if the zone ID is
+ if [ $zone_id ]
+ then
+ # check if there is any IP version 4
+ if [ $ipv4 ]
+ then
+ dns_record_a_id=$(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"
+ )
+ # if the IPv6 exist
+ dns_record_a_ip=$(echo $dns_record_a_id | jq -r '{"result"}[] | .[0] | .content')
+ echo "The set IPv4 on Cloudflare (A Record) is: $dns_record_a_ip"
+ if [ $dns_record_a_ip != $ipv4 ]
+ then
+ # change the A record
+ curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$(echo $dns_record_a_id | jq -r '{"result"}[] | .[0] | .id')" \
+ -H "Content-Type: application/json" \
+ -H "X-Auth-Email: $email" \
+ -H "Authorization: Bearer $api_token" \
+ --data "{"type":"A","name":"$dns_record","content":"$ipv4","ttl":1,"proxied":false}" \
+ | jq -r '.errors'
+ else
+ echo "The current IPv4 and DNS record IPv4 are the same."
+ fi
+ else
+ echo "Could not get your IPv4. Check if you have it; e.g. on https://ifconfig.co"
+ fi
+
+ # check if there is any IP version 6
+ if [ $ipv6 ]
+ then
+ dns_record_aaaa_id=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?type=AAAA&name=$dns_record" \
+ -H "Content-Type: application/json" \
+ -H "X-Auth-Email: $email" \
+ -H "Authorization: Bearer $api_token"
+ )
+ # if the IPv6 exist
+ dns_record_aaaa_ip=$(echo $dns_record_aaaa_id | jq -r '{"result"}[] | .[0] | .content')
+ echo "The set IPv6 on Cloudflare (AAAA Record) is: $dns_record_aaaa_ip"
+ if [ $dns_record_aaaa_ip != $ipv6 ]
+ then
+ # change the AAAA record
+ curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$(echo $dns_record_aaaa_id | jq -r '{"result"}[] | .[0] | .id')" \
+ -H "Content-Type: application/json" \
+ -H "X-Auth-Email: $email" \
+ -H "Authorization: Bearer $api_token" \
+ --data "{"type":"AAAA","name":"$dns_record","content":"$ipv6","ttl":1,"proxied":false}" \
+ | jq -r '.errors'
+ else
+ echo "The current IPv6 and DNS record IPv6 are the same."
+ fi
+ else
+ echo "Could not get your IPv6. Check if you have it; e.g. on https://ifconfig.co"
+ fi
+ else
+ echo "There is a problem with getting the Zone ID. Check if the Zone Name is correct."
+ fi
+else
+ echo "There is a problem with either the email or the password"
+fi
+#+end_src
+
+Once the script is saved and closed, make the scripts executable:
+
+#+begin_src sh
+chmod +x ~/ddns/ddns.sh
+chmod +x ~/ddns/update.sh
+#+end_src
+
+You can test the script by running it manually:
+
+#+begin_src sh
+./update.sh
+#+end_src
+
+To make sure the scripts run automatically, add it to the =cron= file so
+that it will run on a schedule. To do this, open the cron file:
+
+#+begin_src sh
+crontab -e
+#+end_src
+
+In the cron file, paste the following at the bottom of the editor:
+
+#+begin_src sh
+,*/5 ** ** ** ** bash /home/<your_username>/ddns/update.sh
+#+end_src