Все так же в рамках переезда на новый сервер и обустройства. ISPmanager по-умолчанию считает себя главным NS сервером. В качестве зависимых (внешних) поддерживаются серверы с установленными ISPmanager или DNSmanager. Покупать и, главное, устанавливать и поддерживать эти продукты для такой задачи показалось неразумным, поэтому получился такой конфиг.
1. Главный сервер с ISPmanager, на котором установлен PowerDNS. Тут мог бы быть и BIND, для данной схемы это не важно, но так уж получилось. Этот сервер нигде не светится и напрямую ни один домен не обслуживает. Это наш скрытый супермастер. Он не в курсе, что он супермастер, для себя самого он master, остальное настраивается на слэйвах.
Здесь важны 2 вещи в /etc/powerdns/pdns.conf
master=yes disable-axfr=no allow-axfr-ips=212.83.83.83,141.187.161.33
2. На отдельных VPS установлены 2 копии того же pdns в режиме slave. Далее нужно известить pdns о наличии супермастера. Для SQL backeng (gmysql в нашем случае) нужно добавить запись в табличку supermasters базы pdns.
insert into supermasters values ('192.168.111.111', 'ns1.example.com', 'internal');
В первой колонке (ip) должен быть адрес супермастера, во второй — имя NS, которое будет передаваться в AXFR, в третьей пользователь (для аутентификации, которая пока не работает). В данном случае ns1.example.com — это не имя супермастера, это имя одного из слейвов.
Если NOTIFY запрос для домена example.com слэйву пришел с адреса IP 192.168.111.111, если в зоне есть NS запись ns1.example.com, то слэйв создает у себя зону для example.com и перетаскивает к себе все записи. Ну и ведет себя в дальнейшем как нормальный slave.
Есть небольшая проблема — удаление зоны. Скрытый супермастер никак не извещает об удалении зоны, не положено. То есть оба slave будут продолжать считать себя ответственными за зоны, которых в них уже не должно быть.
Вот скрипт, который перидически (cron daily) проверяет все свои домены на присутствие у супермастера. Скрипт найден в сети и адаптирован под ответы pdns, они отличаются от bind (см. закомментированные строчки AUTH & if).
#!/bin/bash # Dependencies: # bind-utils # mysql-client #### Config ################################ DBUSER="pdns" DBPASS="LKgJHG55K7Jffs" #### End of Config ######################### MYSQL="mysql -u $DBUSER -p$DBPASS --skip-column-names --silent -e" check() { #AUTH=`dig @$1 $2 | grep "status" | awk -F , '{print $2}' | awk -F ': ' '{print $2}'` AUTH=`dig @$1 $2 | grep "flags" | awk -F : '{print $2}' | awk -F '; ' '{print $1}'|grep -ci 'aa'` #if [ $AUTH = "REFUSED" ] || [ $AUTH = "NXDOMAIN" ]; then if [ $AUTH = "0" ]; then echo "$1 $2: Server not AUTH or SERVfail - removing zone..." DOMAIN_ID=`$MYSQL "USE pdns; SELECT id FROM domains WHERE name='$2' AND type='SLAVE' AND master='$1' LIMIT 1;"` $MYSQL "USE pdns; DELETE FROM records WHERE domain_id='$DOMAIN_ID';" $MYSQL "USE pdns; DELETE FROM domains WHERE id='$DOMAIN_ID';" fi } MASTERS=(`$MYSQL "USE pdns; SELECT DISTINCT ip FROM supermasters;"`) for m in "${MASTERS[@]}"; do NAMES=(`$MYSQL "USE pdns; SELECT name FROM domains WHERE type = 'SLAVE' AND master = '${m}';"`) for d in "${NAMES[@]}"; do check ${m} ${d} done done
Несуществующие домены удаляются, вся система остается синхронизированной, все улыбаются.
В этой схеме может быть любое число супермастеров (серверов с ISPmanager). В случае с backend-gmysql то же самое можно было бы сделать посредством mysql, но так правильнее, mysql никак не светится в сети и нет зависимости от pdns на мастере.