#!/bin/bash # 2023-05-18 Hyperling # Keep afraid.org dynamic DNS synced on ISP connections without static IPs. ## Setup ## DIR="`dirname $0`" PROG=`basename $0` if [[ $DIR == "."* ]]; then DIR="`pwd`" fi DOMAIN="sync.afraid.org" PROTOCOL="http" KEYFILE_NAME="private.key" KEYFILE="$DIR/$KEYFILE_NAME" ## Functions ## function usage { # Accepts 1 parameter: The exit code to use. exit_status=$1 echo "Usage: $PROG [-4] [-6] [-d | -t] [-v] [-h]" 1>&2 cat <<- EOF Program reads the local $KEYFILE_NAME and syncs with the Dynamic DNS provider. Current DNS providers are mentioned in the README, but initally only afraid.org is being supported since that is the maintainer's primary usage. More may be added eventually or you're welcome to contribute. Parameters: -4 : Update IPV4. -6 : Update IPV6. * If neither 4 or 6 are provided, 4 is assumed as Yes. -d : Perform a dry run, echoing the commands rather than doing the update. -t : Test run. Alias for the dry run option above. -v : Enable extra output, helpful for debugging. -h : Print this list of parameters. EOF exit $exit_status } function check { # Accepts parameter of status and whether the program should quit. status=$1 quit=$2 if [[ $status != 0 ]]; then echo "ERROR: Did not receive a successful return message, got $status." 1>&2 if [[ $quit == "Y" ]]; then exit $status fi fi echo "Status $status is acceptable." } ## Validations ## # Ensure the account key is present and has contents. if [[ ! -s $KEYFILE ]]; then echo "ERROR: Key file '$KEYFILE' is empty or does not exist." 1>&2 echo -e "Please see '$DIR/README.md' for instructions.\n" usage fi ## Parameters ## while getopts ":46dtvh" opt; do case $opt in 4) v4="Y" ;; 6) v6="Y" ;; d | t) dry_run="Y" ;; v) set -x ;; h) usage 0 ;; *) echo "ERROR: Parameter $opt not recognized." usage 1 ;; esac done # Cannot set both 4 and 6, otherwise only the 2nd takes effect. if [[ -n $v4 && -n $v6 ]]; then echo "ERROR: Cannot set both v4 and v6, please only choose one." 1>&2 usage 1 fi # If neither parameter was passed, assume 4 is wanted. if [[ -z $v4 && -z $v6 ]]; then v4="Y" fi ## Main ## # Use echo instead of cURL if doing a dry/test run. command="curl -w HTTP%{http_code}\n" if [[ $dry_run == "Y" ]]; then command="echo $command" fi # Ensure permissions are strict. chmod -c 600 $KEYFILE # Get the user's key if [[ -n $KEYFILE ]]; then key=`cat $KEYFILE` else echo "ERROR: Cannot find '$KEYFILE'. Please set up your account key." 1>&2 usage 1 fi # Remove any padding like newlines or trailing spaces key=`echo $key` # Ensure we got a value if [[ -z $key ]]; then echo "ERROR: Key contents were not read, is '$KEYFILE' set up proerly?." 1>&2 usage 1 fi # Try to ensure the key is not going to cause a malformed link somehow. if [[ $key == *" "* ]]; then echo "WARNING: Space character found in key. Is that correct? Converting to %20." 1>&2 key=${key// /%20} fi uri="$DOMAIN/u/$key/" # Connect with the provider. if [[ $v4 == "Y" ]]; then $command $PROTOCOL://$uri check $? Y fi if [[ $v6 == "Y" ]]; then $command $PROTOCOL://v6.$uri check $? Y fi exit 0