MNeill

GKG DNS Updater

Nov 1st, 2023
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 12.05 KB | Source Code | 0 0
  1. #!/bin/bash
  2.  
  3.  
  4. ####################################################################
  5. #####                     Variable setting                     #####
  6. ####################################################################
  7.  
  8. # Set this to one of your domain's authoritative name servers
  9. NS_SERVER="ns3.gkg.net"
  10.  
  11. #Logfile location and notification address
  12. OUTFILE=/tmp/updateDNS.out
  13.  
  14.  
  15. ####################################################################
  16. #####                     Helper functions                     #####
  17. ####################################################################
  18.  
  19. usage () {
  20.         echot "\n"
  21.         echot "Usage:  [PAUSES=n] ${0} -u username -p password -h FQDN"
  22.         echot ""
  23.         echot "    NOTE:  The (sub)domain part of the name must be case-sensitive to your"
  24.         echot "        domain record at GKG. This is probably all-lowercase, but I haven't"
  25.         echot "        figured out the right way to case-insensitive XPATH-parse yet..."
  26.         echot ""
  27.         echot "    If you want to make this slower, to debug the outfiles at each curl,"
  28.         echot "        include the optional PAUSES=n parameter before the script on the"
  29.         echot "        commandline.  If PAUSES is set on the commandline at runtime, the"
  30.         echot "        script will pause 'n' seconds after each curl step, to allow you"
  31.         echot "        time to ^C and inspect the files being generated and parsed down"
  32.         echot "        the pipeline."
  33.         echot "\n\n"
  34.         exit 1
  35. }
  36.  
  37. # Borrowed from https://unix.stackexchange.com/questions/60653/urlencode-function
  38. #
  39. #    Thanks to https://unix.stackexchange.com/users/885/gilles-so-stop-being-evil
  40. urlencode_od_awk () {
  41.         echo -n "$1" | od -t d1 | awk '{
  42.        for (i = 2; i <= NF; i++) {
  43.                printf(($i>=48 && $i<=57) || ($i>=65 && $i<=90) || ($i>=97 && $i<=122) ||
  44.                        $i==45 || $i==46 || $i==95 || $i==126 ?
  45.                                        "%c" : "%%%02x", $i)
  46.                                }
  47.                }'
  48. }
  49.  
  50. dopauses () {
  51.         if [[ "${PAUSES}" -gt "0" ]]; then
  52.                 echot "Pausing (${PAUSES})  --  ${*}"
  53.                 sleep ${PAUSES}
  54.         fi
  55. }
  56.  
  57. echot () {
  58.         echo -e "${*}"  | tee -a ${OUTFILE}
  59. }
  60.  
  61. ####################################################################
  62. #####                       Start Script                       #####
  63. ####################################################################
  64.  
  65. ######################################
  66. # Prechecks and parameter parsing... #
  67. ######################################
  68.  
  69. # Make sure we have all of our required utilities
  70. UTILS="sed tr dig grep awk date od mktemp mail xmllint"
  71. which --skip-alias ${UTILS} >/dev/null 2>&1; ECODE=${?}
  72. if [[ "${ECODE}" != "0" ]]; then
  73.         echot Missing one of the required utilities!
  74.         echot Fix this before continuing...
  75.         echot
  76.         echot `which  --skip-alias ${UTILS} 2>&1 | sed 's/^/    /'`
  77.         exit 1
  78. fi
  79.  
  80. # Check to see if we preset PAUSES; if not, set it to 0 so that dopauses() skips
  81. if [[ -z ${PAUSES+x} ]]; then PAUSES=0; else echot "Pausing after each curl for ${PAUSES} seconds"; fi
  82.  
  83.  
  84. # Get userpass from parameters
  85. while getopts "u:p:h:" arg; do
  86.         case $arg in
  87.                 u)
  88.                         GKGUSER=${OPTARG}
  89.                         ;;
  90.                 p)
  91.                         GKGPASS=`urlencode_od_awk ${OPTARG}`
  92.                         ;;
  93.                 h)
  94.                         HOSTARG=${OPTARG}
  95.                         HN=${HOSTARG%%.*}
  96.                         DN=`echo ${HOSTARG} | sed "s/${HN}\.//"`
  97.                         ;;
  98.                 *)
  99.                         usage
  100.                         ;;
  101.         esac
  102. done
  103. if [[ -z "${GKGUSER}" || -z "${GKGPASS}" ]]; then
  104.         echot "\n\nMust pass username and password!" && usage
  105. fi
  106.  
  107. dopauses "\nDebugging if sleeping:  user/pass/host/domain is:  ${GKGUSER} / ${GKGPASS} / ${HN} / ${DN}\n\n"
  108.  
  109.  
  110. ###############
  111. # Time to go! #
  112. ###############
  113.  
  114. # Temp directory creation and logfile cleanup
  115. TMPDIR=`mktemp -d`
  116. if [ -e ${OUTFILE} ]; then
  117.         OLDOUTFILE=`ls $OUTFILE`
  118.         rm $OUTFILE
  119.         echot "Starting update at `date`"
  120.         echot "Found old output file, deleted it"
  121.         echot -- "*  ${OLDOUTFILE}"
  122.         echot ""
  123. else
  124.         echot "Starting update at: `date`\n\n"
  125. fi
  126.  
  127.  
  128. # Get my current IP address
  129. while [ "${#ExtIP}" -gt 15 ] || [ "${#ExtIP}" -eq 0 ]; do
  130.         ExtIP=`curl -s http://checkip.amazonaws.com`
  131.         sleep 1
  132. done
  133.  
  134. while [ "$DynIP" == "" ]; do
  135.         DynIP=`dig ${HOSTARG} @${NS_SERVER}| grep -i "^${HOSTARG}" | awk '{print $5}'`
  136.         sleep 1
  137. done
  138.  
  139. echot "Current External IP is:  ${ExtIP}"
  140. echot "${HOSTARG} is at: ${DynIP}  \n\n\n"
  141.  
  142. if [ "$ExtIP" == "$DynIP" ]; then
  143.         echot "IP Addresses match"
  144. else
  145.         echot "IP Adddress mismatch, updating..."
  146.  
  147.         ABORT=0
  148.         CJ="${TMPDIR}/cookiejar.updateDNS"
  149.         CJOPT="-b ${CJ} -c ${CJ}"
  150.  
  151.         cd ${TMPDIR}
  152.         rm -f ${CJ}
  153.  
  154. # Set initial session information
  155.         echot "Getting initial session information..."
  156.         curl -s -o gkg.index 'https://www.gkg.net/' -s ${CJOPT}
  157.         dopauses "# Set initial session information"
  158.  
  159. # Login to GKG
  160.         echot "Logging in to GKG..."
  161.         curl -s -o gkg.login 'https://www.gkg.net/login' ${CJOPT} \
  162.                 -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
  163.                 -H 'content-type: application/x-www-form-urlencoded' \
  164.                 -H 'origin: https://www.gkg.net' -H 'referer: https://www.gkg.net/index.html' \
  165.                 --data-raw "destination=%2Findex.html&credential_0=${GKGUSER}&credential_1=${GKGPASS}"
  166.         echot "Repulling home page to validate login"
  167.         curl -s -o gkg.relogin 'https://www.gkg.net/' -s ${CJOPT}
  168.         EMSG=`grep -c "${GKGUSER}" gkg.relogin`
  169.         if ! [[ "${EMSG}" -gt "0" ]]; then
  170.                 echot "Unable to log in with provided credentials!  Exiting..."
  171.                 ABORT=1
  172.         else
  173.                 echot "    Logged in successfully..."
  174.         fi
  175.         dopauses "# Login to GKG"
  176.  
  177. # Pull manage zones page
  178.         if [[ "${ABORT}" == "0" ]]; then
  179.                 echot "Getting list of managable zones..."
  180.                 curl -s -o gkg.managedns ${CJOPT} 'https://www.gkg.net/protected/dnszone/manage'
  181.  
  182.                 ZID=`xmllint --html --xpath "//a[contains (text(), '${DN}')]" gkg.managedns 2>/dev/null | cut -d\" -f2 | cut -d\; -f2 | cut -d= -f2`
  183.                 MURL="https://www.gkg.net/protected/dnszone/manage?step=edit_rr_form;id=${ZID}"
  184.                 if ! [[ "${ZID}" != '^[0-9]+$' ]]; then
  185.                         echot "Unable to detect Zone ID for ${DN}!  Exiting..."
  186.                         ABORT=1
  187.                 else
  188.                         echot "    Found Zone ID ${ZID} for ${DN}"
  189.                 fi
  190.         dopauses "# Pull manage zones page"
  191.         fi
  192.  
  193. # Pull page for domain to edit
  194.         if [[ "${ABORT}" == "0" ]]; then
  195.                 echot "Getting domain edit page for ${DN}..."
  196.                 curl -s -o gkg.domrecord ${CJOPT}  \
  197.                         -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
  198.                         -H "referer: https://www.gkg.net/protected/dnszone/manage?step=view_zone&id=${ZID}" \
  199.                         ${MURL}
  200.                 EMSG=`grep -c ${DN} gkg.domrecord`
  201.                 if ! [[ "${EMSG}" -gt "0" ]]; then
  202.                         echot "Unable to find ${DN} in domain records!  Exiting..."
  203.                         ABORT=1
  204.                 else
  205.                         echot "    Have edit link for ${DN}"
  206.                 fi
  207.         dopauses "# Pull page for domain to edit"
  208.         fi
  209.  
  210. # Get UI for editing domain
  211.         if [[ "${ABORT}" == "0" ]]; then
  212.                 echot "Getting domain records page for ${DN}..."
  213.                 curl -s -o gkg.domview ${CJOPT} \
  214.                         -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
  215.                         "https://www.gkg.net/protected/dnszone/manage?step=view_zone;id=${ZID}"
  216.                 dCount=`grep -c "${DN}" gkg.domview 2>/dev/null`
  217.                 if ! [[ "${dCount}" -gt "0" ]]; then
  218.                         echot "Unable to find ${DN} in edit page!  Exiting..."
  219.                         ABORT=1
  220.                 else
  221.                         echot "    Got edit page for ${DN}"
  222.                 fi
  223.         dopauses "# Get UI for editing domain"
  224.         fi
  225.  
  226. # Get domain A records
  227. # If you need to update IPv6 records...I haven't figured that out yet
  228.         if [[ "${ABORT}" == "0" ]]; then
  229.                 echot "Getting A records for ${DN}..."
  230.                 curl -s -o gkg.domrecordAREC ${CJOPT} 'https://www.gkg.net/protected/dnszone/manage?step=rrs&type=A' \
  231.                         -H 'authority: www.gkg.net' \
  232.                         -H 'dnt: 1' \
  233.                         -H "referer: https://www.gkg.net/protected/dnszone/manage?step=view_zone;id=${ZID}"
  234.  
  235.                 RECID=`xmllint --html --xpath '//*[@id="tab-a"]/div/div/div[3]/p[4]/a[1]/@href' gkg.domrecordAREC 2>/dev/null | cut -d\" -f2 | cut -d\; -f2 | cut -d= -f2`
  236.                 EDITURL="https://www.gkg.net/protected/dnszone/manage?step=edit_rr_form;id=${RECID}"
  237.                 if ! [[ "${RECID}" != '^[0-9]+$' ]]; then
  238.                         echot "Unable to detect Record ID for ${HN}!  Exiting..."
  239.                         ABORT=1
  240.                 else
  241.                         echot "    Got record ID ${RECID} for ${HN}"
  242.                 fi
  243.         dopauses "# Get domain A records"
  244.         fi
  245.  
  246. # Parse the address change form to get all of the visible + hidden fields
  247.         if [[ "${ABORT}" == "0" ]]; then
  248.                 echot "Parsing address update form..."
  249.                 curl -s -o gkg.editrec ${CJOPT} "${EDITURL}"
  250.                 readarray -t HVALS < <(for i in $(xmllint --html --xpath '//*[@id="rr-form"]/input/@value' gkg.editrec 2>/dev/null); do echo $i | cut -d\" -f2; done)
  251.                 readarray -t HNAMES < <(for i in $(xmllint --html --xpath '//*[@id="rr-form"]/input/@name' gkg.editrec 2>/dev/null); do echo $i | cut -d\" -f2; done)
  252.                 HFDATA=""
  253.                 for i in 0 1 2; do
  254.                         HFDATA+="${HNAMES[${i}]}=`urlencode_od_awk ${HVALS[${i}]}`&"
  255.                 done
  256.                 HFDATA+="host=${HN}&data=${ExtIP}&ttl=86400"
  257.                 dopauses "# Parse the address change form to get all of the visible + hidden fields"
  258.         fi
  259.  
  260. # Submit the address change
  261.         if [[ "${ABORT}" == "0" ]]; then
  262.                 echot "Updating DNS address for ${HN}..."
  263.                 curl -s -o gkg.updatedrec 'https://www.gkg.net/protected/dnszone/manage' ${CJOPT} \
  264.                         -H 'authority: www.gkg.net' \
  265.                         -H 'content-type: application/x-www-form-urlencoded' \
  266.                         -H 'dnt: 1' \
  267.                         -H 'origin: https://www.gkg.net' \
  268.                         -H 'upgrade-insecure-requests: 1' \
  269.                         --data-raw "${HFDATA}"
  270.                 echot "Repulling domain records page for ${DN} to verify ${HN} to ${ExtIP}..."
  271.                 curl -s -o gkg.redomview ${CJOPT} \
  272.                         -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
  273.                         "https://www.gkg.net/protected/dnszone/manage?step=view_zone;id=${ZID}"
  274.                 UPDATED=`grep ${ExtIP} gkg.redomview | grep -c ${HN}`
  275.                 if ! [[ "${UPDATED}" -gt "0" ]]; then
  276.                         echot "Unable to detect updated address for ${HN} to ${ExtIP}!"
  277.                         ABORT=1
  278.                 else
  279.                         echot "    Updated ${HN} to ${ExtIP}"
  280.                 fi
  281.  
  282.                 echot "Done!"
  283.                 dopauses "# Submit the address change"
  284.         fi
  285. echot "Mailing logfile to ${MAILTO}"
  286. mail -s "DNS Update" ${MAILTO} < $OUTFILE
  287. fi
  288.  
  289. # Cleanup and mail logfile
  290. cd -
  291. rm $OUTFILE
  292. rm -rf ${TMPDIR}
  293.  
Advertisement
Add Comment
Please, Sign In to add comment