Skip to content

Instantly share code, notes, and snippets.

@SharpEdgeMarshall
Last active May 17, 2022 17:15
Show Gist options
  • Select an option

  • Save SharpEdgeMarshall/c3d86d228b5e1607122069b60a6ad57a to your computer and use it in GitHub Desktop.

Select an option

Save SharpEdgeMarshall/c3d86d228b5e1607122069b60a6ad57a to your computer and use it in GitHub Desktop.

Revisions

  1. SharpEdgeMarshall revised this gist May 17, 2022. 1 changed file with 5 additions and 4 deletions.
    9 changes: 5 additions & 4 deletions Mikrotik_DDNS_CF.script
    Original file line number Diff line number Diff line change
    @@ -26,13 +26,14 @@
    :set ddnsipWAN [:pick $ip 0 [:find $ip "\n"]];
    }
    } else={
    :local result [/ip address get [/ip address find actual-interface=$WANInterface] address];
    :if ($result~"(nothing|nil)") do={ :set ddnsipWAN [:pick $result 0 [:find $result "/"]]; }
    :put ddnsipWAN
    :local result [/ip address find actual-interface=$WANInterface];
    :if ([:len $result] > 0) do={
    :local ip [/ip address get $result address];
    :set ddnsipWAN [:pick $ip 0 [:find $ip "/"]];
    }
    }

    :if ([:typeof $ddnslastipCF]~"(nothing|nil)" ) do={ :set ddnslastipCF "0.0.0.0"; } else={ :set ddnslastipCF $ddnslastipCF; }
    :if ([:typeof $ddnslastipCF]~"(nothing|nil)" ) do={ :set ddnslastipCF 0.0.0.0; } else={ :set ddnslastipCF $ddnslastipCF; }

    :if ([:typeof $ddnsipWAN]~"(nothing|nil)" ) do={
    :log error ("DDNS-Update: Unable to get public ip, please check.");
  2. SharpEdgeMarshall revised this gist May 16, 2022. 1 changed file with 28 additions and 14 deletions.
    42 changes: 28 additions & 14 deletions Mikrotik_DDNS_CF.script
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    ################# CloudFlare variables #################
    :global WANInterface "<WAN-INTERFACE>";
    ################# Config variables #################
    :global WANInterface;

    ################# CloudFlare variables #################
    :local CFtkn "<TOKEN>"; # Your CloudFlare API token comes here

    :local CFrecordType "A";
    @@ -16,29 +17,42 @@
    #########################################################################

    :global ddnslastipCF;
    :global ddnsipWAN [/ip address get [/ip address find actual-interface=$WANInterface] address ]
    :if ([:typeof [:global ddnslastipCF]] = nil ) do={ :global ddnslastipCF 0.0.0.0/0 } else={ :set ddnslastipCF $ddnslastipCF }
    :local ddnsipWAN;

    :if ([:typeof $WANInterface]~"(nothing|nil)") do={
    :local result [/tool fetch url=https://ifconfig.co http-method=get mode=https as-value output=user];
    :if ($result->"status" = "finished") do={
    :local ip ($result->"data");
    :set ddnsipWAN [:pick $ip 0 [:find $ip "\n"]];
    }
    } else={
    :local result [/ip address get [/ip address find actual-interface=$WANInterface] address];
    :if ($result~"(nothing|nil)") do={ :set ddnsipWAN [:pick $result 0 [:find $result "/"]]; }
    :put ddnsipWAN
    }
    }

    :if ([:typeof $ddnslastipCF]~"(nothing|nil)" ) do={ :set ddnslastipCF "0.0.0.0"; } else={ :set ddnslastipCF $ddnslastipCF; }

    :if ([:typeof [:global ddnsipWAN]] = nil ) do={
    :log error ("DDNS-Update: No ip address present on " . $WANInterface . ", please check.")
    :if ([:typeof $ddnsipWAN]~"(nothing|nil)" ) do={
    :log error ("DDNS-Update: Unable to get public ip, please check.");
    } else={
    :if ($ddnsipWAN != $ddnslastipCF) do={
    :local ipFormat [:pick $ddnsipWAN 0 [:find $ddnsipWAN "/"]];
    :log warn "DDNS-Update use $WANInterface IP: $ddnslastipCF -> $ipFormat"
    :log warn ("DDNS-Update use IP: ".$ddnslastipCF." -> ".$ddnsipWAN);
    :foreach domainName,domainId in=$CFdomains do={
    :local proxied ($CFproxied->$domainName);
    :local url "https://api.cloudflare.com/client/v4/zones/$CFzoneid/dns_records/$domainId";
    :local header "Authorization: Bearer $CFtkn,content-type:application/json";
    :local data "{\"type\":\"$CFrecordType\",\"name\":\"$domainName\",\"content\":\"$ipFormat\",\"proxied\":$proxied,\"ttl\":120}";
    :local result [ /tool fetch http-method=put mode=https url=$url http-header-field=$header http-data=$data output=user as-value ];
    :local data "{\"type\":\"$CFrecordType\",\"name\":\"$domainName\",\"content\":\"$ddnsipWAN\",\"proxied\":$proxied,\"ttl\":120}";
    :local result [/tool fetch http-method=put mode=https url=$url http-header-field=$header http-data=$data as-value output=user];
    :if ($result->"status" = "finished") do={
    :global ddnslastipCF $ddnsipWAN
    :log info ("DDNS-Update IP " . $ipFormat . " Success")
    :set ddnslastipCF $ddnsipWAN;
    :log info ("DDNS-Update IP " . $ddnsipWAN . " Success");
    } else={
    :log error ("DDNS-Update Error ".$result->status)
    :log error ("DDNS-Update Error ".$result->status);
    }
    };
    } else={
    :log debug "DDNS-Update: IP No Change"
    :log debug "DDNS-Update: IP No Change";
    }
    }
  3. SharpEdgeMarshall revised this gist Nov 16, 2020. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,9 @@
    # Setup

    - create a script (System->scripts) with the content of `Mikrotik_DDNS_CF.script`
    - replace: `<WAN-INTERFACE>`, `<TOKEN>`, `<DNS ZONE>`, `<DOMAIN>`, `<DOMAIN-ID>`
    - permissions: `read,write,policy,test`
    - replace: `<WAN-INTERFACE>`, `<TOKEN>`, `<DNS ZONE>`, `<DOMAIN>`, `<DOMAIN-ID>`
    - permissions: `read,write,policy,test`

    - create a schedule (System->schedulers) pointing `On Event` to your script
    - set preferred schedule time (i.e every 5 min)
    - permissions: `read,write,policy,test`
    - set preferred schedule time (i.e every 5 min)
    - permissions: `read,write,policy,test`
  4. SharpEdgeMarshall revised this gist Nov 16, 2020. 2 changed files with 10 additions and 1 deletion.
    2 changes: 1 addition & 1 deletion Mikrotik_DDNS_CF.script
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    :local CFtkn "<TOKEN>"; # Your CloudFlare API token comes here

    :local CFrecordType "A";
    :local CFzoneid "<DNS ZONE>>"; # Your DNS zone ID comes here (a hash of 32 chars)
    :local CFzoneid "<DNS ZONE>"; # Your DNS zone ID comes here (a hash of 32 chars)

    # An associative array of domain names to domainIds (32 chars each, you'll need to query CF to get them)
    :local CFdomains { "<DOMAIN>"="<DOMAIN-ID>" };
    9 changes: 9 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    # Setup

    - create a script (System->scripts) with the content of `Mikrotik_DDNS_CF.script`
    - replace: `<WAN-INTERFACE>`, `<TOKEN>`, `<DNS ZONE>`, `<DOMAIN>`, `<DOMAIN-ID>`
    - permissions: `read,write,policy,test`

    - create a schedule (System->schedulers) pointing `On Event` to your script
    - set preferred schedule time (i.e every 5 min)
    - permissions: `read,write,policy,test`
  5. SharpEdgeMarshall renamed this gist Nov 16, 2020. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. SharpEdgeMarshall renamed this gist Nov 16, 2020. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. SharpEdgeMarshall created this gist Nov 16, 2020.
    44 changes: 44 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    ################# CloudFlare variables #################
    :global WANInterface "<WAN-INTERFACE>";

    :local CFtkn "<TOKEN>"; # Your CloudFlare API token comes here

    :local CFrecordType "A";
    :local CFzoneid "<DNS ZONE>>"; # Your DNS zone ID comes here (a hash of 32 chars)

    # An associative array of domain names to domainIds (32 chars each, you'll need to query CF to get them)
    :local CFdomains { "<DOMAIN>"="<DOMAIN-ID>" };
    # An associative array of domain names to whether you want to enable CF proxying or not
    :local CFproxied { "<DOMAIN>"="false" };

    #########################################################################
    ######################## DO NOT EDIT BELOW ############################
    #########################################################################

    :global ddnslastipCF;
    :global ddnsipWAN [/ip address get [/ip address find actual-interface=$WANInterface] address ]
    :if ([:typeof [:global ddnslastipCF]] = nil ) do={ :global ddnslastipCF 0.0.0.0/0 } else={ :set ddnslastipCF $ddnslastipCF }

    :if ([:typeof [:global ddnsipWAN]] = nil ) do={
    :log error ("DDNS-Update: No ip address present on " . $WANInterface . ", please check.")
    } else={
    :if ($ddnsipWAN != $ddnslastipCF) do={
    :local ipFormat [:pick $ddnsipWAN 0 [:find $ddnsipWAN "/"]];
    :log warn "DDNS-Update use $WANInterface IP: $ddnslastipCF -> $ipFormat"
    :foreach domainName,domainId in=$CFdomains do={
    :local proxied ($CFproxied->$domainName);
    :local url "https://api.cloudflare.com/client/v4/zones/$CFzoneid/dns_records/$domainId";
    :local header "Authorization: Bearer $CFtkn,content-type:application/json";
    :local data "{\"type\":\"$CFrecordType\",\"name\":\"$domainName\",\"content\":\"$ipFormat\",\"proxied\":$proxied,\"ttl\":120}";
    :local result [ /tool fetch http-method=put mode=https url=$url http-header-field=$header http-data=$data output=user as-value ];
    :if ($result->"status" = "finished") do={
    :global ddnslastipCF $ddnsipWAN
    :log info ("DDNS-Update IP " . $ipFormat . " Success")
    } else={
    :log error ("DDNS-Update Error ".$result->status)
    }
    };
    } else={
    :log debug "DDNS-Update: IP No Change"
    }
    }