From c488329417fa86fbb7d7765a52255b4cad7fce5e Mon Sep 17 00:00:00 2001 From: KiekerJan Date: Sat, 5 Jun 2021 00:30:58 +0200 Subject: [PATCH] add dyndns tool --- tools/dyndns/dyndns.cfg | 1 + tools/dyndns/dyndns.domain | 1 + tools/dyndns/dyndns.dynlist | 3 + tools/dyndns/dyndns.sh | 201 ++++++++++++++++++++++++++++++++++++ tools/dyndns/dyndns.totp | 1 + 5 files changed, 207 insertions(+) create mode 100644 tools/dyndns/dyndns.cfg create mode 100644 tools/dyndns/dyndns.domain create mode 100644 tools/dyndns/dyndns.dynlist create mode 100755 tools/dyndns/dyndns.sh create mode 100644 tools/dyndns/dyndns.totp diff --git a/tools/dyndns/dyndns.cfg b/tools/dyndns/dyndns.cfg new file mode 100644 index 00000000..ddbe0513 --- /dev/null +++ b/tools/dyndns/dyndns.cfg @@ -0,0 +1 @@ +user = ":" diff --git a/tools/dyndns/dyndns.domain b/tools/dyndns/dyndns.domain new file mode 100644 index 00000000..d8cf886c --- /dev/null +++ b/tools/dyndns/dyndns.domain @@ -0,0 +1 @@ +. diff --git a/tools/dyndns/dyndns.dynlist b/tools/dyndns/dyndns.dynlist new file mode 100644 index 00000000..96d9e5fe --- /dev/null +++ b/tools/dyndns/dyndns.dynlist @@ -0,0 +1,3 @@ +vpn.. +nas.. + diff --git a/tools/dyndns/dyndns.sh b/tools/dyndns/dyndns.sh new file mode 100755 index 00000000..2cbf8bc6 --- /dev/null +++ b/tools/dyndns/dyndns.sh @@ -0,0 +1,201 @@ +#!/bin/bash +# based on dm-dyndns v1.0, dmurphy@dmurphy.com +# Shell script to provide dynamic DNS to a mail-in-the-box platform. +# Requirements: +# dig installed +# curl installed +# oathtool installed if totp is to be used +# OpenDNS myip service availability (myip.opendns.com 15) +# Mailinabox host (see https://mailinabox.email 2) +# Mailinabox admin username/password in the CFGFILE below +# one line file of the format (curl cfg file): +# user = “username:password” +# Dynamic DNS name to be set +# DYNDNSNAMELIST file contains one hostname per line that needs to be set to this IP. + +#----- Contents of dyndns.cfg file below ------ +#----- user credentials ----------------------- +#user = "admin@mydomain.com:MYADMINPASSWORD" +#----- Contents of dyndns.domain below -------- +# +#------ Contents of dyndns.dynlist below ------ +#vpn.mydomain.com +#nas.mydomain.com +#------ Contents of dyndns.totp --------------- +#- only needed in case of TOTP authentication - +#TOTP_KEY=ABCDEFGABCFEXXXXXXXX + +MYNAME="dyndns" +CFGFILE="$MYNAME.cfg" +TOTPFILE="$MYNAME.totp" +DOMFILE="$MYNAME.domain" +DIGCMD="/usr/bin/dig" +CURLCMD="/usr/bin/curl" +CATCMD="/bin/cat" +OATHTOOLCMD="/usr/bin/oathtool" +DYNDNSNAMELIST="$MYNAME.dynlist" + +if [ ! -x $DIGCMD ]; then + echo "$MYNAME: dig command $DIGCMD not found. Check and fix please." + exit 99 +fi + +if [ ! -x $CURLCMD ]; then + echo "$MYNAME: curl command $CURLCMD not found. Check and fix please." + exit 99 +fi + +if [ ! -x $CATCMD ]; then + echo "$MYNAME: cat command $CATCMD not found. Check and fix please." + exit 99 +fi + +DOMAIN=$(cat $DOMFILE) +MIABHOST="box.$DOMAIN" + +noww="$(date +"%F %T")" +echo "$noww: running dynamic dns update for $DOMAIN" + +if [ ! -f $CFGFILE ]; then + echo "$MYNAME: $CFGFILE not found. Check and fix please." + exit 99 +fi + +if [ ! -f $DYNDNSNAMELIST ]; then + echo "$MYNAME: $DYNDNSNAMELIST not found. Check and fix please." + exit 99 +fi + +MYIP="`$DIGCMD +short myip.opendns.com @resolver1.opendns.com`" + +if [ -z "MYIP" ]; then + MYIP="`$DIGCMD +short myip.opendns.com @resolver2.opendns.com`" +fi + +if [ -z "MYIP" ]; then + MYIP="`$DIGCMD +short myip.opendns.com @resolver3.opendns.com`" +fi + +if [ -z "MYIP" ]; then + MYIP="`$DIGCMD +short myip.opendns.com @resolver4.opendns.com`" +fi + +if [ -z "$MYIP" ]; then + MYIP=$($DIGCMD -4 +short TXT o-o.myaddr.l.google.com @ns1.google.com | tr -d '"') +fi + +if [ ! -z "$MYIP" ]; then + for DYNDNSNAME in `$CATCMD $DYNDNSNAMELIST` + do + PREVIP="`$DIGCMD A +short $DYNDNSNAME @$MIABHOST`" + if [ -z "$PREVIP" ]; then + echo "$MYNAME: dig output was blank." + fi + + if [ "x$PREVIP" = "x$MYIP" ]; then + echo "$MYNAME: $DYNDNSNAME ipv4 hasn't changed." + else + echo "$MYNAME: $DYNDNSNAME changed (previously: $PREVIP, now: $MYIP)" + + STATUS="`$CURLCMD -X PUT -K $CFGFILE -s -d $MYIP https://$MIABHOST/admin/dns/custom/$DYNDNSNAME/A`" + + case $STATUS in + "OK") echo "$MYNAME: mailinabox API returned OK, cmd succeeded but no update.";; + "updated DNS: $DOMAIN") echo "$MYNAME: mailinabox API updated $DYNDNSNAME ipv4 OK.";; + "invalid-totp-token"|"missing-totp-token") echo "$MYNAME: invalid TOTP token. Retrying with TOTP token" + if [ ! -x $AOTHTOOLCMD ]; then + echo "$MYNAME: oathtool command $OATHTOOLCMD not found. Check and fix please." + exit 99 + fi + + if [ ! -f $TOTPFILE ]; then + echo "$MYNAME: $TOTPFILE not found. Check and fix please." + exit 99 + fi + + source $TOTPFILE + + TOTP="X-Auth-Token: $(oathtool --totp -b -d 6 $TOTP_KEY)" + STATUST="`$CURLCMD -X PUT -K $CFGFILE -H "$TOTP" -s -d $MYIP https://$MIABHOST/admin/dns/custom/$DYNDNSNAME/A`" + + case $STATUST in + "OK") echo "$MYNAME: mailinabox API returned OK, cmd succeded but no update.";; + "updated DNS: $DOMAIN") echo "$MYNAME: mailinabox API updated $DYNDNSNAME ipv4 OK.";; + "invalid-totp-token") echo "$MYNAME: invalid TOTP token.";; + *) echo "$MYNAME: other status from mailinabox API. Please check: $STATUST (2)";; + esac + ;; + *) echo "$MYNAME: other status from mailinabox API. Please check: $STATUS (1)";; + esac + fi + done +else + echo "$MYNAME: No ipv4 address found. Check myaddr.google and myip.opendns.com services." + exit 99 +fi + + +# Now to do the same for ipv6 + +MYIP="`$DIGCMD AAAA @resolver1.ipv6-sandbox.opendns.com myip.opendns.com +short -6`" + +if [ -z "MYIP" ]; then + MYIP="`$DIGCMD AAAA @resolver2.ipv6-sandbox.opendns.com myip.opendns.com +short -6`" +fi + +if [ -z "$MYIP" ]; then + MYIP=$($DIGCMD -6 +short TXT o-o.myaddr.l.google.com @ns1.google.com | tr -d '"') +fi + +if [ ! -z "$MYIP" ]; then + for DYNDNSNAME in `$CATCMD $DYNDNSNAMELIST` + do + PREVIP="`$DIGCMD AAAA +short $DYNDNSNAME @$MIABHOST`" + if [ -z "$PREVIP" ]; then + echo "$MYNAME: dig output was blank." + fi + + if [ "x$PREVIP" = "x$MYIP" ]; then + echo "$MYNAME: $DYNDNSNAME ipv6 hasn't changed." + else + echo "$MYNAME: $DYNDNSNAME changed (previously: $PREVIP, now: $MYIP)" + + STATUS="`$CURLCMD -X PUT -K $CFGFILE -s -d $MYIP https://$MIABHOST/admin/dns/custom/$DYNDNSNAME/AAAA`" + + case $STATUS in + "OK") echo "$MYNAME: mailinabox API returned OK, cmd succeeded but no update.";; + "updated DNS: $DOMAIN") echo "$MYNAME: mailinabox API updated $DYNDNSNAME ipv6 OK.";; + "invalid-totp-token"|"missing-totp-token") echo "$MYNAME: invalid TOTP token. Retrying with TOTP token" + if [ ! -x $AOTHTOOLCMD ]; then + echo "$MYNAME: oathtool command $OATHTOOLCMD not found. Check and fix please." + exit 99 + fi + + if [ ! -f $TOTPFILE ]; then + echo "$MYNAME: $TOTPFILE not found. Check and fix please." + exit 99 + fi + + source $TOTPFILE + + TOTP="X-Auth-Token: $(oathtool --totp -b -d 6 $TOTP_KEY)" + STATUST="`$CURLCMD -X PUT -K $CFGFILE -H "$TOTP" -s -d $MYIP https://$MIABHOST/admin/dns/custom/$DYNDNSNAME/AAAA`" + + case $STATUST in + "OK") echo "$MYNAME: mailinabox API returned OK, cmd succeded but no update.";; + "updated DNS: $DOMAIN") echo "$MYNAME: mailinabox API updated $DYNDNSNAME ipv6 OK.";; + "invalid-totp-token") echo "$MYNAME: invalid TOTP token.";; + *) echo "$MYNAME: other status from mailinabox API. Please check: $STATUST (2)";; + esac + ;; + *) echo "$MYNAME: other status from mailinabox API. Please check: $STATUS (1)";; + esac + fi + done +else + echo "$MYNAME: No ipv6 address found. Check myaddr.google and myip.opendns.com services." + exit 99 +fi + + +exit 0 diff --git a/tools/dyndns/dyndns.totp b/tools/dyndns/dyndns.totp new file mode 100644 index 00000000..d066bbd0 --- /dev/null +++ b/tools/dyndns/dyndns.totp @@ -0,0 +1 @@ +TOTP_KEY=