#!/bin/bash ##################################################################### # Snorkasaurus: 2019-07-10 # https://snork.ca/gitsucks#dnscrypt-keyrotate # # Script to rotate dnscrypt-wrapper keys. # Should be cron'ed a few times a day. # Modify these lines to suit your system. # providername can be anything but must start with "2.dnscrypt-cert" # extresolver is your upstream resolver (hopefully a recursive server # that you control). # bindto is where the wrapper will listen. # grepfor is your bindto rewritten as a regular expression, this is # required for the getpids function to work (escape dots on IPv4 # and square backets on IPv6) # keydir is where to store the key files. ##################################################################### logfile=/etc/dnscrypt/wrapper.log datefmt=$(date +"%Y-%m-%d %H:%M:%S") wrapperbin=/usr/local/sbin/dnscrypt-wrapper providername=2.dnscrypt-cert.dnscrypt.ca-1 extresolver=127.0.0.1:53 bindto="167.114.220.125:443" grepfor="167\.114\.220\.125:443" keydir=/etc/dnscrypt # You probably do not need to modify below this line. # But should read it so you know what it does. # =================================================================== # Functions: ######################################################## getpids () { # Grabs PIDs of existing dnscrypt-wrapper so they can be killed pids=`ps ax|egrep "$grepfor" | grep -v grep | awk ' { print $1 }'` } killpids () { # Kills the pids found by getpids if [ "$pids" != "" ]; then kill -9 $pids fi } # End of functions ################################################## cd $keydir ### Here's what happens if there's two full cert/keys present ####### if [ -f 1.cert ] && [ -f 1.key ] && [ -f 2.cert ] && [ -f 2.key ]; then echo $datefmt [WARN] There are two sets of cert/keys present >> $logfile # Figure out which set is older if [ 1.cert -ot 2.cert ]; then echo $datefmt [INFO] 2.cert is newer, starting wrapper with 2.key and 2.cert >> $logfile # 2.cert is newer getpids $wrapperbin --resolver-address=$extresolver --listen-address=$bindto --provider-name=$providername --crypt-secretkey-file=2.key --provider-cert-file=2.cert & rm 1.cert rm 1.key killpids # Exit after starting up wrapper with 2.cert and 2.key exit else echo $datefmt [INFO] 1.cert is newer, starting wrapper with 1.key and 1.cert >> $logfile # 1.cert is newer getpids $wrapperbin --resolver-address=$extresolver --listen-address=$bindto --provider-name=$providername --crypt-secretkey-file=1.key --provider-cert-file=1.cert & rm 2.cert rm 2.key killpids # Exit after starting up wrapper with 1.cert and 1.key exit fi ### Here's what happens if there's a 1.cert/key ##################### elif [ -f 1.cert ] && [ -f 1.key ]; then echo $datefmt [INFO] Found existing 1.cert/key >> $logfile # Create 2.cert/key if [ -f 2.cert ]; then rm 2.cert; fi if [ -f 2.key ]; then rm 2.key; fi echo $datefmt [INFO] Generate 2.cert/key >> $logfile $wrapperbin --gen-crypt-keypair --xchacha20 --crypt-secretkey-file=2.key $wrapperbin --gen-cert-file --xchacha20 --crypt-secretkey-file=2.key --provider-cert-file=2.cert --provider-publickey-file=public.key --provider-secretkey-file=secret.key --cert-file-expire-days=1 getpids echo $datefmt [INFO] Start a new wrapper with all both keysets >> $logfile $wrapperbin --resolver-address=$extresolver --listen-address=$bindto --provider-name=$providername --crypt-secretkey-file=1.key,2.key --provider-cert-file=1.cert,2.cert & echo $datefmt [INFO] Kill off old wrappers >> $logfile killpids echo $datefmt [INFO] Waiting 70 mins >> $logfile sleep 15000 getpids echo $datefmt [INFO] Making new wrapper with just 2.cert/key >> $logfile $wrapperbin --resolver-address=$extresolver --listen-address=$bindto --provider-name=$providername --crypt-secretkey-file=2.key --provider-cert-file=2.cert & echo $datefmt [INFO] Kill off old wrappers >> $logfile killpids # Get rid of stray files if [ -f 1.cert ]; then rm 1.cert; fi if [ -f 1.key ]; then rm 1.key; fi # Exit, leaving behind just 2.cert/key exit ### Here's what happens if there's a 2.cert/key ##################### elif [ -f 2.cert ] && [ -f 2.key ]; then echo $datefmt [INFO] Found existing 2.cert/key >> $logfile # Create 1.cert/key if [ -f 1.cert ]; then rm 1.cert; fi if [ -f 1.key ]; then rm 1.key; fi echo $datefmt [INFO] Generate 1.cert/key >> $logfile $wrapperbin --gen-crypt-keypair --xchacha20 --crypt-secretkey-file=1.key $wrapperbin --gen-cert-file --xchacha20 --crypt-secretkey-file=1.key --provider-cert-file=1.cert --provider-publickey-file=public.key --provider-secretkey-file=secret.key --cert-file-expire-days=1 getpids echo $datefmt [INFO] Start a new wrapper with all both keysets >> $logfile $wrapperbin --resolver-address=$extresolver --listen-address=$bindto --provider-name=$providername --crypt-secretkey-file=2.key,1.key --provider-cert-file=2.cert,1.cert & echo $datefmt [INFO] Kill off old wrappers >> $logfile killpids echo $datefmt [INFO] Waiting 70 mins >> $logfile sleep 15000 getpids echo $datefmt [INFO] Making new wrapper with just 1.cert/key >> $logfile $wrapperbin --resolver-address=$extresolver --listen-address=$bindto --provider-name=$providername --crypt-secretkey-file=1.key --provider-cert-file=1.cert & echo $datefmt [INFO] Kill off old wrappers >> $logfile killpids # Get rid of stray files if [ -f 2.cert ]; then rm 2.cert; fi if [ -f 2.key ]; then rm 2.key; fi # Exit, leaving behind just 1.cert/key exit ### If the script gets to here, something must have gone wrong ###### else echo $datefmt [ERR!] Something went wrong, starting over with fresh key and cert >> $logfile echo $datefmt [ERR!] Clients will not be able to resolve until they fetch this new key >> $logfile if [ -f 1.cert ]; then rm 1.cert; fi if [ -f 1.key ]; then rm 1.key; fi if [ -f 2.cert ]; then rm 2.cert; fi if [ -f 2.key ]; then rm 2.key; fi $wrapperbin --gen-crypt-keypair --xchacha20 --crypt-secretkey-file=1.key $wrapperbin --gen-cert-file --xchacha20 --crypt-secretkey-file=1.key --provider-cert-file=1.cert --provider-publickey-file=public.key --provider-secretkey-file=secret.key --cert-file-expire-days=1 $wrapperbin --resolver-address=$extresolver --listen-address=$bindto --provider-name=$providername --crypt-secretkey-file=1.key --provider-cert-file=1.cert & # Exit after dumping everything and starting fresh exit fi