Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Automatic script for Mikrotik RouterOS updating record on CloudFlare.
#########################################################################
# ================================================== #
# $ Mikrotik RouterOS update script for CloudFlare $ #
# ================================================== #
# #
# - You need a CloudFlare account & api key (look under settings), #
# a zone and A record in it #
# - All variables in first section are obvious, except CFid, #
# To obtain CFzoneid use following command in any unix shell: #
# curl -X GET "https://api.cloudflare.com/client/v4/accounts" -H "X-Auth-Email: YOUR_EMAIL" -H "X-Auth-Key: YOUR_API_KEY" -H "Content-Type: application/json" | python -mjson.tool
# To obtain CFid use following command in any unix shell: #
# curl -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records" -H "X-Auth-Email: YOUR_EMAIL" -H "X-Auth-Key: YOUR_API_KEY" -H "Content-Type: application/json" | python -mjson.tool
# - Enable CFDebug if needed - it'll print some info to logs #
# - Put script under /system scripts giving "read" policy access. #
# For 6.29 and older "test" policy is also needed. #
# - Add script to /system scheduler using it's name in "on-event" #
# - Requires at least RouterOS 6.44beta75 for multiple header support #
# #
# Credits for Samuel Tegenfeldt, CC BY-SA 3.0 #
# Modified by kiler129 #
# Modified by viritt #
#########################################################################
################# CloudFlare variables #################
:local CFDebug "true"
:global WANInterface "ether1-gateway"
:local CFdomain "sub.domain.com"
:local CFzone "domain.com"
:local CFemail "email@example.com"
:local CFtkn "YOUR_API_KEY"
:local CFzoneid "YOUR_ZONE_ID"
:local CFid "YOUR_ID"
#########################################################################
######################## DO NOT EDIT BELOW ############################
#########################################################################
################# Internal variables #################
:local resolvedIP ""
:global WANip ""
################# Resolve and set IP-variables #################
:local currentIP [/ip address get [/ip address find interface=$WANInterface ] address];
:set WANip [:pick $currentIP 0 [:find $currentIP "/"]];
:set resolvedIP [:resolve $CFdomain];
################# Build CF API Url (v4) #################
:local CFurl "https://api.cloudflare.com/client/v4/zones/"
:set CFurl ($CFurl . "$CFzoneid/dns_records/$CFid");
######## Write debug info to log #################
:if ($CFDebug = "true") do={
:log info ("CF: hostname = $CFdomain")
:log info ("CF: resolvedIP = $resolvedIP")
:log info ("CF: currentIP = $currentIP")
:log info ("CF: WANip = $WANip")
:log info ("CF: CFurl = $CFurl&content=$WANip")
};
######## Compare and update CF if necessary #####
:if ($resolvedIP != $WANip) do={
:log info ("CF: Updating CF, setting $CFDomain = $WANip")
/tool fetch http-method=put mode=https url="$CFurl" http-header-field="X-Auth-Email:$CFemail,X-Auth-Key:$CFtkn,content-type:application/json" output=none http-data="{\"type\":\"$CFrecordType\",\"name\":\"$CFdomain\",\"content\":\"$WANip\"}"
/ip dns cache flush
} else={
:log info "CF: No Update Needed!"
}
@ifcho
Copy link

ifcho commented Mar 13, 2019

Thanks for this.
I got it working, but noticed two problems with it.

  1. To get CFzoneid, the API endpoint is not:
    # curl -X GET "https://api.cloudflare.com/client/v4/accounts" -H "X-Auth-Email: YOUR_EMAIL" -H "X-Auth-Key: YOUR_API_KEY" -H "Content-Type: application/json" | python -mjson.tool
    but
    "https://api.cloudflare.com/client/v4/zones" , so it should be:
    # curl -X GET "https://api.cloudflare.com/client/v4/zones" -H "X-Auth-Email: YOUR_EMAIL" -H "X-Auth-Key: YOUR_API_KEY" -H "Content-Type: application/json" | python -mjson.tool

  2. $CFrecordType isn't defined.

@b0nete
Copy link

b0nete commented Apr 30, 2019

@ifcho Idem.

In the script i have add the following;

:local CFrecordType ""
:set CFrecordType "A" (or wanted type).

Thanks!

@DzenDyn
Copy link

DzenDyn commented Dec 18, 2019

Hello!
It dosent work for me.
If I paste the address from the log into the browser, I get:
{"success":false,"errors":[{"code":9106,"message":"Missing X-Auth-Email header"},{"code":9107,"message":"Missing X-Auth-Key header"}],"messages":[],"result":null}

@mike6715b
Copy link

mike6715b commented Feb 22, 2021

For anyone finding this post, I was able to update the script further and it's available here
It was giving authentication errors for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment