Community discussions

MikroTik App
 
nocivo
just joined
Topic Author
Posts: 4
Joined: Fri Jun 26, 2020 1:12 pm
Location: japan
Contact:

Gandi LiveDNS script DDNS

Sat Jul 11, 2020 1:36 pm

Hi,
I modified the NOIP script to make it work with Gandi LiveDNS. it work well, but only with a single domain. To make that use multiple domain, I have to convert the following curl/jq line to "/tool fetch", but I can't. This line is used to change the gandi zones UUID
curl -s -H "X-Api-Key: $apikey" https://dns.api.gandi.net/api/v5/domains/$domain | jq -r '.zone_records_href'

I convert the first part that use curl but I don't know how to convert the last part that use jq.
/tool fetch mode=https http-method=get http-header-field="Content-Type:application/json,X-Api-Key:$apikey" url=https://dns.api.gandi.net/api/v5/domains/$domain

Please give me some advice or suggestions to convert the jq code, if it is possible.
# Gandi.net LiveDNS automatic Dynamic DNS update written by Massimo Ciani
#
# Credits:
#    - This script was designed using the NO-IP script written by riverron https://wiki.mikrotik.com/wiki/Dynamic_DNS_Update_Script_for_No-IP_DNS
#
#--------------- Change Values in this section to match your setup ------------------
# LiveDNS API key
:local apikey "your api key"
# Set the domain and subdomain of zone to be updated.
# Hostnames with spaces are unsupported. Replace the value in the quotations below with your domain and subdomain.
# To specify multiple domain, separate them with commas.(not working right now. Only one domain)
:local domain "example.com"
:local subdomain "subdomain name"
# catch this by using this command on your computer (change the $apikey and $domain): curl -s -H "X-Api-Key: $apikey" https://dns.api.gandi.net/api/v5/domains/$domain | jq -r '.zone_records_href'
:local zonehref "https://dns.api.gandi.net/api/v5/zones/<UUID>/records"
# Change to the name of interface that gets the dynamic IP address
:local inetinterface "pppoe-out1"
#------------------------------------------------------------------------------------
# No more changes need

:global previousIP [:resolve "$subdomain.$domain"]

:if ([/interface get $inetinterface value-name=running]) do={
# Get the current IP on the interface
   :local currentIP [/ip address get [find interface="$inetinterface" disabled=no] address]
# Strip the net mask off the IP address
   :for i from=( [:len $currentIP] - 1) to=0 do={
       :if ( [:pick $currentIP $i] = "/") do={ 
           :set currentIP [:pick $currentIP 0 $i]
       } 
   }
   :if ($currentIP != $previousIP) do={
       :log info "LiveDNS: Current IP $currentIP is not equal to previous IP, update needed"
       :local noiphostarray
       :set noiphostarray [:toarray $domain]
       :foreach host in=$noiphostarray do={
#         Next line must be converted from curl to "/tool fetch"  to have multidomain work
#          :local zonehref [curl -s -H "X-Api-Key: $apikey" https://dns.api.gandi.net/api/v5/domains/$domain | jq -r '.zone_records_href']
           :log info "LiveDNS: Sending update for $subdomain.$host"
           /tool fetch mode=https http-method=put http-header-field="Content-Type:application/json,X-Api-Key:$apikey" http-data="{\"rrset_name\": \"$subdomain\",\"rrset_type\": \"A\",\"rrset_ttl\": 300,\"rrset_values\": [\"$currentIP\"]}" url="$zonehref/$subdomain/A" dst-path="" output=none
           :log info "LiveDNS: Host $subdomain.$host updated on Gandi with IP $currentIP"
       }
   }  else={
       :log info "LiveDNS: Previous IP $previousIP is equal to current IP, no update needed"
   }
} else={
   :log info "LiveDNS: $inetinterface is not currently running, so therefore will not update."
}

I'm not a programmer and maybe there are some error in the script. If there are please report to me.

Thanks
 
nocivo
just joined
Topic Author
Posts: 4
Joined: Fri Jun 26, 2020 1:12 pm
Location: japan
Contact:

Re: Gandi LiveDNS script DDNS

Tue Jul 14, 2020 9:38 am

Hi,
finally I solved the conversion by reading more better the liveDNS documentation. It's possible to use a shortcut link, simply by put only the domain instead of UUID zone. It's not necessary to use "jq".
It's describe here:
https://doc.livedns.gandi.net/#id7

Moreover I decide to rewrite the script from scratch, with different logic, to have update on multi-domain and subdomain.

Put the following script on "system script" as new script with policy "read, write, test" and name "LiveDNS_DDNS". If you use pppoe connection, go to ppp profile and click the profile that pppoe use. In the field "on up" put this line "/system script run LiveDNS_DDNS". without quotes.
If you want, you can also put a scheduler to run every 30m, as check, if your ISP change the IP on the fly. But this, normally not happen.

Thanks
# ----- Gandi.net LiveDNS dynamic DNS multi domain and subdomain write by Massimo Ciani  ------
#
#
#
#--------------- Change Values in this section to match your setup ------------------

# Your LiveDNS API KEY
:local apikey "your APIKEY"

# Set the domain and subdomain to be updated.
# Replace the value in the quotations below with your domain and subdomain name.
# To specify multiple domain and subdomain, separate them with commas.
# IMPORTANT: Before to start the script, remember to create manually the records for all domain.
:local domain "example.com,example.net"
:local subdomain "sub1,sub2,sub3"

# Set the name of interface where get the internet public IP
:local inetinterface "pppoe-out1"

#------------------------------------------------------------------------------------
# No more changes need

# get current IP
:global currentIP
:if ([/interface get $inetinterface value-name=running]) do={
    :global currentIPa [/ip address get [find interface="$inetinterface" disabled=no] address]
# cancel netmask from interface IP address
    :for i from=( [:len $currentIPa] - 1) to=0 do={
        :if ( [:pick $currentIPa $i] = "/") do={ 
            :set currentIP [:pick $currentIPa 0 $i]
       } 
   }
} else={
    :log info "LiveDNS: $inetinterface is not currently running, so therefore will not update."
    :error [:log info "bye"]
}

# Recursively resolve al subdomain and update on IP changes
:global domainarray
:set domainarray [:toarray $domain]
:foreach host in=$domainarray do={
    :global subarray
    :set subarray [:toarray $subdomain]
    :foreach sub in=$subarray do={
        :global previousIP [:resolve "$sub.$host"]
        :if ($currentIP != $previousIP) do={
            :log info "LiveDNS $sub.$host: Current IP $currentIP is not equal to previous IP, update needed"
            :log info "LiveDNS $sub.$host: Sending update"
            /tool fetch mode=https http-method=put http-header-field="Content-Type:application/json,X-Api-Key:$apikey" http-data="{\"rrset_name\": \"$sub\",\"rrset_type\": \"A\",\"rrset_ttl\": 300,\"rrset_values\": [\"$currentIP\"]}" url="https://dns.api.gandi.net/api/v5/domains/$host/records/$sub/A" dst-path="" output=none
            :log info "LiveDNS $sub.$host: updated on Gandi with IP $currentIP"
        } else={
            :log info "LiveDNS $sub.$host: Previous IP $previousIP is equal to current IP, no update needed"
        }
    }
}
 
karloch
just joined
Posts: 7
Joined: Sun Feb 14, 2016 3:07 am

Re: Gandi LiveDNS script DDNS

Sat Oct 15, 2022 7:25 pm

I would like to thank you for the script, it worked nicely; but I was missing two key features: 1/The ability to upgrade the root domain as well. In GANDI Live DNS API root domain is referring by the character @ in the subdomain. 2/I have a split brain DNS so internal resolution was not providing the correct external IP to check whatever it changed or not, so I forced external resolution to the DNS in the $resolver variable. This is the result:
# ----- Gandi.net LiveDNS dynamic DNS multi domain and subdomain write by Massimo Ciani  ------
#
#
#
#--------------- Change Values in this section to match your setup ------------------

# Your LiveDNS API KEY
:local apikey "your APIKEY"

# Set the domain and subdomain to be updated.
# Replace the value in the quotations below with your domain and subdomain name.
# To specify multiple domain and subdomain, separate them with commas.
# IMPORTANT: Before to start the script, remember to create manually the records for all domain.
:local domain "example.com,example.net"
:local subdomain "@,sub1,sub2,sub3"
:local fqdn
:local resolver "8.8.8.8"

# Set the name of interface where get the internet public IP
:local inetinterface "pppoe-out1"

#------------------------------------------------------------------------------------
# No more changes need

# get current IP
:global currentIP
:if ([/interface get $inetinterface value-name=running]) do={
    :global currentIPa [/ip address get [find interface="$inetinterface" disabled=no] address]
# cancel netmask from interface IP address
    :for i from=( [:len $currentIPa] - 1) to=0 do={
        :if ( [:pick $currentIPa $i] = "/") do={ 
            :set currentIP [:pick $currentIPa 0 $i]
       } 
   }
} else={
    :log info "LiveDNS: $inetinterface is not currently running, so therefore will not update."
    :error [:log info "bye"]
}

# Recursively resolve al subdomain and update on IP changes
:global domainarray
:set domainarray [:toarray $domain]
:foreach host in=$domainarray do={
    :global subarray
    :set subarray [:toarray $subdomain]
    :foreach sub in=$subarray do={
        :if ($sub = "@") do={
            :set fqdn "$host"
        } else {
            :set fqdn "$sub.$host"
        }
        :global previousIP [:resolve domain-name="$fqdn" server="$resolver"]
        :if ($currentIP != $previousIP) do={
            :log info "LiveDNS $fqdn: Current IP $currentIP is not equal to previous IP, update needed"
            :log info "LiveDNS $fqdn: Sending update"
            /tool fetch mode=https http-method=put http-header-field="Content-Type:application/json,X-Api-Key:$apikey" http-data="{\"rrset_name\": \"$sub\",\"rrset_type\": \"A\",\"rrset_ttl\": 300,\"rrset_values\": [\"$currentIP\"]}" url="https://dns.api.gandi.net/api/v5/domains/$host/records/$sub/A" dst-path="" output=none
            :log info "LiveDNS $fqdn: updated on Gandi with IP $currentIP"
        } else={
            :log info "LiveDNS $fqdn: Previous IP $previousIP is equal to current IP, no update needed"
        }
    }
}
Now you can use @ in the subdomain list to tell the script that the root should also be updated and if you have split brain DNS the external resolution will keep ok.
 
wirSeefahrer
just joined
Posts: 13
Joined: Tue Jul 26, 2016 12:52 pm

Re: Gandi LiveDNS script DDNS

Wed Nov 15, 2023 11:18 pm

I've updated the script to make it work with the current version of the API and stored it in a public Github repository. Please feel free to create a PR to keep it updated in the future. https://github.com/smangels/mikrotik-sc ... record.rsc

Who is online

Users browsing this forum: Google [Bot] and 21 guests