Раньше в домашней сети использовал pihole, в установке из 1 ноды. Этого хватало, но с увеличением количества "клиентов" начались проблемы. Локальные запси постоянно отваливались, кэш практически не работал, моментами вовсе умирал.
Из вариантов, предназначенных для домашних лабораторий вариантов остается не много, а если быть точным - только AdGuardHome.
По моим наблюдениям - 50 активных "клиентов" для AdGuard это не проблема, ничего не отваливается. Работоспособность кэша остается спорным вопросом, никаких красивых графиков мне найти не удалось.
Из плюсов, по сравнению pihole, можно выделить DOT и DOH для вышестоящих серверов. Заморочек не много, нужно посетить сайт AdGuard и выбрать понравившиеся . Так же, есть некоторое количество "балансировок" между dns серверами пересылки, для себя я выбрал "Fastest IP address", запрос отправляется сразу на все сервера, что может ускорить резолв.
Как было сказано в предисловии - будет использоваться AdGuardHome.
Для обеспечения отказоустойчивости будет использоваться классический вариант реализации vrrp протокола на linux - keepalived.
Так же, нужно что бы конфиг (все настройки сервера конфигурируется 1 файлом, что очень удобно) AdGuard был одинаков на обоих нодах. Тут реализаций много, но я выбрал простейшую - rsync. Да, можно прикрутить syncthing или unison, но это более тяжелые варианты, которые требуют сильно больше уделенного времени, мониторинга, постоянного обновления ПО и даже решения конфликтов.
Тут всё очень скромно (но а большего и не нужно, базовый минимум):
2 ВМ на разных физических хостах. Используется 1 цпу и 1 ГиБ озу (в shared режиме, минимально 512Миб). На каждой ВМ по 12ГиБ диска, примонтированного в /. Этого должно быть с большим запасом.
ОС я решил использовать последний debian, а именно 13.1.
Ничего сверхъестественного тут нет, займет не больше 10 минут:
apt-get update && apt-get install curl keepalived rsync -y
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v #Команда взята с офф сайта
После этого нужно зайти в web интерфейс и настроить всё что хочется.
На 2 сервере установить всё тоже надо, но конфигурировать в web - нет.
Далее руками немного редактируем конфиг AdGuard, он находится в /opt/AdGuardHome.
Открываем его
vim /opt/AdGuardHome/AdGuardHome.yaml
Ищем всё где указан локальный ip и нужно убрать все привязки к локальному ip, так как будем использовать VIP.
На данный момент привязок всего две, меняем локальный ip на 0.0.0.0:
1.
http:
...
address: 0.0.0.0:80
dns:
bind_hosts:
- 0.0.0.0
Сейчас можно перезагрузить сервис и протестировать что всё работает:
systemctl restart AdGuardHome
Опять же, на 2 ноже этого делать не имеет смысла.
Тут сильно много думать не надо, пушим конфигу, меняя некоторые параметры на свои:
На первой ноде:
vrrp_instance VI_1 {
state MASTER
interface ens18 #Меняем, если это не так
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass qqqqqq #Пароль обязательно меняем, до 8 символов
}
unicast_src_ip 192.168.111.8 #Это ip адрес первой ноды
unicast_peer {
192.168.111.9 #Это ip адрес второй ноды
}
virtual_ipaddress {
192.168.111.10/16 #Это vip, по которму будем обращаться
}
track_script {
check_adguard
}
}
vrrp_script check_adguard {
script "[[ -n \"$(ss -tulnp | grep ':53 ')\" ]] && timeout 2 dig @127.0.0.1 localhost A +short >/dev/null 2>&1"
interval 3
weight -20
fall 3
rise 2
}
}
На второй ноде:
vrrp_instance VI_1 {
state BACKUP
interface ens18 #Тут тоже меняем, если это не так
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass qqqqqq #Пароль как и на 1 ноде
}
unicast_src_ip 192.168.111.9 #ДАнные 2 параметра - зеркальны параметрам на 1 ноде
unicast_peer {
192.168.111.8
}
virtual_ipaddress {
192.168.111.10/16 #vip такой же как и на 1 ноде
}
track_script {
check_adguard
}
}
vrrp_script check_adguard {
script "[[ -n \"$(ss -tulnp | grep ':53 ')\" ]] && timeout 2 dig @127.0.0.1 localhost A +short >/dev/null 2>&1"
interval 3
weight -20
fall 3
rise 2
}
Немного объясню:
Можно запустить keepalived:
systemctl enable --now keepalived
Смотрим на первой ноде:
ip -br a
В течении секунд 10 после запуска vip должен появиться на указанном ранее интерфейсе.
Как писАл выше - буду использовать rsync, само простой и надежный вариант.
Нужен всего 1 скрипт и сервис.
Скрипт "вытягивает" конфиг с другой ноды, при условии что на данный момент сам не является мастером (то есть vip на другой ноде) и перезагружает сервис.
Сначала нужно прокинуть ssh ключики под root с каждой ноды на каждую. Ну и само собой - нужно разрешить root login без пароля.
Создаем вспомогательную папку, что бы не плодить вечный беспорядок:
mkdir /scripts && cd /scripts
И вставляем следующий скрипт в файл /scripts/AdGuardSync.sh:
#!/bin/bash
MASTER_IP="192.168.111.10" #Vip
LEFT_IP="192.168.111.9" #ip следующей ноды
CONF="/opt/AdGuardHome/AdGuardHome.yaml"
SERVICE="AdGuardHome"
while true; do
if ip a | grep -q "$MASTER_IP"; then
echo "Im a master. Nothing to do."
# exit 0
else
echo "Im not a master. Sync and restart AdGuardHome...."
rsync -avz root@$LEFT_IP:$CONF $CONF
systemctl restart $SERVICE
fi
echo "Go sleep 987s"
sleep 987
done
Установим правильные права на файл:
chmod 700 /scripts/AdGuardSync.sh
На второй ноде проделываем аналогичное, но только меняем переменную LEFT_IP.
Создадим сервис, тут уже на 2х нодах всё будет одинаково:
cat << EOF1 > /etc/systemd/system/AdGuardHome_sync.service
Description=Automatating synchronization of AdGuardHome config
After=network.target
[Service]
Type=simple
User=root
ExecStart=/scripts/AdGuardSync.sh
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF1
Перечитываем демонов:
systemctl daemon-reload
Ну и запускаем сервис:
systemctl enable --now AdGuardHome_sync
Теперь раз в 987 секунд бэкап нода будет вытягивать конфиг с мастера. Время можно сократить, хоть до 1 секунды, но мне это не нужно.
AdGuardHome работает и 1 из 2х нод может упасть, никто из-за этого ругаться не будет.
Можно добавить мониторингов всяких, но не считаю нужным. Ломаться тут нечему. Если одна ВМ упадет - вероятно гипервизор тоже прилег
По аналогии можно добавить ещё нод, нужно будет в keepalived указать ещё один unicast_peer и немного видоизменить скрипт (Добавить цикл перебора ip, в нем проверку на мастера).