A minimal Bash script to keep A and AAAA records up-to-date on Cloudflare using their v4 API. The script loads its configuration from the file cloudflare-dns.conf in the same directory as the script.
Features:
- Update multiple domains and subdomains in a single run
- Independent IPv4/IPv6 configuration per subdomain
- Enable/disable IPv4 or IPv6 for specific subdomains
- Support for root domain updates using
@
-
Clone or download this repository.
-
Copy the example config and edit it with your settings:
cp cloudflare-dns.conf.example cloudflare-dns.conf vim cloudflare-dns.conf
Set at least:
CF_API_TOKEN– your Cloudflare API tokenDOMAINS– array of domains to manage (e.g.("example.com"))DOMAIN_<name>_IPV4_SUBDOMAINS– subdomains to update with IPv4DOMAIN_<name>_IPV6_SUBDOMAINS– subdomains to update with IPv6
Example configuration:
DOMAINS=("example.com") DOMAIN_example_com_IPV4_SUBDOMAINS=("www" "@" "home") DOMAIN_example_com_IPV6_SUBDOMAINS=("www" "@")
-
Make the script executable and run it:
chmod +x cloudflare-dns.sh ./cloudflare-dns.sh
The script will:
- Detect your current public IPv4/IPv6 addresses
- Process each domain and subdomain in your configuration
- Create DNS records if they don't exist
- Update records only when the IP changes
Create a restricted token with Zone → DNS → Edit and Zone → Zone → Read permissions:
For extra security, choose Include → Specific Zone and select the zone you plan to update.
Add multiple domains to the DOMAINS array:
DOMAINS=("example.com" "anotherdomain.net")For each domain, define separate subdomain lists for IPv4 and IPv6:
# example.com configuration
DOMAIN_example_com_IPV4_SUBDOMAINS=("www" "@" "home")
DOMAIN_example_com_IPV6_SUBDOMAINS=("www" "@")
# anotherdomain.net configuration (dots become underscores)
DOMAIN_anotherdomain_net_IPV4_SUBDOMAINS=("blog" "mail")
DOMAIN_anotherdomain_net_IPV6_SUBDOMAINS=("blog")To enable IPv4 for specific subdomains:
Add them to the IPV4_SUBDOMAINS array for that domain.
To disable IPv4 for a domain entirely:
Set the array to empty: DOMAIN_example_com_IPV4_SUBDOMAINS=()
To enable IPv6 for specific subdomains:
Add them to the IPV6_SUBDOMAINS array for that domain.
To disable IPv6 for a domain entirely:
Set the array to empty: DOMAIN_example_com_IPV6_SUBDOMAINS=()
Use @ as the subdomain name to update the root domain:
DOMAIN_example_com_IPV4_SUBDOMAINS=("@" "www") # Updates example.com and www.example.comDomain names are converted to variable-safe format by replacing dots and hyphens with underscores:
example.com→DOMAIN_example_com_IPV4_SUBDOMAINSmy-site.co.uk→DOMAIN_my_site_co_uk_IPV4_SUBDOMAINS
Run it periodically with cron, for example every 10 minutes:
*/10 * * * * /path/to/cloudflare-dns.sh >/dev/null 2>&1Or use a systemd timer if you prefer.
bash(4.x or newer)curljq(for JSON parsing)
This project is licensed under the GNU General Public License v3 or later (GPL-3.0-or-later).
See the LICENSE file for the full text.