Skip to content

Instantly share code, notes, and snippets.

@Sizzl
Forked from m-wild/cloudflaredns.sh
Last active April 25, 2018 13:24
Show Gist options
  • Save Sizzl/73018e45140cfdcc8ff7 to your computer and use it in GitHub Desktop.
Save Sizzl/73018e45140cfdcc8ff7 to your computer and use it in GitHub Desktop.

Revisions

  1. Sizzl revised this gist Mar 26, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -111,7 +111,7 @@ fi
    if [ '${__RECID__}' != '' ] && [ ${__RECID__} -ge 0 ]
    then
    # Send the update to CF API
    __URL__="${__CFBASEURL__}?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"
    __URL__="${__CFBASEURL__}?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__ZONE__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"

    # Update DNS record:
    log "Updating with ${__MYIP__}..." 7
  2. Sizzl revised this gist Mar 26, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -87,7 +87,7 @@ __ZONES__=$(echo ${__RESPONSE__} | grep -rosE "${__REGEX__}" | awk -F ':"' '{pri
    for zone in ${__ZONES__}
    do
    # Match on either sub-domain or root domain (e.g. if the hostname is the root itself):
    if [ `echo ${__HOSTNAME__} | grep "\.${zone//\./\\\.}$|^${zone//\./\\\.}$"` ]
    if [ `echo ${__HOSTNAME__} | grep -E "(.*\.${zone//\./\\\.}$|^${zone//\./\\\.}$)"` ]
    then
    __ZONE__=${zone}
    fi
  3. Sizzl revised this gist Mar 26, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -111,7 +111,7 @@ fi
    if [ '${__RECID__}' != '' ] && [ ${__RECID__} -ge 0 ]
    then
    # Send the update to CF API
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"
    __URL__="${__CFBASEURL__}?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"

    # Update DNS record:
    log "Updating with ${__MYIP__}..." 7
  4. Sizzl revised this gist Mar 26, 2016. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,8 @@
    # cloudflareddns.sh - dynamic dns updater module for Synology
    #
    # Author:
    # Michael Wildman (http://mwild.me)
    # Michael Wildman (http://mwild.me) [v0.2]
    # Chris Moore [v0.3]
    #
    # Version:
    # 0.3
  5. Sizzl revised this gist Mar 26, 2016. 1 changed file with 55 additions and 8 deletions.
    63 changes: 55 additions & 8 deletions cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@
    # Michael Wildman (http://mwild.me)
    #
    # Version:
    # 0.2
    # 0.3
    #
    # Description:
    # copy to /sbin/cloudflaredns.sh
    @@ -25,12 +25,19 @@
    # 0.2:
    # - Simplified this thing to its most basic requirements (curl + logging)
    # - Now either returns 'good' or the result (no checking for cases -- the log was always more useful anyway!)
    # 0.3:
    # - Added __CFBASEURL__
    # - Added code to fetch all zones and find the right one to update
    # - Added code to fetch the record ID and name for the hostname
    # - Changed final __URL__
    #
    # Based on Brian Schmidt Pedersen (http://blog.briped.net) gratisdns.sh
    # v0.3 Based on cloudflaredns.sh by Michael Wildman (https://gist.github.com/tehmantra/)
    # v0.2 Based on Brian Schmidt Pedersen (http://blog.briped.net) gratisdns.sh

    # TODO
    # read addition parameters from cloudflare api calls
    #
    __CFBASEURL__="https://www.cloudflare.com/api_json.html"

    # these variables are passed by DSM
    # username is your email
    @@ -67,14 +74,54 @@ log() {
    echo "${__LOGTIME__} $(basename ${0}) (${__LOGPRIO__}): ${__LOGMSG__}" >> ${__LOGFILE__}
    }

    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"

    # Update DNS record:
    log "Updating with ${__MYIP__}..." 7
    # Fetch all zones available
    __URL__="${__CFBASEURL__}?a=zone_load_multi&tkn=${__PASSWORD__}&email=${__USERNAME__}"
    __RESPONSE__=$(curl --silent "${__URL__}")

    # Strip the result element from response json
    __RESULT__=$(echo ${__RESPONSE__} | grep -o -E .result.:.[A-z]+.)
    # Parse the response
    __REGEX__="\"zone_name\":\"([a-zA-Z0-9]+([-.]?[a-zA-Z0-9]+)*.[a-zA-Z]+)"
    __ZONES__=$(echo ${__RESPONSE__} | grep -rosE "${__REGEX__}" | awk -F ':"' '{print $2}')

    # Check which zone the __HOSTNAME__ belongs to
    for zone in ${__ZONES__}
    do
    # Match on either sub-domain or root domain (e.g. if the hostname is the root itself):
    if [ `echo ${__HOSTNAME__} | grep "\.${zone//\./\\\.}$|^${zone//\./\\\.}$"` ]
    then
    __ZONE__=${zone}
    fi
    done

    if [ '${__ZONE__}' != '' ]
    then
    # Fetch the zone for this hostname and get the record ID
    __URL__="${__CFBASEURL__}?a=rec_load_all&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__ZONE__}"
    __RESPONSE__=$(curl --silent "${__URL__}")

    # Parse the response to get the record ID and name
    __REGEX__="\"rec_id\":\"([0-9]*)\",\"rec_hash\":\"[a-z0-9]*\",\"zone_name\":\"${__ZONE__}\",\"name\":\"${__HOSTNAME__}\",\"display_name\":\"[A-z0-9]*"
    __RECID__=$(echo ${__RESPONSE__} | grep -rosE "${__REGEX__}" | awk -F ':"' '{print $2}' | awk -F '"' '{print $1}')
    __RECNAME__=$(echo ${__RESPONSE__} | grep -rosE "${__REGEX__}" | awk -F ':"' '{print $6}')
    else
    log "Not sending update, no zone match for: ${__HOSTNAME__}" 7
    __RESULT__="nohost"
    fi

    if [ '${__RECID__}' != '' ] && [ ${__RECID__} -ge 0 ]
    then
    # Send the update to CF API
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"

    # Update DNS record:
    log "Updating with ${__MYIP__}..." 7
    __RESPONSE__=$(curl --silent "${__URL__}")

    # Strip the result element from response json
    __RESULT__=$(echo ${__RESPONSE__} | grep -o -E .result.:.[A-z]+.)
    else
    log "Not sending update, no record found for ${__HOSTNAME__} in zone: ${__ZONE__}" 7
    __RESULT__="nohost"
    fi

    case ${__RESULT__} in
    '"result":"success"')
  6. @m-wild m-wild revised this gist Jul 10, 2014. 1 changed file with 4 additions and 6 deletions.
    10 changes: 4 additions & 6 deletions cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -70,25 +70,23 @@ log() {
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"

    # Update DNS record:
    log "update_ddns(): Updating with ${__URL__}." 7
    log "Updating with ${__MYIP__}..." 7
    __RESPONSE__=$(curl --silent "${__URL__}")

    # Strip the result element from response json
    __RESULT__=$(echo ${__RESPONSE__} | grep -o -E .result.:.[A-z]+.)

    log "update_ddns(): __RESULT__=${__RESULT__}" 7

    case ${__RESULT__} in
    '"result":"success"')
    __STATUS__='good'
    true
    ;;
    *)
    __STATUS__="${__RESULT__}"
    log "update_dns(): __RESPONSE__=${__RESPONSE__}" 5
    log "__RESPONSE__=${__RESPONSE__}" 5
    false
    ;;
    esac
    log "update_ddns(): DDNSd Status: ${__STATUS__}" 6
    log "Status: ${__STATUS__}" 6

    printf "%s" "${__STATUS__}"
    printf "%s" "${__STATUS__}"
  7. @m-wild m-wild revised this gist Jul 10, 2014. 1 changed file with 49 additions and 111 deletions.
    160 changes: 49 additions & 111 deletions cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -6,76 +6,51 @@
    # Michael Wildman (http://mwild.me)
    #
    # Version:
    # 0.1.0
    # 0.2
    #
    # Description:
    # To install:
    # copy to /sbin/cloudflaredns.sh
    # make executable (chmod +x)
    # add the following entry to /etc.defaults/ddns_provider.conf
    # [CloudFlare]
    # modulepath=/sbin/cloudflaredns.sh
    # queryurl=https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=__PASSWORD__&email=__USERNAME__&z=__HOSTNAME__&content=__MYIP__
    #
    # [CloudFlare]
    # modulepath=/sbin/cloudflaredns.sh
    # queryurl=https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=__PASSWORD__&email=__USERNAME__&z=__HOSTNAME__&content=__MYIP__
    #
    # (note that URL is not actually used, DSM will pass us the variables)
    # run a rec_load_all query to get the record id
    # (see https://www.cloudflare.com/docs/client-api.html)
    #
    # Changelog:
    # 0.2:
    # - Simplified this thing to its most basic requirements (curl + logging)
    # - Now either returns 'good' or the result (no checking for cases -- the log was always more useful anyway!)
    #
    # Based on Brian Schmidt Pedersen (http://blog.briped.net) gratisdns.sh

    # TODO
    # read addition parameters from cloudflare api calls
    #

    { # Read the supplied arguments into variables used in this script.
    # username should be your email
    __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
    # password is your API key
    __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"

    __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
    __MYIP__="$(echo ${@} | cut -d' ' -f4)"
    # these variables are passed by DSM
    # username is your email
    __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
    # password is your cloudflare API key
    __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"
    __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
    __MYIP__="$(echo ${@} | cut -d' ' -f4)"

    # Where to store the IP used for the last DNS update:
    __IP_CACHE__="/tmp/cloudflareddns_ip.txt"

    # Where to store the logfile:
    __LOGFILE__="/var/log/cloudflareddns.log"

    # Additional parameters needed for CloudFlare
    # you will need to create the record then run rec_load_all to get the id
    __RECTYPE__="A"
    __RECID__=""
    __RECNAME__=""
    __TTL__="1"
    __SERVICEMODE__="0"

    }
    # log location
    __LOGFILE__="/var/log/cloudflareddns.log"

    # additional parameters needed for CloudFlare
    __RECTYPE__="A"
    __RECID__=""
    __RECNAME__=""
    __TTL__="1"
    __SERVICEMODE__="0"

    log() {
    # Severity Levels:
    # 0 Emergency System is unusable.
    # A "panic" condition usually affecting multiple apps/servers/sites.
    # At this level it would usually notify all tech staff on call.
    # 1 Alert Action must be taken immediately.
    # Should be corrected immediately, therefore notify staff who can fix
    # the problem.An example would be the loss of a backup ISP connection
    # 2 Critical Critical conditions.
    # Should be corrected immediately, but indicates failure in a primary
    # system, an example is a loss of primary ISP connection.
    # 3 Error Error conditions.
    # Non-urgent failures, these should be relayed to developers or
    # admins; each item must be resolved within a given time.
    # 4 Warning Warning conditions.
    # Warning messages, not an error, but indication that an error will
    # occur if action is not taken, e.g. file system 85% full - each item
    # must be resolved within a given time.
    # 5 Notice Normal but significant condition.
    # Events that are unusual but not error conditions - might be
    # summarized in an email to developers or admins to spot potential
    # problems - no immediate action required.
    # 6 Informational Informational messages.
    # Normal operational messages - may be harvested for reporting,
    # measuring throughput, etc - no action required.
    # 7 Debug Debug-level messages.
    # Info useful to developers for debugging the application, not useful
    # during operations.
    __LOGTIME__=$(date +"%b %e %T")
    if [ "${#}" -lt 1 ]; then
    false
    @@ -92,65 +67,28 @@ log() {
    echo "${__LOGTIME__} $(basename ${0}) (${__LOGPRIO__}): ${__LOGMSG__}" >> ${__LOGFILE__}
    }

    update_ddns() {
    if [ -z "${1}" ]; then
    log "update_ddns(): Missing Argument. URL string required." 3
    false
    else
    __URL__="${1}"
    fi

    # Update DNS record:
    log "update_ddns(): Updating with ${__URL__}." 7
    __RESPONSE__=$(curl --silent "${__URL__}")

    # Strip the result element from response json
    __RESULT__=$(echo ${__RESPONSE__} | grep -o -E .result.:.[A-z]+.)
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"

    if [ "${?}" -ne "0" ]; then
    log "update_ddns(): cURL returned error code ${?} while trying to update DDNS." 3
    false
    fi
    log "update_ddns(): __RESULT__=${__RESULT__}" 7

    case ${__RESULT__} in
    '"result":"success"')
    echo ${__MYIP__} > ${__IP_CACHE__}
    __STATUS__='good'
    true
    ;;
    *)
    __STATUS__="${__RESULT__}"
    log "update_dns(): __RESPONSE__=${__RESPONSE__}" 5
    false
    ;;
    esac
    log "update_ddns(): DDNSd Status: ${__STATUS__}" 6

    }
    # Update DNS record:
    log "update_ddns(): Updating with ${__URL__}." 7
    __RESPONSE__=$(curl --silent "${__URL__}")

    { # Get the last known DDNS IP
    if [ ! -f ${__IP_CACHE__} ]; then
    # If the file wasn't found, create it to avoid errors.
    echo "127.0.0.1" > ${__IP_CACHE__}
    fi
    __OLDIP__=$(cat ${__IP_CACHE__})
    }
    if [ "${__MYIP__}" == "0.0.0.0" ] || [ "${__MYIP__}" == "0.0.0.0" ]; then
    log "IP was '0.0.0.0', which is wrong. Not updating." 5
    elif [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"
    # Strip the result element from response json
    __RESULT__=$(echo ${__RESPONSE__} | grep -o -E .result.:.[A-z]+.)

    # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
    __RESULT__="No result from DDNS."
    __RESPONSE__="No response returned from DDNS provider."
    __STATUS__="No status returned from update_ddns()."
    log "update_ddns(): __RESULT__=${__RESULT__}" 7

    log "IP changed. ${__OLDIP__} > ${__MYIP__}. Attempting to update DNS." 6
    update_ddns "${__URL__}"
    case ${__RESULT__} in
    '"result":"success"')
    __STATUS__='good'
    true
    ;;
    *)
    __STATUS__="${__RESULT__}"
    log "update_dns(): __RESPONSE__=${__RESPONSE__}" 5
    false
    ;;
    esac
    log "update_ddns(): DDNSd Status: ${__STATUS__}" 6

    fi
    printf "%s" "${__STATUS__}"
  8. @tehmantra tehmantra revised this gist Jul 10, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -142,7 +142,7 @@ elif [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}}&service_mode=${__SERVICEMODE__}"
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}&service_mode=${__SERVICEMODE__}"

    # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
    __RESULT__="No result from DDNS."
  9. @tehmantra tehmantra revised this gist Jul 10, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -142,7 +142,7 @@ elif [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}}&service_mode=${__SERVICEMODE__}""
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}}&service_mode=${__SERVICEMODE__}"

    # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
    __RESULT__="No result from DDNS."
  10. @tehmantra tehmantra revised this gist Jul 10, 2014. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -3,11 +3,20 @@
    # cloudflareddns.sh - dynamic dns updater module for Synology
    #
    # Author:
    # Michael Wildman (mwildman.co.nz)
    # Michael Wildman (http://mwild.me)
    #
    # Version:
    # 0.1.0
    #
    # Description:
    # To install:
    # copy to /sbin/cloudflaredns.sh
    # make executable (chmod +x)
    # add the following entry to /etc.defaults/ddns_provider.conf
    # [CloudFlare]
    # modulepath=/sbin/cloudflaredns.sh
    # queryurl=https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=__PASSWORD__&email=__USERNAME__&z=__HOSTNAME__&content=__MYIP__
    #
    # Based on Brian Schmidt Pedersen (http://blog.briped.net) gratisdns.sh

    # TODO
  11. @tehmantra tehmantra revised this gist May 10, 2014. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -35,6 +35,7 @@
    __RECID__=""
    __RECNAME__=""
    __TTL__="1"
    __SERVICEMODE__="0"

    }

    @@ -132,7 +133,7 @@ elif [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}"
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}}&service_mode=${__SERVICEMODE__}""
    # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
    __RESULT__="No result from DDNS."
  12. @tehmantra tehmantra revised this gist May 10, 2014. 2 changed files with 146 additions and 346 deletions.
    146 changes: 146 additions & 0 deletions cloudflaredns.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,146 @@
    #!/bin/sh

    # cloudflareddns.sh - dynamic dns updater module for Synology
    #
    # Author:
    # Michael Wildman (mwildman.co.nz)
    #
    # Version:
    # 0.1.0
    #
    # Based on Brian Schmidt Pedersen (http://blog.briped.net) gratisdns.sh

    # TODO
    # read addition parameters from cloudflare api calls
    #

    { # Read the supplied arguments into variables used in this script.
    # username should be your email
    __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
    # password is your API key
    __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"

    __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
    __MYIP__="$(echo ${@} | cut -d' ' -f4)"

    # Where to store the IP used for the last DNS update:
    __IP_CACHE__="/tmp/cloudflareddns_ip.txt"

    # Where to store the logfile:
    __LOGFILE__="/var/log/cloudflareddns.log"

    # Additional parameters needed for CloudFlare
    # you will need to create the record then run rec_load_all to get the id
    __RECTYPE__="A"
    __RECID__=""
    __RECNAME__=""
    __TTL__="1"

    }

    log() {
    # Severity Levels:
    # 0 Emergency System is unusable.
    # A "panic" condition usually affecting multiple apps/servers/sites.
    # At this level it would usually notify all tech staff on call.
    # 1 Alert Action must be taken immediately.
    # Should be corrected immediately, therefore notify staff who can fix
    # the problem.An example would be the loss of a backup ISP connection
    # 2 Critical Critical conditions.
    # Should be corrected immediately, but indicates failure in a primary
    # system, an example is a loss of primary ISP connection.
    # 3 Error Error conditions.
    # Non-urgent failures, these should be relayed to developers or
    # admins; each item must be resolved within a given time.
    # 4 Warning Warning conditions.
    # Warning messages, not an error, but indication that an error will
    # occur if action is not taken, e.g. file system 85% full - each item
    # must be resolved within a given time.
    # 5 Notice Normal but significant condition.
    # Events that are unusual but not error conditions - might be
    # summarized in an email to developers or admins to spot potential
    # problems - no immediate action required.
    # 6 Informational Informational messages.
    # Normal operational messages - may be harvested for reporting,
    # measuring throughput, etc - no action required.
    # 7 Debug Debug-level messages.
    # Info useful to developers for debugging the application, not useful
    # during operations.
    __LOGTIME__=$(date +"%b %e %T")
    if [ "${#}" -lt 1 ]; then
    false
    else
    __LOGMSG__="${1}"
    fi
    if [ "${#}" -lt 2 ]; then
    __LOGPRIO__=7
    else
    __LOGPRIO__=${2}
    fi

    logger -p ${__LOGPRIO__} -t "$(basename ${0})" "${__LOGMSG__}"
    echo "${__LOGTIME__} $(basename ${0}) (${__LOGPRIO__}): ${__LOGMSG__}" >> ${__LOGFILE__}
    }

    update_ddns() {
    if [ -z "${1}" ]; then
    log "update_ddns(): Missing Argument. URL string required." 3
    false
    else
    __URL__="${1}"
    fi

    # Update DNS record:
    log "update_ddns(): Updating with ${__URL__}." 7
    __RESPONSE__=$(curl --silent "${__URL__}")

    # Strip the result element from response json
    __RESULT__=$(echo ${__RESPONSE__} | grep -o -E .result.:.[A-z]+.)

    if [ "${?}" -ne "0" ]; then
    log "update_ddns(): cURL returned error code ${?} while trying to update DDNS." 3
    false
    fi
    log "update_ddns(): __RESULT__=${__RESULT__}" 7

    case ${__RESULT__} in
    '"result":"success"')
    echo ${__MYIP__} > ${__IP_CACHE__}
    __STATUS__='good'
    true
    ;;
    *)
    __STATUS__="${__RESULT__}"
    log "update_dns(): __RESPONSE__=${__RESPONSE__}" 5
    false
    ;;
    esac
    log "update_ddns(): DDNSd Status: ${__STATUS__}" 6

    }

    { # Get the last known DDNS IP
    if [ ! -f ${__IP_CACHE__} ]; then
    # If the file wasn't found, create it to avoid errors.
    echo "127.0.0.1" > ${__IP_CACHE__}
    fi
    __OLDIP__=$(cat ${__IP_CACHE__})
    }
    if [ "${__MYIP__}" == "0.0.0.0" ] || [ "${__MYIP__}" == "0.0.0.0" ]; then
    log "IP was '0.0.0.0', which is wrong. Not updating." 5
    elif [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
    __URL__="https://www.cloudflare.com/api_json.html?a=rec_edit&tkn=${__PASSWORD__}&email=${__USERNAME__}&z=${__HOSTNAME__}&type=${__RECTYPE__}&id=${__RECID__}&name=${__RECNAME__}&content=${__MYIP__}&ttl=${__TTL__}"

    # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
    __RESULT__="No result from DDNS."
    __RESPONSE__="No response returned from DDNS provider."
    __STATUS__="No status returned from update_ddns()."

    log "IP changed. ${__OLDIP__} > ${__MYIP__}. Attempting to update DNS." 6
    update_ddns "${__URL__}"

    fi
    printf "%s" "${__STATUS__}"
    346 changes: 0 additions & 346 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -1,346 +0,0 @@
    #!/bin/sh

    # gratisdns.sh - A GratisDNS.dk DDNSd module for Synology DSM
    #
    # Author:
    # Brian Schmidt Pedersen (http://blog.briped.net)
    #
    # Version:
    # 1.3.5

    # Description:
    # This is a custom DDNSd module, for use with my Synology DiskStation. It
    # allows me to use the DSM interface for GratisDNS.dk DDNS service.
    #
    # You can either add the provider manually or by using the "--install"
    # feature.
    #
    # Using the "--install" feature
    # Execute the script with the "--install" option:
    # > gratisdns.sh --install
    # If the script isn't executable, you can prepend sh:
    # > sh gratisdns.sh --install
    #
    # This will copy (and overwrite if already exists) the gratisdns.sh file
    # '/sbin/gratisdns.sh' and chmod +x it (make it eXecutable).
    #
    # If no other arguments are added to the "--install" option, a provider
    # with the name "GratisDNS.dk" will be added. In order to use more hosts
    # you can add a custom provider name after the "--install" option:
    # > gratisdns.sh --install example.org
    # or
    # > gratisdns.sh --install My Custom Provider
    # This adds a provider with the name "example.org", which will use the
    # GratisDNS.dk DDNS module.
    #
    # You don't have to worry about spaces. The script reads everything after
    # "--install" as one string. You might have to beware of using certain
    # characters that might act as an escape character (backslash, ticks,
    # backticks, single- and double quotes spring to mind).
    #
    # Manual installation
    # Copy the 'gratisdns.sh' file to the '/sbin' folder:
    # > cp /volume1/homes/USERNAME/gratisdns.sh /sbin/gratisdns.sh
    # The above copy command assumes you have enabled "User home service" on
    # your Synology, and also assumes that the home shares are located on
    # your first volume "volume1".
    #
    # Then make the file eXecutable:
    # > chmod +x /sbin/gratisdns.sh
    #
    # Then edit the "/etc.defaults/ddnsd_provider.conf" file to add DDNS
    # providers. I only know of 'vi' editor on the Synolgoy devices, which
    # can be a bit annoying to navigate, if you don't know how.
    # Open "/etc.defaults/ddnsd_provider.conf" in vi:
    # > vi /etc.defaults/ddnsd_provider.conf
    # When opened, hold the DOWN ARROW until you reach the end of the config
    # file, then hit (once only) the O key (the letter,not the number). This
    # opens edit mode, below the current line. Then simply type (or paste,
    # but remember to not paste the # comments) the following:
    # [GratisDNS.dk]
    # modulepath=/sbin/gratisdns.sh
    # queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__
    #
    # You can add multiple sections by adding the above, and changing the
    # text between the square brackets (i.e. [GratisDNS.dk]).
    #
    # If you have a DS with two interfaces (like me), and the DDNS/ezCloud
    # interface doesn't show the IP for the right interface, then you can
    # make it, by setting the gateway manually in Network settings, to be the
    # gateway of the interface which you want DDNS to use. Just bear in mind
    # that this also affects which interface all the other services on the DS
    # uses.

    # Changelist:
    # 1.3.5
    # * Added a simple check, to ensure that DDNS wouldn't update if IP was 0.0.0.0
    # (yes, I've had that happen to me)
    # 1.3.4
    # * Changed from cut to awk, to find the __DOMAIN__ from __HOSTNAME__, this
    # is to ensure that the last two delimeters are always found (i.e.
    # 'example.org' found from 'example.org', 'sub.example.org' and
    # 'sub.sub.example.org' etc.)
    # 1.3.3
    # * Minor fixes and modifications to the "--install" feature.
    # 1.3.2
    # + Modified the "--install" feature to add a custom provider/domain.
    # See the description for more details.
    # 1.3.1
    # * Fixed the "--install" feature.
    # 1.3.0
    # + Added a simple "--install" argument which simply appends the GratisDNS
    # provider to the /etc.defaults/ddns_provider.conf file, if not already
    # added.
    # 1.2.7
    # * __DOMAIN__ would be incorrect, if using 2nd. or 3rd. (or higher)
    # level subdomains, since it was just the 2nd. and 3rd. delimiter
    # that was returned. Changed to 2nd. delimiter and the rest.
    # Thanks to Mathias Neerup for bringing my attention to this.
    # 1.2.6
    # * Just minor changes to the code, so Notepad++ could code-fold :)
    # 1.2.5
    # * Changed update_ca_bundle() a bit, since the age checking didn't
    # seem to work before.
    # 1.2.4
    # * Fixed script to return "nochg" when IP isn't changed from IPcache
    # 1.2.3
    # * Fixed so the IP cache is also updated, even when DDNS provider
    # responds with 'nochg', since obivously then the cached IP were
    # wrong.
    # 1.2.2
    # * Fixed some return code checking.
    # 1.2.1
    # + Added more debug logging.
    # 1.2.0
    # + Moved the entire update ddns routine into its own function.
    # + Moved the CA bundle checking and updating into its own function.
    # 1.1.0
    # + Changed the cURL update query to use CA bundle, for better
    # security.
    # 1.0.0
    # + Release.

    # Todo:
    #
    ###############################################################################

    { # Read the supplied arguments into variables used in this script.
    __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
    __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"
    __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
    __DOMAIN__="$(echo ${__HOSTNAME__} | awk -F. '{print $(NF-1) "." $NF}')"
    __MYIP__="$(echo ${@} | cut -d' ' -f4)"
    # Alternate methods for getting the IP:
    #__INTERFACE_IP__="$(ifconfig ${__INTERFACE__} | sed '/inet\ /!d;s/.*r://g;s/\ .*//g')"
    #__MYIP__=$(curl --silent --interface ${__INTERFACE__} "http://automation.whatismyip.com/n09230945.asp")

    # Where to store the IP used for the last DNS update:
    __IP_CACHE__="/tmp/gratisdns_ddnsd_ip.txt"
    # Where to store the logfile:
    __LOGFILE__="/var/log/gratisdns_ddnsd.log"
    # Where to store the CA bundle:
    #__CA_BUNDLE__="/tmp/cacert.pem"
    # The ddns_provider.conf path and filename:
    __CONFIGFILE__="/etc.defaults/ddns_provider.conf"
    # The scriptfile (this file) path and filename (used for the --install parameter):
    __SCRIPTFILE__="/sbin/gratisdns.sh"
    }
    if [ "$(echo ${@} | cut -d' ' -f1)" == "--install" ]; then
    cp -f ${0} ${__SCRIPTFILE__}
    chmod +x ${__SCRIPTFILE__}

    if [ "$(echo ${@} | cut -d' ' -f2-)" == "--install" ]; then
    __MYDOMAIN__="GratisDNS.dk"
    else
    __MYDOMAIN__="$(echo ${@} | cut -d' ' -f2-)"
    fi
    if [ ! $(grep "${__MYDOMAIN__}" ${__CONFIGFILE__}) ]; then
    # Add the custom domain to the ddns_provider.conf file.
    echo "[${__MYDOMAIN__}]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added '${__MYDOMAIN__}' to the DDNS Provider list."
    fi
    echo "Done!"
    exit
    fi

    log() {
    # Severity Levels:
    # 0 Emergency System is unusable.
    # A "panic" condition usually affecting multiple apps/servers/sites.
    # At this level it would usually notify all tech staff on call.
    # 1 Alert Action must be taken immediately.
    # Should be corrected immediately, therefore notify staff who can fix
    # the problem.An example would be the loss of a backup ISP connection
    # 2 Critical Critical conditions.
    # Should be corrected immediately, but indicates failure in a primary
    # system, an example is a loss of primary ISP connection.
    # 3 Error Error conditions.
    # Non-urgent failures, these should be relayed to developers or
    # admins; each item must be resolved within a given time.
    # 4 Warning Warning conditions.
    # Warning messages, not an error, but indication that an error will
    # occur if action is not taken, e.g. file system 85% full - each item
    # must be resolved within a given time.
    # 5 Notice Normal but significant condition.
    # Events that are unusual but not error conditions - might be
    # summarized in an email to developers or admins to spot potential
    # problems - no immediate action required.
    # 6 Informational Informational messages.
    # Normal operational messages - may be harvested for reporting,
    # measuring throughput, etc - no action required.
    # 7 Debug Debug-level messages.
    # Info useful to developers for debugging the application, not useful
    # during operations.
    __LOGTIME__=$(date +"%b %e %T")
    if [ "${#}" -lt 1 ]; then
    false
    else
    __LOGMSG__="${1}"
    fi
    if [ "${#}" -lt 2 ]; then
    __LOGPRIO__=7
    else
    __LOGPRIO__=${2}
    fi

    logger -p ${__LOGPRIO__} -t "$(basename ${0})" "${__LOGMSG__}"
    echo "${__LOGTIME__} $(basename ${0}) (${__LOGPRIO__}): ${__LOGMSG__}" >> ${__LOGFILE__}
    }

    update_ca_bundle() {
    if [ ! -z "${1}" ]; then
    __CA_BUNDLE__="${1}"
    else
    __CA_BUNDLE__="${__CA_BUNDLE__}"
    fi
    log "update_ca_bundle(): __CA_BUNDLE__=${__CA_BUNDLE__}" 7
    if [ ! -z "${2}" ]; then
    __MAXAGE__="${2}"
    else
    __MAXAGE__="7"
    fi
    log "update_ca_bundle(): __MAXAGE__=${__MAXAGE__}" 7
    local download="0"
    if [ ! -f "${__CA_BUNDLE__}" ]; then
    log "update_ca_bundle(): Local CA bundle doesn't exist. Set to download." 7
    download="1"
    fi
    if [ "$(find '${__CA_BUNDLE__}' -type f -mtime +${__MAXAGE__})" = "${__CA_BUNDLE__}" ]; then
    log "update_ca_bundle(): Local CA bundle older than ${__MAXAGE__} days. Set to download." 7
    download="1"
    fi
    if [ "${download}" = "1" ]; then
    curl --silent --output "${__CA_BUNDLE__}" "http://curl.haxx.se/ca/cacert.pem"
    if [ "${?}" -ne "0" ]; then
    log "update_ca_bundle: cURL returned error code ${?} while trying to download CA bundle." 4
    fi
    fi
    }

    update_ddns() {
    if [ -z "${1}" ]; then
    log "update_ddns(): Missing Argument. URL string required." 3
    false
    else
    __URL__="${1}"
    fi

    # Update DNS record:
    if [ -f "${__CA_BUNDLE__}" ]; then
    log "update_ddns(): Updating using --cacert \"${__CA_BUNDLE__}\"." 7
    __RESPONSE__=$(curl --silent --cacert "${__CA_BUNDLE__}" "${__URL__}")
    else
    log "update_ddns(): Updating using --insecure." 7
    __RESPONSE__=$(curl --silent --insecure "${__URL__}")
    fi
    if [ "${?}" -ne "0" ]; then
    log "update_ddns(): cURL returned error code ${?} while trying to update DDNS." 3
    false
    fi
    log "update_ddns(): __RESPONSE__=${__RESPONSE__}" 7

    # Output:
    # When you write your own module, you can use the following words to tell user what happen by print it.
    # You can use your own message, but there is no multiple-language support.
    #
    # good - Update successfully.
    # nochg - Update successfully but the IP address have not changed.
    # nohost - The hostname specified does not exist in this user account.
    # abuse - The hostname specified is blocked for update abuse.
    # notfqdn - The hostname specified is not a fully-qualified domain name.
    # badauth - Authenticate failed.
    # 911 - There is a problem or scheduled maintenance on provider side
    # badagent - The user agent sent bad request(like HTTP method/parameters is not permitted)
    # badresolv - Failed to connect to because failed to resolve provider address.
    # badconn - Failed to connect to provider because connection timeout.
    case ${__RESPONSE__} in
    'OK<br>')
    echo ${__MYIP__} > ${__IP_CACHE__}
    __STATUS__='good'
    true
    ;;
    'OK<br>Opdateret i forvejen')
    echo ${__MYIP__} > ${__IP_CACHE__}
    __STATUS__='nochg'
    true
    ;;
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'Domæne kan IKKE administreres af bruger')
    __STATUS__='nohost'
    false
    ;;
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    __STATUS__='notfqdn'
    false
    ;;
    'Bruger login: 1Fejl i kodeord, prøv igen. Husk serveren ser forskel på STORE Og små BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel på STORE Og smÅ BOGstAvER.')
    __STATUS__='badauth'
    false
    ;;
    'Bruger login: MD5 invalid')
    # The error from the provider doesn't really match up with the
    # status I forward to DDNSd. But it seems that a malformed URL,
    # such as if the URL isn't enclosed in quotes or contains spaces
    # etc. will give this error.
    __STATUS__='badagent'
    false
    ;;
    *)
    __STATUS__="${__RESPONSE__}"
    false
    ;;
    esac
    log "update_ddns(): DDNSd Status: ${__STATUS__}" 6
    }

    { # Get the last known DDNS IP
    if [ ! -f ${__IP_CACHE__} ]; then
    # If the file wasn't found, create it to avoid errors.
    echo "127.0.0.1" > ${__IP_CACHE__}
    fi
    __OLDIP__=$(cat ${__IP_CACHE__})
    }
    if [ "${__MYIP__}" == "0.0.0.0" ] || [ "${__MYIP__}" == "0.0.0.0" ]; then
    log "IP was '0.0.0.0', which is wrong. Not updating." 5
    elif [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
    update_ca_bundle "${__CA_BUNDLE__}" 7

    __URL__="https://ssl.gratisdns.dk/ddns.phtml?u=${__USERNAME__}&p=${__PASSWORD__}&d=${__DOMAIN__}&h=${__HOSTNAME__}&i=${__MYIP__}"

    # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
    __RESPONSE__="No response returned from DDNS provider."
    __STATUS__="No status returned from update_ddns()."

    log "IP changed. ${__OLDIP__} > ${__MYIP__}. Attempting to update DNS." 6
    update_ddns "${__URL__}"
    if [ "${?}" -ne "0" ]; then
    log "update_dns(): ${__RESPONSE__}" 3
    else
    log "update_dns(): ${__RESPONSE__}" 6
    fi
    fi
    printf "%s" "${__STATUS__}"
  13. @briped briped revised this gist Aug 22, 2013. 1 changed file with 7 additions and 3 deletions.
    10 changes: 7 additions & 3 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@
    # Brian Schmidt Pedersen (http://blog.briped.net)
    #
    # Version:
    # 1.3.4
    # 1.3.5

    # Description:
    # This is a custom DDNSd module, for use with my Synology DiskStation. It
    @@ -72,6 +72,9 @@
    # uses.

    # Changelist:
    # 1.3.5
    # * Added a simple check, to ensure that DDNS wouldn't update if IP was 0.0.0.0
    # (yes, I've had that happen to me)
    # 1.3.4
    # * Changed from cut to awk, to find the __DOMAIN__ from __HOSTNAME__, this
    # is to ensure that the last two delimeters are always found (i.e.
    @@ -318,8 +321,9 @@ update_ddns() {
    fi
    __OLDIP__=$(cat ${__IP_CACHE__})
    }

    if [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    if [ "${__MYIP__}" == "0.0.0.0" ] || [ "${__MYIP__}" == "0.0.0.0" ]; then
    log "IP was '0.0.0.0', which is wrong. Not updating." 5
    elif [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
  14. briped revised this gist Jul 27, 2013. 1 changed file with 10 additions and 5 deletions.
    15 changes: 10 additions & 5 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@
    # Brian Schmidt Pedersen (http://blog.briped.net)
    #
    # Version:
    # 1.3.3
    # 1.3.4

    # Description:
    # This is a custom DDNSd module, for use with my Synology DiskStation. It
    @@ -72,6 +72,11 @@
    # uses.

    # Changelist:
    # 1.3.4
    # * Changed from cut to awk, to find the __DOMAIN__ from __HOSTNAME__, this
    # is to ensure that the last two delimeters are always found (i.e.
    # 'example.org' found from 'example.org', 'sub.example.org' and
    # 'sub.sub.example.org' etc.)
    # 1.3.3
    # * Minor fixes and modifications to the "--install" feature.
    # 1.3.2
    @@ -120,7 +125,7 @@
    __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
    __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"
    __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
    __DOMAIN__="$(echo ${__HOSTNAME__} | cut -d. -f2-)"
    __DOMAIN__="$(echo ${__HOSTNAME__} | awk -F. '{print $(NF-1) "." $NF}')"
    __MYIP__="$(echo ${@} | cut -d' ' -f4)"
    # Alternate methods for getting the IP:
    #__INTERFACE_IP__="$(ifconfig ${__INTERFACE__} | sed '/inet\ /!d;s/.*r://g;s/\ .*//g')"
    @@ -278,15 +283,15 @@ update_ddns() {
    __STATUS__='nochg'
    true
    ;;
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'DomÊne kan IKKE administreres af bruger')
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'Domæne kan IKKE administreres af bruger')
    __STATUS__='nohost'
    false
    ;;
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    __STATUS__='notfqdn'
    false
    ;;
    'Bruger login: 1Fejl i kodeord, pr¯v igen. Husk serveren ser forskel STORE Og sm BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel STORE Og sm≈ BOGstAvER.')
    'Bruger login: 1Fejl i kodeord, prøv igen. Husk serveren ser forskel STORE Og små BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel STORE Og smÅ BOGstAvER.')
    __STATUS__='badauth'
    false
    ;;
  15. briped revised this gist May 12, 2013. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -153,6 +153,7 @@ if [ "$(echo ${@} | cut -d' ' -f1)" == "--install" ]; then
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added '${__MYDOMAIN__}' to the DDNS Provider list."
    fi
    echo "Done!"
    exit
    fi

  16. briped revised this gist May 12, 2013. 1 changed file with 30 additions and 38 deletions.
    68 changes: 30 additions & 38 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@
    # Brian Schmidt Pedersen (http://blog.briped.net)
    #
    # Version:
    # 1.3.2
    # 1.3.3

    # Description:
    # This is a custom DDNSd module, for use with my Synology DiskStation. It
    @@ -24,12 +24,19 @@
    # This will copy (and overwrite if already exists) the gratisdns.sh file
    # '/sbin/gratisdns.sh' and chmod +x it (make it eXecutable).
    #
    # You'll also be prompted for a domain name. The text you enter here is
    # only used as a descriptive name in the provider list. This is so that
    # you can add multiple DDNS hosts through the GratisDNS.dk DDNS module.
    # If you do not enter enything (just hit enter), the default provider
    # name 'GratisDNS.dk' will be used.
    # If no other arguments are added to the "--install" option, a provider
    # with the name "GratisDNS.dk" will be added. In order to use more hosts
    # you can add a custom provider name after the "--install" option:
    # > gratisdns.sh --install example.org
    # or
    # > gratisdns.sh --install My Custom Provider
    # This adds a provider with the name "example.org", which will use the
    # GratisDNS.dk DDNS module.
    #
    # You don't have to worry about spaces. The script reads everything after
    # "--install" as one string. You might have to beware of using certain
    # characters that might act as an escape character (backslash, ticks,
    # backticks, single- and double quotes spring to mind).
    #
    # Manual installation
    # Copy the 'gratisdns.sh' file to the '/sbin' folder:
    @@ -65,6 +72,8 @@
    # uses.

    # Changelist:
    # 1.3.3
    # * Minor fixes and modifications to the "--install" feature.
    # 1.3.2
    # + Modified the "--install" feature to add a custom provider/domain.
    # See the description for more details.
    @@ -129,39 +138,22 @@
    __SCRIPTFILE__="/sbin/gratisdns.sh"
    }
    if [ "$(echo ${@} | cut -d' ' -f1)" == "--install" ]; then
    if [ -f ${__SCRIPTFILE__} ]; then
    echo "The file '${__SCRIPTFILE__}' already exists. Overwriting."
    else
    echo "Copying the GratisDNS.dk module to '${__SCRIPTFILE__}'."
    fi
    cp -f ${0} ${__SCRIPTFILE__}
    chmod +x ${__SCRIPTFILE__}
    echo "Enter your domain name..."
    echo "This is only used as a descriptive providername, in order to create"
    echo "multiple poviders (one for each of your GratisDNS hosted domains)."
    echo "If left blank, the default 'GratisDNS.dk' will be used."
    read __MYDOMAIN__
    if [ "${__MYDOMAIN__}." == "." ]; then
    if [ ! $(grep "GratisDNS.dk" ${__CONFIGFILE__}) ]; then
    # Add the GratisDNS.dk module to the ddns_provider.conf file.
    echo "[GratisDNS.dk]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added 'GratisDNS.dk' to the DDNS Provider list."
    else
    echo "The 'GratisDNS.dk' provier is already added. Skipping."
    fi

    if [ "$(echo ${@} | cut -d' ' -f2-)" == "--install" ]; then
    __MYDOMAIN__="GratisDNS.dk"
    else
    if [ ! $(grep "${__MYDOMAIN__}" ${__CONFIGFILE__}) ]; then
    # Add the custom domain to the ddns_provider.conf file.
    echo "[${__MYDOMAIN__}]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added '${__MYDOMAIN__}' to the DDNS Provider list."
    else
    echo "The '${__MYDOMAIN__}' provier is already added. Skipping."
    fi
    __MYDOMAIN__="$(echo ${@} | cut -d' ' -f2-)"
    fi
    if [ ! $(grep "${__MYDOMAIN__}" ${__CONFIGFILE__}) ]; then
    # Add the custom domain to the ddns_provider.conf file.
    echo "[${__MYDOMAIN__}]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added '${__MYDOMAIN__}' to the DDNS Provider list."
    fi
    exit
    fi

    log() {
    @@ -285,15 +277,15 @@ update_ddns() {
    __STATUS__='nochg'
    true
    ;;
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'Domæne kan IKKE administreres af bruger')
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'DomÊne kan IKKE administreres af bruger')
    __STATUS__='nohost'
    false
    ;;
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    __STATUS__='notfqdn'
    false
    ;;
    'Bruger login: 1Fejl i kodeord, prøv igen. Husk serveren ser forskel STORE Og små BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel STORE Og smÅ BOGstAvER.')
    'Bruger login: 1Fejl i kodeord, pr¯v igen. Husk serveren ser forskel STORE Og sm BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel STORE Og sm≈ BOGstAvER.')
    __STATUS__='badauth'
    false
    ;;
  17. briped revised this gist May 11, 2013. 1 changed file with 67 additions and 17 deletions.
    84 changes: 67 additions & 17 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -6,25 +6,57 @@
    # Brian Schmidt Pedersen (http://blog.briped.net)
    #
    # Version:
    # 1.3.1
    # 1.3.2

    # Description:
    # This is a custom DDNSd module, for use with my Synology DiskStation. It
    # allows me to use the DSM interface for GratisDNS.dk DDNS service.
    #
    # To use this script, put it in the "/sbin" folder of the DiskStation,
    # i.e. "/sbin/gratisdns.sh"
    # Remember to make the file eXecutable:
    # chmod +x /sbin/gratisdns.sh
    # You can either add the provider manually or by using the "--install"
    # feature.
    #
    # Using the "--install" feature
    # Execute the script with the "--install" option:
    # > gratisdns.sh --install
    # If the script isn't executable, you can prepend sh:
    # > sh gratisdns.sh --install
    #
    # This will copy (and overwrite if already exists) the gratisdns.sh file
    # '/sbin/gratisdns.sh' and chmod +x it (make it eXecutable).
    #
    # You'll also be prompted for a domain name. The text you enter here is
    # only used as a descriptive name in the provider list. This is so that
    # you can add multiple DDNS hosts through the GratisDNS.dk DDNS module.
    # If you do not enter enything (just hit enter), the default provider
    # name 'GratisDNS.dk' will be used.
    #
    #
    # Then execute the file once with the "--install" (without "quotes") argument.
    # Manual installation
    # Copy the 'gratisdns.sh' file to the '/sbin' folder:
    # > cp /volume1/homes/USERNAME/gratisdns.sh /sbin/gratisdns.sh
    # The above copy command assumes you have enabled "User home service" on
    # your Synology, and also assumes that the home shares are located on
    # your first volume "volume1".
    #
    # You can also just manually edit the "/etc.defaults/ddnsd_provider.conf" file and
    # add the following section at the end of that file:
    # Then make the file eXecutable:
    # > chmod +x /sbin/gratisdns.sh
    #
    # Then edit the "/etc.defaults/ddnsd_provider.conf" file to add DDNS
    # providers. I only know of 'vi' editor on the Synolgoy devices, which
    # can be a bit annoying to navigate, if you don't know how.
    # Open "/etc.defaults/ddnsd_provider.conf" in vi:
    # > vi /etc.defaults/ddnsd_provider.conf
    # When opened, hold the DOWN ARROW until you reach the end of the config
    # file, then hit (once only) the O key (the letter,not the number). This
    # opens edit mode, below the current line. Then simply type (or paste,
    # but remember to not paste the # comments) the following:
    # [GratisDNS.dk]
    # modulepath=/sbin/gratisdns.sh
    # queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__
    #
    # You can add multiple sections by adding the above, and changing the
    # text between the square brackets (i.e. [GratisDNS.dk]).
    #
    # If you have a DS with two interfaces (like me), and the DDNS/ezCloud
    # interface doesn't show the IP for the right interface, then you can
    # make it, by setting the gateway manually in Network settings, to be the
    @@ -33,6 +65,9 @@
    # uses.

    # Changelist:
    # 1.3.2
    # + Modified the "--install" feature to add a custom provider/domain.
    # See the description for more details.
    # 1.3.1
    # * Fixed the "--install" feature.
    # 1.3.0
    @@ -69,7 +104,6 @@
    # + Release.

    # Todo:
    # Add support for multiple GratisDNS DDNS hosts, through a conf. file.
    #
    ###############################################################################

    @@ -102,16 +136,32 @@ if [ "$(echo ${@} | cut -d' ' -f1)" == "--install" ]; then
    fi
    cp -f ${0} ${__SCRIPTFILE__}
    chmod +x ${__SCRIPTFILE__}
    if [ ! $(grep "GratisDNS.dk" ${__CONFIGFILE__}) ]; then
    # Add the GratisDNS.dk module to the ddns_provider.conf file.
    echo "[GratisDNS.dk]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added GratisDNS.dk to the DDNS Provider list."
    echo "Enter your domain name..."
    echo "This is only used as a descriptive providername, in order to create"
    echo "multiple poviders (one for each of your GratisDNS hosted domains)."
    echo "If left blank, the default 'GratisDNS.dk' will be used."
    read __MYDOMAIN__
    if [ "${__MYDOMAIN__}." == "." ]; then
    if [ ! $(grep "GratisDNS.dk" ${__CONFIGFILE__}) ]; then
    # Add the GratisDNS.dk module to the ddns_provider.conf file.
    echo "[GratisDNS.dk]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added 'GratisDNS.dk' to the DDNS Provider list."
    else
    echo "The 'GratisDNS.dk' provier is already added. Skipping."
    fi
    else
    echo "Looks like GratisDNS.dk is already added to the DDNS Provider list. Skipping this part."
    if [ ! $(grep "${__MYDOMAIN__}" ${__CONFIGFILE__}) ]; then
    # Add the custom domain to the ddns_provider.conf file.
    echo "[${__MYDOMAIN__}]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added '${__MYDOMAIN__}' to the DDNS Provider list."
    else
    echo "The '${__MYDOMAIN__}' provier is already added. Skipping."
    fi
    fi
    exit
    fi

    log() {
  18. briped revised this gist May 10, 2013. 1 changed file with 22 additions and 8 deletions.
    30 changes: 22 additions & 8 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -3,10 +3,10 @@
    # gratisdns.sh - A GratisDNS.dk DDNSd module for Synology DSM
    #
    # Author:
    # Brian Schmidt Pedersen (http://briped.net)
    # Brian Schmidt Pedersen (http://blog.briped.net)
    #
    # Version:
    # 1.3.0
    # 1.3.1

    # Description:
    # This is a custom DDNSd module, for use with my Synology DiskStation. It
    @@ -33,6 +33,8 @@
    # uses.

    # Changelist:
    # 1.3.1
    # * Fixed the "--install" feature.
    # 1.3.0
    # + Added a simple "--install" argument which simply appends the GratisDNS
    # provider to the /etc.defaults/ddns_provider.conf file, if not already
    @@ -88,14 +90,26 @@
    # Where to store the CA bundle:
    #__CA_BUNDLE__="/tmp/cacert.pem"
    # The ddns_provider.conf path and filename:
    __CONFIGFILE__=/etc.defaults/ddns_provider.conf
    __CONFIGFILE__="/etc.defaults/ddns_provider.conf"
    # The scriptfile (this file) path and filename (used for the --install parameter):
    __SCRIPTFILE__="/sbin/gratisdns.sh"
    }

    if [ "$(echo ${@} | cut -d' ' -f1)" -eq "--install" ]; then
    if [ "$(echo ${@} | cut -d' ' -f1)" == "--install" ]; then
    if [ -f ${__SCRIPTFILE__} ]; then
    echo "The file '${__SCRIPTFILE__}' already exists. Overwriting."
    else
    echo "Copying the GratisDNS.dk module to '${__SCRIPTFILE__}'."
    fi
    cp -f ${0} ${__SCRIPTFILE__}
    chmod +x ${__SCRIPTFILE__}
    if [ ! $(grep "GratisDNS.dk" ${__CONFIGFILE__}) ]; then
    # Add the GratisDNS.dk module to the ddns_provider.conf file.
    echo "[GratisDNS.dk]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    echo "Added GratisDNS.dk to the DDNS Provider list."
    else
    echo "Looks like GratisDNS.dk is already added to the DDNS Provider list. Skipping this part."
    fi
    exit
    fi
    @@ -221,15 +235,15 @@ update_ddns() {
    __STATUS__='nochg'
    true
    ;;
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'DomÊne kan IKKE administreres af bruger')
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'Domæne kan IKKE administreres af bruger')
    __STATUS__='nohost'
    false
    ;;
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    __STATUS__='notfqdn'
    false
    ;;
    'Bruger login: 1Fejl i kodeord, pr¯v igen. Husk serveren ser forskel STORE Og sm BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel STORE Og sm≈ BOGstAvER.')
    'Bruger login: 1Fejl i kodeord, prøv igen. Husk serveren ser forskel STORE Og små BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel STORE Og smÅ BOGstAvER.')
    __STATUS__='badauth'
    false
    ;;
  19. briped created this gist Apr 18, 2013.
    280 changes: 280 additions & 0 deletions gratisdns.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,280 @@
    #!/bin/sh

    # gratisdns.sh - A GratisDNS.dk DDNSd module for Synology DSM
    #
    # Author:
    # Brian Schmidt Pedersen (http://briped.net)
    #
    # Version:
    # 1.3.0

    # Description:
    # This is a custom DDNSd module, for use with my Synology DiskStation. It
    # allows me to use the DSM interface for GratisDNS.dk DDNS service.
    #
    # To use this script, put it in the "/sbin" folder of the DiskStation,
    # i.e. "/sbin/gratisdns.sh"
    # Remember to make the file eXecutable:
    # chmod +x /sbin/gratisdns.sh
    #
    # Then execute the file once with the "--install" (without "quotes") argument.
    #
    # You can also just manually edit the "/etc.defaults/ddnsd_provider.conf" file and
    # add the following section at the end of that file:
    # [GratisDNS.dk]
    # modulepath=/sbin/gratisdns.sh
    # queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__
    #
    # If you have a DS with two interfaces (like me), and the DDNS/ezCloud
    # interface doesn't show the IP for the right interface, then you can
    # make it, by setting the gateway manually in Network settings, to be the
    # gateway of the interface which you want DDNS to use. Just bear in mind
    # that this also affects which interface all the other services on the DS
    # uses.

    # Changelist:
    # 1.3.0
    # + Added a simple "--install" argument which simply appends the GratisDNS
    # provider to the /etc.defaults/ddns_provider.conf file, if not already
    # added.
    # 1.2.7
    # * __DOMAIN__ would be incorrect, if using 2nd. or 3rd. (or higher)
    # level subdomains, since it was just the 2nd. and 3rd. delimiter
    # that was returned. Changed to 2nd. delimiter and the rest.
    # Thanks to Mathias Neerup for bringing my attention to this.
    # 1.2.6
    # * Just minor changes to the code, so Notepad++ could code-fold :)
    # 1.2.5
    # * Changed update_ca_bundle() a bit, since the age checking didn't
    # seem to work before.
    # 1.2.4
    # * Fixed script to return "nochg" when IP isn't changed from IPcache
    # 1.2.3
    # * Fixed so the IP cache is also updated, even when DDNS provider
    # responds with 'nochg', since obivously then the cached IP were
    # wrong.
    # 1.2.2
    # * Fixed some return code checking.
    # 1.2.1
    # + Added more debug logging.
    # 1.2.0
    # + Moved the entire update ddns routine into its own function.
    # + Moved the CA bundle checking and updating into its own function.
    # 1.1.0
    # + Changed the cURL update query to use CA bundle, for better
    # security.
    # 1.0.0
    # + Release.

    # Todo:
    # Add support for multiple GratisDNS DDNS hosts, through a conf. file.
    #
    ###############################################################################

    { # Read the supplied arguments into variables used in this script.
    __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
    __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"
    __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
    __DOMAIN__="$(echo ${__HOSTNAME__} | cut -d. -f2-)"
    __MYIP__="$(echo ${@} | cut -d' ' -f4)"
    # Alternate methods for getting the IP:
    #__INTERFACE_IP__="$(ifconfig ${__INTERFACE__} | sed '/inet\ /!d;s/.*r://g;s/\ .*//g')"
    #__MYIP__=$(curl --silent --interface ${__INTERFACE__} "http://automation.whatismyip.com/n09230945.asp")

    # Where to store the IP used for the last DNS update:
    __IP_CACHE__="/tmp/gratisdns_ddnsd_ip.txt"
    # Where to store the logfile:
    __LOGFILE__="/var/log/gratisdns_ddnsd.log"
    # Where to store the CA bundle:
    #__CA_BUNDLE__="/tmp/cacert.pem"
    # The ddns_provider.conf path and filename:
    __CONFIGFILE__=/etc.defaults/ddns_provider.conf
    }

    if [ "$(echo ${@} | cut -d' ' -f1)" -eq "--install" ]; then
    if [ ! $(grep "GratisDNS.dk" ${__CONFIGFILE__}) ]; then
    echo "[GratisDNS.dk]" >> ${__CONFIGFILE__}
    echo " modulepath=/sbin/gratisdns.sh" >> ${__CONFIGFILE__}
    echo " queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__" >> ${__CONFIGFILE__}
    fi
    exit
    fi

    log() {
    # Severity Levels:
    # 0 Emergency System is unusable.
    # A "panic" condition usually affecting multiple apps/servers/sites.
    # At this level it would usually notify all tech staff on call.
    # 1 Alert Action must be taken immediately.
    # Should be corrected immediately, therefore notify staff who can fix
    # the problem.An example would be the loss of a backup ISP connection
    # 2 Critical Critical conditions.
    # Should be corrected immediately, but indicates failure in a primary
    # system, an example is a loss of primary ISP connection.
    # 3 Error Error conditions.
    # Non-urgent failures, these should be relayed to developers or
    # admins; each item must be resolved within a given time.
    # 4 Warning Warning conditions.
    # Warning messages, not an error, but indication that an error will
    # occur if action is not taken, e.g. file system 85% full - each item
    # must be resolved within a given time.
    # 5 Notice Normal but significant condition.
    # Events that are unusual but not error conditions - might be
    # summarized in an email to developers or admins to spot potential
    # problems - no immediate action required.
    # 6 Informational Informational messages.
    # Normal operational messages - may be harvested for reporting,
    # measuring throughput, etc - no action required.
    # 7 Debug Debug-level messages.
    # Info useful to developers for debugging the application, not useful
    # during operations.
    __LOGTIME__=$(date +"%b %e %T")
    if [ "${#}" -lt 1 ]; then
    false
    else
    __LOGMSG__="${1}"
    fi
    if [ "${#}" -lt 2 ]; then
    __LOGPRIO__=7
    else
    __LOGPRIO__=${2}
    fi

    logger -p ${__LOGPRIO__} -t "$(basename ${0})" "${__LOGMSG__}"
    echo "${__LOGTIME__} $(basename ${0}) (${__LOGPRIO__}): ${__LOGMSG__}" >> ${__LOGFILE__}
    }

    update_ca_bundle() {
    if [ ! -z "${1}" ]; then
    __CA_BUNDLE__="${1}"
    else
    __CA_BUNDLE__="${__CA_BUNDLE__}"
    fi
    log "update_ca_bundle(): __CA_BUNDLE__=${__CA_BUNDLE__}" 7
    if [ ! -z "${2}" ]; then
    __MAXAGE__="${2}"
    else
    __MAXAGE__="7"
    fi
    log "update_ca_bundle(): __MAXAGE__=${__MAXAGE__}" 7
    local download="0"
    if [ ! -f "${__CA_BUNDLE__}" ]; then
    log "update_ca_bundle(): Local CA bundle doesn't exist. Set to download." 7
    download="1"
    fi
    if [ "$(find '${__CA_BUNDLE__}' -type f -mtime +${__MAXAGE__})" = "${__CA_BUNDLE__}" ]; then
    log "update_ca_bundle(): Local CA bundle older than ${__MAXAGE__} days. Set to download." 7
    download="1"
    fi
    if [ "${download}" = "1" ]; then
    curl --silent --output "${__CA_BUNDLE__}" "http://curl.haxx.se/ca/cacert.pem"
    if [ "${?}" -ne "0" ]; then
    log "update_ca_bundle: cURL returned error code ${?} while trying to download CA bundle." 4
    fi
    fi
    }

    update_ddns() {
    if [ -z "${1}" ]; then
    log "update_ddns(): Missing Argument. URL string required." 3
    false
    else
    __URL__="${1}"
    fi

    # Update DNS record:
    if [ -f "${__CA_BUNDLE__}" ]; then
    log "update_ddns(): Updating using --cacert \"${__CA_BUNDLE__}\"." 7
    __RESPONSE__=$(curl --silent --cacert "${__CA_BUNDLE__}" "${__URL__}")
    else
    log "update_ddns(): Updating using --insecure." 7
    __RESPONSE__=$(curl --silent --insecure "${__URL__}")
    fi
    if [ "${?}" -ne "0" ]; then
    log "update_ddns(): cURL returned error code ${?} while trying to update DDNS." 3
    false
    fi
    log "update_ddns(): __RESPONSE__=${__RESPONSE__}" 7

    # Output:
    # When you write your own module, you can use the following words to tell user what happen by print it.
    # You can use your own message, but there is no multiple-language support.
    #
    # good - Update successfully.
    # nochg - Update successfully but the IP address have not changed.
    # nohost - The hostname specified does not exist in this user account.
    # abuse - The hostname specified is blocked for update abuse.
    # notfqdn - The hostname specified is not a fully-qualified domain name.
    # badauth - Authenticate failed.
    # 911 - There is a problem or scheduled maintenance on provider side
    # badagent - The user agent sent bad request(like HTTP method/parameters is not permitted)
    # badresolv - Failed to connect to because failed to resolve provider address.
    # badconn - Failed to connect to provider because connection timeout.
    case ${__RESPONSE__} in
    'OK<br>')
    echo ${__MYIP__} > ${__IP_CACHE__}
    __STATUS__='good'
    true
    ;;
    'OK<br>Opdateret i forvejen')
    echo ${__MYIP__} > ${__IP_CACHE__}
    __STATUS__='nochg'
    true
    ;;
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'DomÊne kan IKKE administreres af bruger')
    __STATUS__='nohost'
    false
    ;;
    'Forkerte vÊrdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
    __STATUS__='notfqdn'
    false
    ;;
    'Bruger login: 1Fejl i kodeord, pr¯v igen. Husk serveren ser forskel p STORE Og sm BOGstAvER.'|'Bruger login: Bruger eksistere ikke, husk serveren ser forskel p STORE Og sm≈ BOGstAvER.')
    __STATUS__='badauth'
    false
    ;;
    'Bruger login: MD5 invalid')
    # The error from the provider doesn't really match up with the
    # status I forward to DDNSd. But it seems that a malformed URL,
    # such as if the URL isn't enclosed in quotes or contains spaces
    # etc. will give this error.
    __STATUS__='badagent'
    false
    ;;
    *)
    __STATUS__="${__RESPONSE__}"
    false
    ;;
    esac
    log "update_ddns(): DDNSd Status: ${__STATUS__}" 6
    }

    { # Get the last known DDNS IP
    if [ ! -f ${__IP_CACHE__} ]; then
    # If the file wasn't found, create it to avoid errors.
    echo "127.0.0.1" > ${__IP_CACHE__}
    fi
    __OLDIP__=$(cat ${__IP_CACHE__})
    }

    if [ "${__OLDIP__}" == "${__MYIP__}" ]; then
    log "IP not changed. ${__MYIP__}. Not updating." 6
    __STATUS__="nochg"
    else
    update_ca_bundle "${__CA_BUNDLE__}" 7

    __URL__="https://ssl.gratisdns.dk/ddns.phtml?u=${__USERNAME__}&p=${__PASSWORD__}&d=${__DOMAIN__}&h=${__HOSTNAME__}&i=${__MYIP__}"

    # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
    __RESPONSE__="No response returned from DDNS provider."
    __STATUS__="No status returned from update_ddns()."

    log "IP changed. ${__OLDIP__} > ${__MYIP__}. Attempting to update DNS." 6
    update_ddns "${__URL__}"
    if [ "${?}" -ne "0" ]; then
    log "update_dns(): ${__RESPONSE__}" 3
    else
    log "update_dns(): ${__RESPONSE__}" 6
    fi
    fi
    printf "%s" "${__STATUS__}"