HowTo: Stretch + dnscrypt-wrapper + Unbound + DNSSEC + Key-rotation 2019-07-12
With my recent departure from OpenVZ.ca/Media-Hosts.com I had to find a new hosting provider for the dnscrypt.ca resolvers. While building the new servers I thought it might be nice to update the key-rotation script and make it easier to get a fresh server started up quickly. You'll still have to go through the process of getting the software all setup, but at least now the script can take care of automating the query keys right from the start. The commands below generally need to be run as root, you can log in as root or use sudo, whatever makes you happy. Here's what to do:
Start off by installing some dependencies:
apt-get install resolvconf dnsutils net-tools build-essential automake libtool unzip unbound
Edit your Unbound config and add these lines to the end of it:
# nano /etc/unbound/unbound.conf
access-control: 127.0.0.1 allow
Now setup the named.root for Unbound, restart it, and test it.
wget -O /etc/unbound/named.root https://www.internic.net/domain/named.root
systemctl restart unbound
nslookup snork.ca 127.0.0.1
If you were able to successfully nslookup the address then your Unbound is working and you can move on to the installation of the wrapper and its dependencies.
mkdir ~/src && cd ~/src
wget -O libevent-wrapper-master.zip https://github.com/libevent/libevent/archive/master.zip
wget -O libsodium-latest.tar.gz https://download.libsodium.org/libsodium/releases/LATEST.tar.gz
wget -O dnscrypt-wrapper-master.zip https://github.com/cofyc/dnscrypt-wrapper/archive/master.zip
tar xzf libsodium-latest.tar.gz
I suggest that you use /etc/dnscrypt for your key directory, but you can put them wherever you like. If you also want to have an IPv6 listener you'll need a separate key directory such as /etc/dnscrypt-ipv6. Now make your server keys. You will have to change the provider-name to a name of your choosing (it must begin with "2.dnscrypt-cert") and you'll need to change ext-address to your server's listening IP address and port. Of course the dnssec, nolog, and nofilter options should only be present if you support DNSSEC, do not keep query logs, and do not filter query results respectively.
mkdir /etc/dnscrypt && cd /etc/dnscrypt
dnscrypt-wrapper --gen-provider-keypair --dnssec --nolog --nofilter --provider-name=2.dnscrypt-cert.CHANGE-ME --ext-address=220.127.116.11:443
After this step you will be presented with your sdns:// stamp and the parameters required for use with dnscrypt-proxy v1. These do not need to be kept secret, but they should be saved somewhere safe. You will also find your secret and public keyfiles in the current directory. The secret.key file should of course be kept secret and both files should be saved somewhere safe.
Now you are ready to use the key-rotation script to start up the wrapper listener. You'll need to download it to your key directory, edit it to suit your system, make it executable, and run it once to get your server started. Then add it to your crontab to rotate keys on whatever schedule you choose.
wget -O keyrotate.sh https://snork.ca/posts/2019-07-12-howto-stretch-dnscrypt-wrapper-unbound-dnssec-key-rotation/keyrotate.sh.txt
chmod +x keyrotate.sh
Do not run the script as is, you will need to modify it first, and hopefully also read through it so that you'll have an idea of what it does. At a minimum you will need to change a few variables at the top:
- keydir: should match the key directory such as /etc/dnscrypt
- bindto: must be set to your server's IP address and the port to listen on
- providername: must be the name you used earlier when you made your server keys
extresolver, wrapperbin, logfile, and grepfor should not have to be changed if you are following these instructions but they can be used to specify a different upstream DNS resolver, a different path to the wrapper binary, a different logfile location, and a different string used to locate currently running wrapper processes.
Once you have the script modified to suit your server, run it once:
and confirm that the wrapper is running:
ps ax | grep dnscrypt-wrapper
If you see the process listed then your server is listening and you can test a connection to it by using the dnscrypt-proxy client application (typically from a computer other than the server). Since your server is not currently listed in the public resolver list you need to add it manually and you need to force your client to use only your server. You'll find the "server_names" setting near the top, and the example "static" entries near the bottom of the example .toml file:
server_names = ['my-test-server']
stamp = 'sdns://abcdefg123456789hijklmn'
Now when you run your dnscrypt-proxy client it should connect only to your my-test-server entry and should allow you to resolve addresses via localhost through the proxy:
nslookup dnscrypt.ca 127.0.0.1
If that resolves properly, then it looks like your server is working. The keys should be rotated a few times per day, which is easily done by adding the script to your crontab on the server (of course you can choose whatever times you like).
crontab -e 0 2,10,18 * * * /etc/dnscrypt/keyrotate.sh