Advertisement
briped

GratisDNS.sh

Mar 22nd, 2012
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2.  
  3. # gratisdns.sh - A GratisDNS.dk DDNSd module for Synology DSM
  4. #
  5. # Author:
  6. #       Brian Schmidt Pedersen (http://briped.net)
  7. #
  8. # Version:
  9. #       1.2.6
  10.  
  11. # Description:
  12. #       This is a custom DDNSd module, for use with my Synology DiskStation. It
  13. #       allows me to use the DSM interface for GratisDNS.dk DDNS service.
  14. #
  15. #       To use this script, put it in the "/sbin" folder of the DiskStation,
  16. #       i.e. "/sbin/gratisdns.sh"
  17. #
  18. #       Then edit the "/etc.defaults/ddnsd_provider.conf" file and add the
  19. #       following section at the end of that file:
  20. #
  21. #       [GratisDNS.dk]
  22. #               modulepath=/sbin/gratisdns.sh
  23. #               queryurl=https://ssl.gratisdns.dk/ddns.phtml?u=__USERNAME__&p=__PASSWORD__&d=__DOMAIN__&h=__HOSTNAME__&i=__MYIP__
  24. #
  25. #       If you have a DS with two interfaces (like me), and the DDNS/ezCloud
  26. #       interface doesn't show the IP for the right interface, then you can
  27. #       make it, by setting the gateway manually in Network settings, to be the
  28. #       gateway of the interface which you want DDNS to use. Just bear in mind
  29. #       that this also affects which interface all the other services on the DS
  30. #       uses.
  31.  
  32. # Changelist:
  33. #       1.2.6
  34. #           * Just minor changes to the code, so Notepad++ could code-fold :)
  35. #       1.2.5
  36. #           * Changed update_ca_bundle() a bit, since the age checking didn't
  37. #               seem to work before.
  38. #       1.2.4
  39. #           * Fixed script to return "nochg" when IP isn't changed from IPcache
  40. #       1.2.3
  41. #           * Fixed so the IP cache is also updated, even when DDNS provider
  42. #               responds with 'nochg', since obivously then the cached IP were
  43. #               wrong.
  44. #       1.2.2
  45. #           * Fixed some return code checking.
  46. #       1.2.1
  47. #           + Added more debug logging.
  48. #       1.2.0
  49. #           + Moved the entire update ddns routine into its own function.
  50. #           + Moved the CA bundle checking and updating into its own function.
  51. #       1.1.0
  52. #           + Changed the cURL update query to use CA bundle, for better
  53. #               security.
  54. #       1.0.0
  55. #           + Release.
  56.  
  57. # Todo:
  58. #       Add support for multiple GratisDNS DDNS hosts, through a conf. file.
  59. #
  60. ###############################################################################
  61.  
  62. { # Read the supplied arguments into variables used in this script.
  63.     __USERNAME__="$(echo ${@} | cut -d' ' -f1)"
  64.     __PASSWORD__="$(echo ${@} | cut -d' ' -f2)"
  65.     __HOSTNAME__="$(echo ${@} | cut -d' ' -f3)"
  66.     __DOMAIN__="$(echo ${__HOSTNAME__} | cut -d. -f2-3)"
  67.     __MYIP__="$(echo ${@}  | cut -d' ' -f4)"
  68.     # Alternate methods for getting the IP:
  69.     #__INTERFACE_IP__="$(ifconfig ${__INTERFACE__} | sed '/inet\ /!d;s/.*r://g;s/\ .*//g')"
  70.     #__MYIP__=$(curl --silent --interface ${__INTERFACE__} "http://automation.whatismyip.com/n09230945.asp")
  71.  
  72.     # Where to store the IP used for the last DNS update:
  73.     __IP_CACHE__="/tmp/gratisdns_ddnsd_ip.txt"
  74.     # Where to store the logfile:
  75.     __LOGFILE__="/var/log/gratisdns_ddnsd.log"
  76.     # Where to store the CA bundle:
  77.     __CA_BUNDLE__="/tmp/cacert.pem"
  78. }
  79.  
  80. log() {
  81.     # Severity Levels:
  82.     # 0 Emergency       System is unusable.
  83.     #       A "panic" condition usually affecting multiple apps/servers/sites.
  84.     #       At this level it would usually notify all tech staff on call.
  85.     # 1 Alert           Action must be taken immediately.
  86.     #       Should be corrected immediately, therefore notify staff who can fix
  87.     #       the problem.An example would be the loss of a backup ISP connection
  88.     # 2 Critical        Critical conditions.
  89.     #       Should be corrected immediately, but indicates failure in a primary
  90.     #       system, an example is a loss of primary ISP connection.
  91.     # 3 Error           Error conditions.
  92.     #       Non-urgent failures, these should be relayed to developers or
  93.     #       admins; each item must be resolved within a given time.
  94.     # 4 Warning         Warning conditions.
  95.     #       Warning messages, not an error, but indication that an error will
  96.     #       occur if action is not taken, e.g. file system 85% full - each item
  97.     #       must be resolved within a given time.
  98.     # 5 Notice          Normal but significant condition.
  99.     #       Events that are unusual but not error conditions - might be
  100.     #       summarized in an email to developers or admins to spot potential
  101.     #       problems - no immediate action required.
  102.     # 6 Informational   Informational messages.
  103.     #       Normal operational messages - may be harvested for reporting,
  104.     #       measuring throughput, etc - no action required.
  105.     # 7 Debug           Debug-level messages.
  106.     #       Info useful to developers for debugging the application, not useful
  107.     #       during operations.
  108.     __LOGTIME__=$(date +"%b %e %T")
  109.     if [ "${#}" -lt 1 ]; then
  110.         false
  111.     else
  112.         __LOGMSG__="${1}"
  113.     fi
  114.     if [ "${#}" -lt 2 ]; then
  115.         __LOGPRIO__=7
  116.     else
  117.         __LOGPRIO__=${2}
  118.     fi
  119.  
  120.     logger -p ${__LOGPRIO__} -t "$(basename ${0})" "${__LOGMSG__}"
  121.     echo "${__LOGTIME__} $(basename ${0}) (${__LOGPRIO__}): ${__LOGMSG__}" >> ${__LOGFILE__}
  122. }
  123.  
  124. update_ca_bundle() {
  125.     if [ ! -z "${1}" ]; then
  126.         __CA_BUNDLE__="${1}"
  127.     else
  128.         __CA_BUNDLE__="${__CA_BUNDLE__}"
  129.     fi
  130.     log "update_ca_bundle(): __CA_BUNDLE__=${__CA_BUNDLE__}" 7
  131.     if [ ! -z "${2}" ]; then
  132.         __MAXAGE__="${2}"
  133.     else
  134.         __MAXAGE__="7"
  135.     fi
  136.     log "update_ca_bundle(): __MAXAGE__=${__MAXAGE__}" 7
  137.     local download="0"
  138.     if [ ! -f "${__CA_BUNDLE__}" ]; then
  139.         log "update_ca_bundle(): Local CA bundle doesn't exist. Set to download." 7
  140.         download="1"
  141.     fi
  142.     if [ "$(find '${__CA_BUNDLE__}' -type f -mtime +${__MAXAGE__})" = "${__CA_BUNDLE__}" ]; then
  143.         log "update_ca_bundle(): Local CA bundle older than ${__MAXAGE__} days. Set to download." 7
  144.         download="1"
  145.     fi
  146.     if [ "${download}" = "1" ]; then
  147.         curl --silent --output "${__CA_BUNDLE__}" "http://curl.haxx.se/ca/cacert.pem"
  148.         if [ "${?}" -ne "0" ]; then
  149.             log "update_ca_bundle: cURL returned error code ${?} while trying to download CA bundle." 4
  150.         fi
  151.     fi
  152. }
  153.  
  154. update_ddns() {
  155.     if [ -z "${1}" ]; then
  156.         log "update_ddns(): Missing Argument. URL string required." 3
  157.         false
  158.     else
  159.         __URL__="${1}"
  160.     fi
  161.  
  162.     # Update DNS record:
  163.     if [ -f "${__CA_BUNDLE__}" ]; then
  164.         log "update_ddns(): Updating using --cacert \"${__CA_BUNDLE__}\"." 7
  165.         __RESPONSE__=$(curl --silent --cacert "${__CA_BUNDLE__}" "${__URL__}")
  166.     else
  167.         log "update_ddns(): Updating using --insecure." 7
  168.         __RESPONSE__=$(curl --silent --insecure "${__URL__}")
  169.     fi
  170.     if [ "${?}" -ne "0" ]; then
  171.         log "update_ddns(): cURL returned error code ${?} while trying to update DDNS." 3
  172.         false
  173.     fi
  174.     log "update_ddns(): __RESPONSE__=${__RESPONSE__}" 7
  175.  
  176.     # Output:
  177.     #    When you write your own module, you can use the following words to tell user what happen by print it.
  178.     #    You can use your own message, but there is no multiple-language support.
  179.     #
  180.     #       good -  Update successfully.
  181.     #       nochg - Update successfully but the IP address have not changed.
  182.     #       nohost - The hostname specified does not exist in this user account.
  183.     #       abuse - The hostname specified is blocked for update abuse.
  184.     #       notfqdn - The hostname specified is not a fully-qualified domain name.
  185.     #       badauth - Authenticate failed.
  186.     #       911 - There is a problem or scheduled maintenance on provider side
  187.     #       badagent - The user agent sent bad request(like HTTP method/parameters is not permitted)
  188.     #       badresolv - Failed to connect to  because failed to resolve provider address.
  189.     #       badconn - Failed to connect to provider because connection timeout.
  190.     case ${__RESPONSE__} in
  191.         'OK<br>')
  192.             echo ${__MYIP__} > ${__IP_CACHE__}
  193.             __STATUS__='good'
  194.             true
  195.             ;;
  196.         'OK<br>Opdateret i forvejen')
  197.             echo ${__MYIP__} > ${__IP_CACHE__}
  198.             __STATUS__='nochg'
  199.             true
  200.             ;;
  201.         'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.'|'Domæne kan IKKE administreres af bruger')
  202.             __STATUS__='nohost'
  203.             false
  204.             ;;
  205.         'Forkerte værdier, opdatering kan ikke laves.<br><br>A record findes ikke.Hostnavn er ulovligt.')
  206.             __STATUS__='notfqdn'
  207.             false
  208.             ;;
  209.         '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.')
  210.             __STATUS__='badauth'
  211.             false
  212.             ;;
  213.         'Bruger login: MD5 invalid')
  214.             # The error from the provider doesn't really match up with the
  215.             # status I forward to DDNSd. But it seems that a malformed URL,
  216.             # such as if the URL isn't enclosed in quotes or contains spaces
  217.             # etc. will give this error.
  218.             __STATUS__='badagent'
  219.             false
  220.             ;;
  221.         *)
  222.             __STATUS__="${__RESPONSE__}"
  223.             false
  224.             ;;
  225.     esac
  226.     log "DDNSd Status: ${__STATUS__}" 6
  227. }
  228.  
  229. { # Get the last known DDNS IP
  230.     if [ ! -f ${__IP_CACHE__} ]; then
  231.         # If the file wasn't found, create it to avoid errors.
  232.         echo "127.0.0.1" > ${__IP_CACHE__}
  233.     fi
  234.     __OLDIP__=$(cat ${__IP_CACHE__})
  235. }
  236.  
  237. if [ "${__OLDIP__}" == "${__MYIP__}" ]; then
  238.     log "IP not changed. ${__MYIP__}. Not updating." 6
  239.     __STATUS__="nochg"
  240. else
  241.     update_ca_bundle "${__CA_BUNDLE__}" 7
  242.  
  243.     __URL__="https://ssl.gratisdns.dk/ddns.phtml?u=${__USERNAME__}&p=${__PASSWORD__}&d=${__DOMAIN__}&h=${__HOSTNAME__}&i=${__MYIP__}"
  244.  
  245.     # Set the response and status variables, so they're available globally. That way I can read them outside the update_ddns() function.
  246.     __RESPONSE__="No response returned from DDNS provider."
  247.     __STATUS__="No status returned from update_ddns()."
  248.  
  249.     log "IP changed. ${__OLDIP__} > ${__MYIP__}. Attempting to update DNS." 6
  250.     update_ddns "${__URL__}"
  251.     if [ "${?}" -ne "0" ]; then
  252.         log "update_dns(): ${__RESPONSE__}" 3
  253.     else
  254.         log "update_dns(): ${__RESPONSE__}" 6
  255.     fi
  256. fi
  257. printf "%s" "${__STATUS__}"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement