Guest User

dns-krbnsupdate.sh

a guest
Jan 8th, 2014
2,295
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2.  
  3. # This script is for secure DDNS updates using GSS/TSIG
  4. # Version: 0.1
  5.  
  6. ## CONFIGURATION ##
  7. # Kerberos realm
  8. REALM="EXAMPLE.COM"
  9. # Kerberos principal
  10. PRINCIPAL="dns-update@${REALM}"
  11. # Kerberos keytab
  12. KEYTAB="/etc/krb5.dhcpd.keytab"
  13. # Kerberos credentials cache
  14. KRB5CC="/var/run/isc-dhcpd/dhcpd.krb5cc"
  15. # Use MIT kerberos args instead of heimdal.
  16. #KRB5MIT="YES"
  17.  
  18. # Domain appended to hostname
  19. DOMAIN="example.com"
  20. # Space separated list of DNS servers for sending updates to
  21. NSRVS="ns1.example.com ns2.example.com"
  22. # Default DNS resource records TTL
  23. RRTTL="3600"
  24. # Do not use TXT RRs (rfc4701)
  25. NOTXTRRS="YES"
  26. # Default to IPv4
  27. PROTO="IPv4"
  28.  
  29. # Additional nsupdate flags (-g already applied), e.g. "-d" for debug
  30. #NSUPDFLAGS="-d"
  31. # Run in the foreground (for manual run only!!!), it's better to use "-d" as script's first argument
  32. #DEBUG="YES"
  33.  
  34. ######################################################
  35.  
  36. _usage() {
  37.   if [ "${NOTXTRRS}" == "YES" ]
  38.   then
  39.     echo "Usage:"
  40.     echo "`basename ${0}` add ip-address -h hostname [-m dhcid|mac-address] [-p IP version | --ipv4 | --ipv6] [-t dns-ttl] [-d]"
  41.     echo "`basename ${0}` delete ip-address [-m dhcid|mac-address] [-p IP version | --ipv4 | --ipv6]"
  42.   else
  43.     echo "Usage:"
  44.     echo "`basename ${0}` add ip-address -h hostname -m dhcid|mac-address [-p IP version | --ipv4 | --ipv6] [-t dns-ttl] [-d]"
  45.     echo "`basename ${0}` delete ip-address -m dhcid|mac-address [-p IP version | --ipv4 | --ipv6]"
  46.   fi
  47. }
  48.  
  49. ## VARIABLES ##
  50. ACTION=${1}
  51. IP=${2}
  52. shift && shift
  53. while [ ! -z ${1} ]
  54. do
  55.   case "${1}" in
  56.     "-d")
  57.       DEBUG="YES"
  58.       shift
  59.     ;;
  60.     "-m")
  61.       DHCID=${2}
  62.       shift && shift
  63.     ;;
  64.     "-h")
  65.       NAME=${2%%.*}
  66.       shift && shift
  67.     ;;
  68.     "-t")
  69.       RRTTL="${2}"
  70.       shift && shift
  71.     ;;
  72.     "-p")
  73.       PROTO=${2}
  74.       shift && shift
  75.     ;;
  76.     "--ipv4")
  77.       PROTO="IPv4"
  78.       shift
  79.     ;;
  80.     "--ipv6")
  81.       PROTO="IPv6"
  82.       shift
  83.     ;;
  84.     "--help")
  85.       _usage
  86.       exit 0
  87.     ;;
  88.     *)
  89.       echo "Unknown option: ${1}"
  90.       _usage
  91.       exit 1
  92.   esac
  93. done
  94.  
  95. _kerberos() {
  96.   export KRB5_KTNAME="${KEYTAB}"
  97.   export KRB5CCNAME="${KRB5CC}"
  98.  
  99.   if [ "${KRB5MIT}" = "YES" ]; then
  100.     KLISTARG="-s"
  101.   else
  102.     KLISTARG="-t"
  103.   fi
  104.  
  105.   klist ${KLISTARG} || kinit -k -t "${KEYTAB}" -c "${KRB5CC}" "${PRINCIPAL}" || { echo "DDNS: kinit failed"; exit 1; }
  106. }
  107.  
  108. _expandv6() {
  109. # Adapted from https://github.com/mutax/IPv6-Address-checks by
  110. # Florian Streibelt <florian@f-streibelt.de>
  111.   local __revipv6=${2}
  112.   local INPUT="${1}"
  113.   local O=""
  114.  
  115.   while [ "${O}" != "${INPUT}" ]; do
  116.     O="${INPUT}"
  117.  
  118.     # fill all words with zeroes
  119.     INPUT="$( sed  's|:\([0-9a-f]\{3\}\):|:0\1:|g' <<< "${INPUT}" )"
  120.     INPUT="$( sed  's|:\([0-9a-f]\{3\}\)$|:0\1|g'  <<< "${INPUT}")"
  121.     INPUT="$( sed  's|^\([0-9a-f]\{3\}\):|0\1:|g'  <<< "${INPUT}" )"
  122.  
  123.     INPUT="$( sed  's|:\([0-9a-f]\{2\}\):|:00\1:|g' <<< "${INPUT}")"
  124.     INPUT="$( sed  's|:\([0-9a-f]\{2\}\)$|:00\1|g'  <<< "${INPUT}")"
  125.     INPUT="$( sed  's|^\([0-9a-f]\{2\}\):|00\1:|g'  <<< "${INPUT}")"
  126.  
  127.     INPUT="$( sed  's|:\([0-9a-f]\):|:000\1:|g'  <<< "${INPUT}")"
  128.     INPUT="$( sed  's|:\([0-9a-f]\)$|:000\1|g'   <<< "${INPUT}")"
  129.     INPUT="$( sed  's|^\([0-9a-f]\):|000\1:|g'   <<< "${INPUT}")"
  130.   done
  131.  
  132.   # now expand the ::
  133.   grep -qs "::" <<< "${INPUT}"
  134.   if [ "$?" -eq 0 ]; then
  135.     GRPS="$(sed  's|[0-9a-f]||g' <<< "${INPUT}" | wc -m)"
  136.     ((GRPS--)) # carriage return
  137.     ((MISSING=8-GRPS))
  138.     for ((i=0;i<$MISSING;i++)); do
  139.       ZEROES="$ZEROES:0000"
  140.     done
  141.  
  142.     # be careful where to place the :
  143.     INPUT="$( sed  's|\(.\)::\(.\)|\1'$ZEROES':\2|g'   <<< "${INPUT}")"
  144.     INPUT="$( sed  's|\(.\)::$|\1'$ZEROES':0000|g'   <<< "${INPUT}")"
  145.     INPUT="$( sed  's|^::\(.\)|'$ZEROES':0000:\1|g;s|^:||g'   <<< "${INPUT}")"
  146.   fi
  147.  
  148.   # an expanded address has 39 chars + CR
  149.   if [ $(echo ${INPUT} | wc -m) != 40 ]; then
  150.     echo "Invalid IPv6 Address"
  151.     exit 1
  152.   fi
  153.  
  154.   LEN=${#INPUT}
  155.   for ((i=LEN-1;i>=0;i--))
  156.   do
  157.     [ ${INPUT:i:1} != ":" ] && TMPSTR=${TMPSTR}"."${INPUT:i:1}
  158.   done
  159.   INPUT=${TMPSTR:1}".ip6.arpa"
  160.  
  161.   # echo the fully expanded version of the address
  162.   eval ${__revipv6}="'${INPUT}'"
  163. }
  164.  
  165. _main() {
  166.   umask 77
  167.  
  168.   if [ -z "${IP}" ]
  169.   then
  170.     _usage
  171.     exit 1
  172.   fi
  173.  
  174.   if [ "${NOTXTRRS}" != "YES" ] && [ -z "${DHCID}" ]
  175.   then
  176.     _usage
  177.     exit 1
  178.   fi
  179.  
  180.   ## NSUPDATE ##
  181.   case "${ACTION}" in
  182.     add)
  183.       if [ -z "${NAME}" ]
  184.       then
  185.         _usage
  186.         exit 1
  187.       fi
  188.  
  189.       RRPTR="${NAME}.${DOMAIN}"
  190.       if [ "${NOTXTRRS}" != "YES" ]; then
  191.         NOTXTRRS=""
  192.         RRAOLD=`host ${RRPTR} | awk '/has address/ {print $4}'`
  193.         if [ -n "${RRAOLD}" ]; then
  194.           RRTXTOLD=`host -t txt "${RRPTR}" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
  195.           [ -z "${RRTXTOLD}" ] && echo "DDNS: adding records for $ip (${RRPTR}) FAILED: has A record but no DHCID, not mine" && exit 1
  196.  
  197.           RRTXT=`echo "${DHCID}${RRPTR}" | sha256sum`
  198.           RRTXT="000101${RRTXT%% *}"
  199.           [ "${RRTXT}" != "${RRTXTOLD}" ] && echo "DDNS: adding records for $ip (${RRPTR}) FAILED: has A record but DHCID is wrong" && exit 1
  200.         else
  201.           RRTXT=`echo "${DHCID}${RRPTR}" | sha256sum`
  202.           RRTXT="000101${RRTXT%% *}"
  203.         fi
  204.       else
  205.         NOTXTRRS=";"
  206.       fi
  207.  
  208.       echo "${PROTO}!"
  209.  
  210.       case "${PROTO}" in
  211.         "IPv4")
  212.            RRPTRNAME=`echo ${IP} | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
  213.            RECNAME="A"
  214.         ;;
  215.         "IPv6")
  216.           _expandv6 ${IP} RRPTRNAME
  217.           RECNAME="AAAA"
  218.         ;;
  219.         *)
  220.           echo "Unknown IP version: ${PROTO}"
  221.           exit 1
  222.       esac
  223.  
  224.       _kerberos
  225.  
  226.       for NSRV in ${NSRVS}; do
  227.         nsupdate -g ${NSUPDFLAGS} << UPDATE
  228. server ${NSRV}
  229. realm ${REALM}
  230. update delete ${RRPTR}. ${RRTTL} ${RECNAME}
  231. ${NOTXTRRS}update delete ${RRPTR}. ${RRTTL} TXT
  232. ${NOTXTRRS}update add ${RRPTR}. ${RRTTL} TXT ${RRTXT}
  233. update add ${RRPTR}. ${RRTTL} ${RECNAME} ${IP}
  234. send
  235. update delete ${RRPTRNAME}. ${RRTTL} PTR
  236. update add ${RRPTRNAME}. ${RRTTL} PTR ${NAME}.${DOMAIN}.
  237. send
  238. UPDATE
  239.  
  240.         RESULT=${?}
  241.         [ "${RESULT}" -eq "0" ] && echo "DDNS: adding records for ${IP} (${RRPTR}) succeeded" && exit 0
  242.       done
  243.  
  244.       [ "${RESULT}" != "0" ] && echo "DDNS: adding records for ${IP} (${RRPTR}) FAILED: nsupdate status ${RESULT}" && exit "${RESULT}"
  245.     ;;
  246.     delete)
  247.       RRPTR=`host ${IP} | awk '/domain name pointer/ { sub(/\.$/, "", $5); print $5}'`
  248.       if [ "${NOTXTRRS}" != "YES" ]; then
  249.         NOTXTRRS=""
  250.         if [ -n "${RRPTR}" ]; then
  251.           RRTXTOLD=`host -t txt "${RRPTR}" | sed -n '/descriptive text/s/^.*[[:space:]]descriptive text[[:space:]]*"\(.*\)"$/\1/p'`
  252.           [ -z "${RRTXTOLD}" ] && echo "DDNS: removing records for $ip (${RRPTR}) FAILED: has A record but no DHCID, not mine" && exit 1
  253.  
  254.           RRTXT=`echo "${DHCID}${RRPTR}" | sha256sum`
  255.           RRTXT="000101${RRTXT%% *}"
  256.           [ "${RRTXT}" != "${RRTXTOLD}" ] && echo "DDNS: removing records for ${IP} (${RRPTR}) FAILED: has A record but DHCID is wrong" && exit 1
  257.         else
  258.           echo "DDNS: removing records for ${IP} FAILED: has no PTR, can not determine A record" && exit 1
  259.         fi
  260.       else
  261.         NOTXTRRS=";"
  262.       fi
  263.  
  264.       case "${PROTO}" in
  265.         "IPv4")
  266.            RRPTRNAME=`echo ${IP} | awk -F '.' '{print $4"."$3"."$2"."$1".in-addr.arpa"}'`
  267.            RECNAME="A"
  268.         ;;
  269.         "IPv6")
  270.           _expandv6 ${IP} RRPTRNAME
  271.           RECNAME="AAAA"
  272.         ;;
  273.         *)
  274.           echo "Unknown IP version: ${PROTO}"
  275.           exit 1
  276.       esac
  277.  
  278.       _kerberos
  279.  
  280.       for NSRV in ${NSRVS}; do
  281.         nsupdate -g ${NSUPDFLAGS} << UPDATE
  282. server ${NSRV}
  283. realm ${REALM}
  284. update delete ${RRPTR}. ${RRTTL} ${RECNAME}
  285. ${NOTXTRRS}update delete ${RRPTR}. ${RRTTL} TXT
  286. send
  287. update delete ${RRPTRNAME}. ${RRTTL} PTR
  288. send
  289. UPDATE
  290.  
  291.         RESULT=${?}
  292.         [ "${RESULT}" -eq "0" ] && echo "DDNS: removing records for ${IP} (${RRPTR}) succeeded" && exit 0
  293.       done
  294.  
  295.       [ "${RESULT}" != "0" ] && echo "DDNS: removing records for ${IP} (${RRPTR}) FAILED: nsupdate status ${RESULT}" && exit "${RESULT}"
  296.     ;;
  297.     *)
  298.       _usage && exit 1
  299.     ;;
  300. esac
  301. }
  302.  
  303. if [ "$DEBUG" = "YES" ]; then
  304.   _main
  305. else
  306.   :
  307.   _main | logger -s -t dhcpd &
  308. fi
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×