From e383520ebbb43c30c337cbe1a8a598aa581df76a Mon Sep 17 00:00:00 2001 From: Chad Date: Sun, 23 Jul 2023 13:14:47 -0700 Subject: [PATCH] Add Dynamic DNS Script (#9) * Initial commit for Dynamic DNS code. Not in a runnable state but as far as I can get for now. * Bring shell script for Dynamic DNS to working order. Dry runs are going well. Have not tested against a production environment yet. * Add instructions for No-IP in case it needs installed later.. * Variablize the full path to the keyfile. Enforce strict permissions on the file. * Final updates after successful testing. * Update instructions, add examples. * Fix usage. * Remove unnecessary asterisk. --- .gitignore | 4 +- Config/DynamicDNS/README.md | 66 ++++++++++++++ Config/DynamicDNS/update_dns.sh | 149 ++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 Config/DynamicDNS/README.md create mode 100755 Config/DynamicDNS/update_dns.sh diff --git a/.gitignore b/.gitignore index b7976a2..df0fc48 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ Config/ReverseProxy/config/hosts/* Config/ReverseProxy/config/load.conf.d/* Config/ReverseProxy/config/mail.conf.d/* -# Ignore MailServer Files +# Ignore downloaded mail server files Config/MailServer/setup.sh +# Ignore any private key information +private.key diff --git a/Config/DynamicDNS/README.md b/Config/DynamicDNS/README.md new file mode 100644 index 0000000..778eaca --- /dev/null +++ b/Config/DynamicDNS/README.md @@ -0,0 +1,66 @@ +# Dynamic DNS Updater + +This script is meant to be added to cron if you are using afraid.org as your +dynamic DNS provider. Similar may be possible with sites such as dyn.org or +noip.com but are currently not supported in this project. Links to some of these +product's self-built solutions can be found below. + +## Afraid.org Version 2 Instructions + +1. Install this project. + + ``` + git clone https://github.com/Hyperling/docker $PROJECT_DIR + ``` + +1. Add your Afraid DNS account key to $PROJECT_DIR/Config/DynamicDNS/private.key +Account key can be found [here](https://freedns.afraid.org/dynamic/v2/). + +1. Add this line to the system's cron scheduling using a command like `crontab -e`. + + ``` + 5 * * * * $PROJECT_DIR/Config/DynamicDNS/update_dns.sh + ``` + +### TESTING + +Please ensure all testing is done with the test or dry run flags. If you run +this for your private key outside of your network then your Dynamic DNS may +become inaccurate. This program is only intended to be run in a production +manner on the network which needs the Dynamic DNS pointing towards it. + +### Example + +``` +$ ./update_dns.sh -4 +Updated DOMAIN from 1:2:3:4:5:6:7:8 to 1.2.3.4 +HTTP200 +Status 0 is acceptable. +``` +``` +$ ./update_dns.sh -6 +Updated DOMAIN from 1.2.3.4 to 1:2:3:4:5:6:7:8 +HTTP200 +Status 0 is acceptable. +``` + +## Afraid.org Version 1 Instructions + +Add one of these to your crontab. Basically what the script does without fancy +options and checks. Please be concious of how often you knock on the servers, +and preferably add a 30-45 second sleep so that you do not hit near :00 seconds. + +``` +*/4 * * * * sleep 28; curl http://freedns.afraid.org/dynamic/update.php?YOUR_V1_KEY_GOES_HERE +``` +``` +*/7 * * * * sleep 42; wget -O http://freedns.afraid.org/dynamic/update.php?YOUR_V1_KEY_GOES_HERE +``` + +## Other Dynamic DNS Hosts + +### No-IP.org Instructions + +Please see this guide on installing the Dynamic Update Client (DUC). + +https://my.noip.com/dynamic-dns/duc diff --git a/Config/DynamicDNS/update_dns.sh b/Config/DynamicDNS/update_dns.sh new file mode 100755 index 0000000..f4d51f1 --- /dev/null +++ b/Config/DynamicDNS/update_dns.sh @@ -0,0 +1,149 @@ +#!/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