A script to manage CloudFlare’s DNS within Active directory DNS

Using the Cloudflare API and Powershell it is possible to keep a windows 2012r2 DNS server the master of a cloudflare DNS zone. This works with all pricing tiers of cloudflare. I have seen a few solutions to keeping cloudflare synced with AD but none were based in powershell and several are only hosted on sourceforge which has recently gotten a dubious reputation. I understand that is being worked on/cleaned up. Though I’m sure many people can agree you can see the source code and read it, it is a better option. So this is what I put together.

This script is designed to run off of a domain controller/DNS server by default through a basic task scheduler configuration.

You can get a copy of both scripts offered here from my github OR  paste bin

A quick break down of the script:

Global configs:

Authentication/To-do list of domains:

$domain_to_sync_list = ("electric-horizons.com", "Example.com")

$email = "ReallyRealEmail@gmail.com"

$api_key = "THEAPIKEYIGOTFROMCLOUDFLARE!@"

Cloudflare’s API is pretty well documented and you can find your api key here and the email would simply be the email you registered with.

One last value is considered global.

The “strict” value:

$strict = $false

When this value is set to true the script will delete any DNS entries that do not match those found in Active Directory DNS.

The script is uses 5 functions and a foreach loop. A brief explanation of each function:

get-cfzoneid:

This function simply identifies the Zone id number cloudflare has assigned. Running it without arguments outputs the id of every Zone attached to your account in CloudFlare.

Create-cfdns:

When given a FQDN, Type (Cname, A, etc), an IP address/domain, and optionally the ID generated by get-cfzoneid. This function will generate a new DNS entry in CloudFlare.

Update-cfdns:

When given FQDN, an ip address, and optionally the ID. This will update an existing cloudflare DNS entry.

Delete-cFdns:

When given a FQDN and optionally the zone id, this command will without further prompting delete an existing cloudflare DNS entry. It will output what was deleted to the console.

Get-cfdnslist

This command simply outputs all DNS entries stored within Cloudflare when provided with the mandatory zone id.

The foreach loop(s):

The foreach loop is broken up into 2 main sections. With several steps discussed below: 

The primary section enumerates the active directory zone based on the $domain_to_sync_list. It only grabs the CNAME and the A name entries. You can do MX and any other entries you feel like simply by adding them to there Where-object check:

foreach($domain in $domain_to_sync_list) {
$dns_list = Get-DnsServerResourceRecord -ZoneName "$domain" | where {($_.RecordType -eq "A") -or ($_.RecordType -eq "CNAME")}

CloudFlare is very generous in they allow 1200 calls in 5 minutes or about 4 calls a second. I didn’t see a reason to abuse that generosity so I load the zone id for the domain we are working with at the beginning even though the update-cfdns, and Create-cfdns will look them up if not provided a value. Though the script isn’t particularly fast. In some instances you may need you add a sleep to the loop if the zone is large:

$id = get-cfzoneid $domain

A second Foreach loop handles the data we gathered from the earlier AD query. It utilizes a switch statement to select the procedure followed based on DNS entry type. As you can see due to how Powershell and the DNS function returns the object I used different calls. This is where you would add queries  for MX, TXT or SPF records. I made it easy to add them but they will need to be tested in your own environment.

 

Outside the second Foreach loop we are now checking the strict variable. If the strict variable is true we will be removing any entries that do not match.

if($strict) {
$cf_dns_list = get-cfdnslist $id
foreach($entry in $cf_dns_list.result.name) {
$replace_string = "." + $domain
$verify = $entry -Replace $replace_string
if($dns_list.Hostname -notcontains "$verify") {
delete-CFdns $entry $id
}
}
}

This plus a few brackets completes the cycle of the script.

Thanks for reading.

As a bonus:

Dynamic dns script

 Those same 5 functions can be used to create your own free dynamic DNS service. You won’t need active directory DNS for this. By using another service such as api.ipify.org to get the external IP you can point an ip to your house.  The script can be found on my github here, or on pastebin here.

The modifying these variables at the top is all that is needed:

List of FQDNs you want to update with your dynamic entry:

$domain_list = ("fqdn for dynamic update")

The email and API key described earlier.

$email = "<email from cloudflare>"
$api_key = "<api key from cloudflare>"

Thanks for reading,
I-Script-Stuff

Sharing is caring!

Leave your comment

7 − two =