Hack your own HA!

Posted by Sander van Kasteel on December 14, 2022 · 539 words, 3 mins read

Categories:

So, for a while now I’ve been running AdGuardHome across my network. Which is great, since it allows me either use their “block services” functionality (so I can block certain services like, YouTube or Spotify at will) and have the possibility to use adblock across my entire network.

There is only one caveat with AdGuardHome. It doesn’t have any built-in support for High Availabilty (called HA, from this point). So a while back, when my storage pool crashed, so I was in the situation where my homeserver (on which AdGuardHome runs) was down but I also couldn’t do DNS traffic because AdGuardHome was down. That’s not really a situation where you would want to be in. So after I got my homeserver back online, I decided to see if I could make my AdGuardHome, highly available.

But alas, out of the box AdGuardHome does not support HA. But luckily we can something hack it together, that would kinda resemble HA. Good enough, I guess? 🤷

So first off all, we will need an additional machine to load up AdGuardHome upon. I decided it was gonna be a Raspberry Pi 3, just because that was something I still had laying around. So I loaded up AdGuardHome through Docker and off I went. But, I still needed a way to sync settings between the AdGuardHome instance on my homeserver and the instance on my Pi. To achieve that, I decided the following. The AdGuardHome instance on my homeserver was considered my “primary” instance, the instance on my Pi was considered “secondary”. That means that all configuration changes need to be pushed to my Pi. And for that, I wrote the following shell script.

#!/usr/bin/env bash

function trigger_update_cousteau() {
    echo "Running update on cousteau"
    ssh root@10.0.0.4 'bash ~/tools/update_adguard_config.sh'
}

inotifywait -m /storage/configuration/adguard/conf |
    while read path action file; do
        sleep 2
        trigger_update_cousteau
    done

This script, is loaded via supervisord (configuration is below) and the only thing, that that script does is;

  • Monitor changes in the configuration files of AdGuardHome
  • If it sees them, it will sleep 2 seconds (just to make sure that all changes are written).
  • It will login into the my Raspberry Pi (called cousteau) and have that pull in configuration changes.

Supervisor configuration

[program:adguardhome-config-updater]
process_name="adguardHome_config_updater"
command=/root/tools/watch_adguard_config.sh
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/supervisor/adguard-config_update.log

The script that’s on Raspberry pi is the following;

#!/usr/bin/env bash

SSL_DIRECTORY_HAWKING=/etc/letsencrypt/live/redacted.sandervankasteel.nl/

scp root@10.0.0.3:"$SSL_DIRECTORY_HAWKING/privkey.pem" /srv/configuration/adguardhome/certs/privkey.pem
scp root@10.0.0.3:"$SSL_DIRECTORY_HAWKING/fullchain.pem" /srv/configuration/adguardhome/certs/fullchain.pem

scp root@10.0.0.3:/storage/configuration/adguard/conf/AdGuardHome.yaml /srv/configuration/adguardhome/conf

docker restart adguardhome-adguardhome-1

What it will do is, via SCP copy over the SSL certificates (needed for DoH (DNS over HTTPS) and DoT (DNS over TLS)), secondly copy over the configuration file (AdGuardHome.yaml) and once that is done, it force Docker to restart the AdGuardHome container.

And that’s it, that’s a quick and dirty way to achieve High Availability with AdGuardHome.

If you have any questions after this post, feel free to send me a message over at, Mastdon, email using the contact form or use the Disqus comment box below.