Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- ####################################################################
- ##### Variable setting #####
- ####################################################################
- # Set this to one of your domain's authoritative name servers
- NS_SERVER="ns3.gkg.net"
- #Logfile location and notification address
- OUTFILE=/tmp/updateDNS.out
- MAILTO="mark@thisismyown.com"
- ####################################################################
- ##### Helper functions #####
- ####################################################################
- usage () {
- echot "\n"
- echot "Usage: [PAUSES=n] ${0} -u username -p password -h FQDN"
- echot ""
- echot " NOTE: The (sub)domain part of the name must be case-sensitive to your"
- echot " domain record at GKG. This is probably all-lowercase, but I haven't"
- echot " figured out the right way to case-insensitive XPATH-parse yet..."
- echot ""
- echot " If you want to make this slower, to debug the outfiles at each curl,"
- echot " include the optional PAUSES=n parameter before the script on the"
- echot " commandline. If PAUSES is set on the commandline at runtime, the"
- echot " script will pause 'n' seconds after each curl step, to allow you"
- echot " time to ^C and inspect the files being generated and parsed down"
- echot " the pipeline."
- echot "\n\n"
- exit 1
- }
- # Borrowed from https://unix.stackexchange.com/questions/60653/urlencode-function
- #
- # Thanks to https://unix.stackexchange.com/users/885/gilles-so-stop-being-evil
- urlencode_od_awk () {
- echo -n "$1" | od -t d1 | awk '{
- for (i = 2; i <= NF; i++) {
- printf(($i>=48 && $i<=57) || ($i>=65 && $i<=90) || ($i>=97 && $i<=122) ||
- $i==45 || $i==46 || $i==95 || $i==126 ?
- "%c" : "%%%02x", $i)
- }
- }'
- }
- dopauses () {
- if [[ "${PAUSES}" -gt "0" ]]; then
- echot "Pausing (${PAUSES}) -- ${*}"
- sleep ${PAUSES}
- fi
- }
- echot () {
- echo -e "${*}" | tee -a ${OUTFILE}
- }
- ####################################################################
- ##### Start Script #####
- ####################################################################
- ######################################
- # Prechecks and parameter parsing... #
- ######################################
- # Make sure we have all of our required utilities
- UTILS="sed tr dig grep awk date od mktemp mail xmllint"
- which --skip-alias ${UTILS} >/dev/null 2>&1; ECODE=${?}
- if [[ "${ECODE}" != "0" ]]; then
- echot Missing one of the required utilities!
- echot Fix this before continuing...
- echot
- echot `which --skip-alias ${UTILS} 2>&1 | sed 's/^/ /'`
- exit 1
- fi
- # Check to see if we preset PAUSES; if not, set it to 0 so that dopauses() skips
- if [[ -z ${PAUSES+x} ]]; then PAUSES=0; else echot "Pausing after each curl for ${PAUSES} seconds"; fi
- # Get userpass from parameters
- while getopts "u:p:h:" arg; do
- case $arg in
- u)
- GKGUSER=${OPTARG}
- ;;
- p)
- GKGPASS=`urlencode_od_awk ${OPTARG}`
- ;;
- h)
- HOSTARG=${OPTARG}
- HN=${HOSTARG%%.*}
- DN=`echo ${HOSTARG} | sed "s/${HN}\.//"`
- ;;
- *)
- usage
- ;;
- esac
- done
- if [[ -z "${GKGUSER}" || -z "${GKGPASS}" ]]; then
- echot "\n\nMust pass username and password!" && usage
- fi
- dopauses "\nDebugging if sleeping: user/pass/host/domain is: ${GKGUSER} / ${GKGPASS} / ${HN} / ${DN}\n\n"
- ###############
- # Time to go! #
- ###############
- # Temp directory creation and logfile cleanup
- TMPDIR=`mktemp -d`
- if [ -e ${OUTFILE} ]; then
- OLDOUTFILE=`ls $OUTFILE`
- rm $OUTFILE
- echot "Starting update at `date`"
- echot "Found old output file, deleted it"
- echot -- "* ${OLDOUTFILE}"
- echot ""
- else
- echot "Starting update at: `date`\n\n"
- fi
- # Get my current IP address
- while [ "${#ExtIP}" -gt 15 ] || [ "${#ExtIP}" -eq 0 ]; do
- ExtIP=`curl -s http://checkip.amazonaws.com`
- sleep 1
- done
- while [ "$DynIP" == "" ]; do
- DynIP=`dig ${HOSTARG} @${NS_SERVER}| grep -i "^${HOSTARG}" | awk '{print $5}'`
- sleep 1
- done
- echot "Current External IP is: ${ExtIP}"
- echot "${HOSTARG} is at: ${DynIP} \n\n\n"
- if [ "$ExtIP" == "$DynIP" ]; then
- echot "IP Addresses match"
- else
- echot "IP Adddress mismatch, updating..."
- ABORT=0
- CJ="${TMPDIR}/cookiejar.updateDNS"
- CJOPT="-b ${CJ} -c ${CJ}"
- cd ${TMPDIR}
- rm -f ${CJ}
- # Set initial session information
- echot "Getting initial session information..."
- curl -s -o gkg.index 'https://www.gkg.net/' -s ${CJOPT}
- dopauses "# Set initial session information"
- # Login to GKG
- echot "Logging in to GKG..."
- curl -s -o gkg.login 'https://www.gkg.net/login' ${CJOPT} \
- -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
- -H 'content-type: application/x-www-form-urlencoded' \
- -H 'origin: https://www.gkg.net' -H 'referer: https://www.gkg.net/index.html' \
- --data-raw "destination=%2Findex.html&credential_0=${GKGUSER}&credential_1=${GKGPASS}"
- echot "Repulling home page to validate login"
- curl -s -o gkg.relogin 'https://www.gkg.net/' -s ${CJOPT}
- EMSG=`grep -c "${GKGUSER}" gkg.relogin`
- if ! [[ "${EMSG}" -gt "0" ]]; then
- echot "Unable to log in with provided credentials! Exiting..."
- ABORT=1
- else
- echot " Logged in successfully..."
- fi
- dopauses "# Login to GKG"
- # Pull manage zones page
- if [[ "${ABORT}" == "0" ]]; then
- echot "Getting list of managable zones..."
- curl -s -o gkg.managedns ${CJOPT} 'https://www.gkg.net/protected/dnszone/manage'
- ZID=`xmllint --html --xpath "//a[contains (text(), '${DN}')]" gkg.managedns 2>/dev/null | cut -d\" -f2 | cut -d\; -f2 | cut -d= -f2`
- MURL="https://www.gkg.net/protected/dnszone/manage?step=edit_rr_form;id=${ZID}"
- if ! [[ "${ZID}" != '^[0-9]+$' ]]; then
- echot "Unable to detect Zone ID for ${DN}! Exiting..."
- ABORT=1
- else
- echot " Found Zone ID ${ZID} for ${DN}"
- fi
- dopauses "# Pull manage zones page"
- fi
- # Pull page for domain to edit
- if [[ "${ABORT}" == "0" ]]; then
- echot "Getting domain edit page for ${DN}..."
- curl -s -o gkg.domrecord ${CJOPT} \
- -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
- -H "referer: https://www.gkg.net/protected/dnszone/manage?step=view_zone&id=${ZID}" \
- ${MURL}
- EMSG=`grep -c ${DN} gkg.domrecord`
- if ! [[ "${EMSG}" -gt "0" ]]; then
- echot "Unable to find ${DN} in domain records! Exiting..."
- ABORT=1
- else
- echot " Have edit link for ${DN}"
- fi
- dopauses "# Pull page for domain to edit"
- fi
- # Get UI for editing domain
- if [[ "${ABORT}" == "0" ]]; then
- echot "Getting domain records page for ${DN}..."
- curl -s -o gkg.domview ${CJOPT} \
- -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
- "https://www.gkg.net/protected/dnszone/manage?step=view_zone;id=${ZID}"
- dCount=`grep -c "${DN}" gkg.domview 2>/dev/null`
- if ! [[ "${dCount}" -gt "0" ]]; then
- echot "Unable to find ${DN} in edit page! Exiting..."
- ABORT=1
- else
- echot " Got edit page for ${DN}"
- fi
- dopauses "# Get UI for editing domain"
- fi
- # Get domain A records
- # If you need to update IPv6 records...I haven't figured that out yet
- if [[ "${ABORT}" == "0" ]]; then
- echot "Getting A records for ${DN}..."
- curl -s -o gkg.domrecordAREC ${CJOPT} 'https://www.gkg.net/protected/dnszone/manage?step=rrs&type=A' \
- -H 'authority: www.gkg.net' \
- -H 'dnt: 1' \
- -H "referer: https://www.gkg.net/protected/dnszone/manage?step=view_zone;id=${ZID}"
- 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`
- EDITURL="https://www.gkg.net/protected/dnszone/manage?step=edit_rr_form;id=${RECID}"
- if ! [[ "${RECID}" != '^[0-9]+$' ]]; then
- echot "Unable to detect Record ID for ${HN}! Exiting..."
- ABORT=1
- else
- echot " Got record ID ${RECID} for ${HN}"
- fi
- dopauses "# Get domain A records"
- fi
- # Parse the address change form to get all of the visible + hidden fields
- if [[ "${ABORT}" == "0" ]]; then
- echot "Parsing address update form..."
- curl -s -o gkg.editrec ${CJOPT} "${EDITURL}"
- 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)
- 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)
- HFDATA=""
- for i in 0 1 2; do
- HFDATA+="${HNAMES[${i}]}=`urlencode_od_awk ${HVALS[${i}]}`&"
- done
- HFDATA+="host=${HN}&data=${ExtIP}&ttl=86400"
- dopauses "# Parse the address change form to get all of the visible + hidden fields"
- fi
- # Submit the address change
- if [[ "${ABORT}" == "0" ]]; then
- echot "Updating DNS address for ${HN}..."
- curl -s -o gkg.updatedrec 'https://www.gkg.net/protected/dnszone/manage' ${CJOPT} \
- -H 'authority: www.gkg.net' \
- -H 'content-type: application/x-www-form-urlencoded' \
- -H 'dnt: 1' \
- -H 'origin: https://www.gkg.net' \
- -H 'upgrade-insecure-requests: 1' \
- --data-raw "${HFDATA}"
- echot "Repulling domain records page for ${DN} to verify ${HN} to ${ExtIP}..."
- curl -s -o gkg.redomview ${CJOPT} \
- -H 'authority: www.gkg.net' -H 'dnt: 1' -H 'upgrade-insecure-requests: 1' \
- "https://www.gkg.net/protected/dnszone/manage?step=view_zone;id=${ZID}"
- UPDATED=`grep ${ExtIP} gkg.redomview | grep -c ${HN}`
- if ! [[ "${UPDATED}" -gt "0" ]]; then
- echot "Unable to detect updated address for ${HN} to ${ExtIP}!"
- ABORT=1
- else
- echot " Updated ${HN} to ${ExtIP}"
- fi
- echot "Done!"
- dopauses "# Submit the address change"
- fi
- echot "Mailing logfile to ${MAILTO}"
- mail -s "DNS Update" ${MAILTO} < $OUTFILE
- fi
- # Cleanup and mail logfile
- cd -
- rm $OUTFILE
- rm -rf ${TMPDIR}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement