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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Apr 30, 2019

@ifcho Idem.

In the script i have add the following;

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

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.