DEV Community

Mark Caudill
Mark Caudill

Posted on • Edited on • Originally published at mrkc.me

2 1

Cloudflare Dynamic DNS Updater

Here's a quick Python script I wrote that, when provided with your Cloudflare account email address and API token, can update a DNS entry for you. It's designed to be used in a cron job but can be run one-off as well.


#!/usr/bin/env python                                      

import argparse                                                                                                       
import CloudFlare                                          
import logging                                             
import requests                                            

def public_ip(service='http://ip.mrkc.me'):                                                                           
    """                                                    
    Get the apparent public IP of this computer. This does not imply that the
    necessary network configurations are in place to allow public access.

    Raises Exceptions for anything but a 200 response.

    :param service: the url to perform a GET against (should return only an IP)
    :type  service: str
    :returns: this machine's IP as seen by a server on the Internet
    :rtype: str
    """
    logging.debug("Looking up public IP")
    r = requests.get(service)
    r.raise_for_status()
    logging.debug("Found " + r.text)
    return r.text

def update_cf_dns(cf, name, ip_address):
    # 'AAAA' for IPv6, 'A' for IPv4 (default)
    if ':' in ip_address:
        ip_address_type = 'AAAA'
    else:
        ip_address_type = 'A'
    logging.debug("Address type " + ip_address_type)

    # Get the Zone ID
    logging.debug("Looking up zone id for " + name)        
        for zone in cf.zones.get():
            if '.'.join(name.split('.')[-2:]) in zone['name']:
                zone_id = zone['id']
                logging.debug("Found " + zone_id)
                break
        else:
            raise Exception("Unable to find zone id for " + name)


        # Get the DNS record
        logging.debug("Fetching DNS record")
        dns_record = cf.zones.dns_records.get(zone_id,
                params={'name': name, 'match': 'all', 'type': ip_address_type})[0]
        logging.debug("Found " + dns_record['id'])

        # Check to see if the IP has changed
        if dns_record['content'] != ip_address:
            logging.info("Performing DSN record update", dns_record['content'],
                    "->", ip_address)
            cf.zones.dns_records.put(zone_id, dns_record['id'],
                    data={'name': name,
                        'type': ip_address_type,
                        'content': ip_address})
        else:
            logging.debug("Old Address:" + dns_record['content'] +
                    "New Address:" + ip_address)
            logging.info("Not updating")




            def main():
                parser = argparse.ArgumentParser()
                parser.add_argument('--email', type=str, required=True)
                parser.add_argument('--token', type=str, required=True)
                parser.add_argument('--domain', type=str, required=True,
                        help='the domain name to update')
                args = parser.parse_args()
                logging.basicConfig(format='%(asctime)s %(message)s',
                        level=logging.INFO)
                cf = CloudFlare.CloudFlare(email=args.email, token=args.token)
                update_cf_dns(cf, args.domain, public_ip())

            if __name__ == '__main__':
                main()
Enter fullscreen mode Exit fullscreen mode

You can then invoke it with a cron job:

*/15 * * * *  /root/updatedns.py --email cfemail@domain.tld --token TOKEN --domain something.com 2>&1 | logger -t "updatedns.py"
Enter fullscreen mode Exit fullscreen mode

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more