Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- # gratisdns.sh - A GratisDNS.dk DDNSd module for Synology DSM
- #
- # Author:
- # Brian Schmidt Pedersen (http://briped.net)
- #
- # Version:
- # 1.2.3
- #
- # 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"
- #
- # Then 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__
- #
- #
- # Changelist:
- # 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 DDNS hosts, either through a conf file, or
- # through a delimited string from DSM. Only with same admin user though.
- # F.ex.: sub1.example.com|sub2.example.com
- #
- # Specify the target interface. This would probably be a hack that won't
- # be visible through DSM, since it appears DSM only uses the LAN1/eth0
- # interface for DDNS.
- #
- ###############################################################################
- # Set variables based on parameters.
- __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
- __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"
- __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
- __DOMAIN__="$(echo ${__HOSTNAME__} | cut -d. -f2-3)"
- __MYIP__="$(echo ${@} | cut -d' ' -f4)"
- # 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"
- 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
- if [ test $(find "${__CA_BUNDLE__}" -mtime +${__MAXAGE__}) -o ! -f "${__CA_BUNDLE__}" ]; then
- log "update_ca_bundle(): Local CA bundle older than ${__MAXAGE__} days, or doesn't exist. Attempting to download fresh copy." 6
- 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 "DDNSd Status: ${__STATUS__}" 6
- }
- # Get the current IP
- #__INTERFACE_IP__="$(ifconfig ${__INTERFACE__} | sed '/inet\ /!d;s/.*r://g;s/\ .*//g')"
- #__MYIP__=$(curl --silent --interface ${__INTERFACE__} "http://automation.whatismyip.com/n09230945.asp")
- # 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
- 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."
- __STATUS__="No status returned."
- 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
- printf "%s" "${__STATUS__}"
- fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement