Advertisement
MNeill

GKG DNS Updater

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