From: Alex Samorukov <samm@os2.kiev.ua.>
Date: Mon, 6 Mar 2008 14:31:37 +0000 (UTC)
Subject: Автоматическая синхронизация файлов конфигурации master и slave DNS серверов
Зачем это нужно?
Для одного из проектов мне потребовалось обеспечить автоматическое
распространение DNS зон, прописанных на master dns, slave серверам. Так
как зон ожидалось не больше 100-200 мне хотелось сделать максимально
простую, но в тоже время безопасную схему синхронизации серверов, без
использования LDAP или SQL в качестве backend. В итоге я решил задачу
используя shell скрипты, которыми решил поделиться с общественностью.
Всё нижеописанное работает на OS FreeBSD но должно без проблем работать
и в любой другой UNIX OS c BIND в роли DNS.
Как это работает
Все master зоны на primary dns лежат в отдельной директории
(/etc/namedb/master-auto) и названы в формате <domain>.db.
Например example.com.db, kernel.org.db и т.п. Это важный момент, так как
на этом основан алгоритм получения списка доменов (это проще и удобнее
чем читать named.conf). Используя протокол SSH клиенты (secondary
сервера) запрашивают у primary сервера список доменов и, в случае
различий с локальным списком, обновляют конфигурацию. Клиентов может
быть сколько угодно, обновление происходит по cron, например, раз в 10
минут. Для безопасного транспорта содержимого зон используется TSIG
протокол.
Конфигурация сервера
Как я уже писал выше, primary сервер должен по протоколу SSH отдавать
список обслуживаемых доменов. Для этого я завёл пользователя dnssync.
Shell данного пользователя будет специально созданный для данной цели sh
скрипт.
# pw user add dnssync -s /home/dnssync/domainlist.sh
Пароль пользователю не нужен, так как для подключения будет
использоваться SSH ключ.
Теперь создадим сам скрипт:
mkdir /home/dnssync; chmod 700 /home/dnssync;
vi /home/dnssync/domainlist.sh
#!/bin/sh
export COLUMNS=1
# directory with <zone>.db files
cd /etc/namedb/master-auto
echo "DOMAINLIST_START"
/bin/ls *.db|/usr/bin/sed 's/.db//'
echo "DOMAINLIST_END"
Корректируем права доступа:
chmod +x /home/dnssync/domainlist.sh
Как видно из текста скрипта, всё что он делает - это получает список
файлов в директории, убирает суффикс .db и добавляет к выводу
DOMAINLIST_START перед листингом и DOMAINLIST_END в конце вывода. Для
проверки запустите /home/dnssync/domainlist.sh - должно быть что-то
вроде
Теперь перейдём к настройке secondary DNS. Для начала нам потребуется
настроить авторизацию по ключу для подключения к главному серверу. Если
ключ ещё не создан, запустим ssh-keygen, указав пустой passphrase. Нам
потребуется скопировать публичный ключ (по умолчанию
/root/.ssh/id_rsa.pub в FreeBSD) в список авторизованных ключей на
главном сервере (в файл /home/dnssync/.ssh/authorized_keys). В этом же
файле можно задать IP адрес владельца ключа для большей безопасности.
Чтобы убедиться, что всё работает, на клиенте введём команду ssh
dnssync@<master_ip>, например # 'ssh dnssync@1.2.3.4 sync'. Последний
аргумент требуется, чтобы сервер не показывал motd и прочие радости. В
случае правильной настройки должен быть выведен список доменов, без
запроса пароля.
Теперь установим клиентский скрипт, который отвечает за изменение
конфигурации BIND и его перезапуск:
# fetching domain list from the master
/usr/bin/ssh -o BatchMode=yes ${MASTERUSER}@${MASTERHOST} fetch > ${DNSTMPDIR}/domains.tmp </dev/null
if [ "$?" -ne "0" ]; then
echo "Error while transferring"
exit 1
fi
# simple check of the received file
if [ -z `grep DOMAINLIST_START ${DNSTMPDIR}/domains.tmp` -o -z `grep DOMAINLIST_END ${DNSTMPDIR}/domains.tmp` ]; then
echo "Invalid data received"
exit 1;
fi
# check if the files are equal
if [ -f ${DNSTMPDIR}/domains -a -z "`/usr/bin/cmp ${DNSTMPDIR}/domains.tmp ${DNSTMPDIR}/domains 2>/dev/null`" ]; then
# files are equal, do nothing
exit 0;
fi
# copy temporary file to the primary
/bin/cp ${DNSTMPDIR}/domains.tmp ${DNSTMPDIR}/domains
# creating output file for the dns
/usr/bin/grep -v DOMAINLIST_ ${DNSTMPDIR}/domains
| sed 's/(.*)/zone "1" in { type slave; file "slave/1.db"; masters {'${MASTERHOST}';}; };/'
> /etc/namedb/slave.conf
/etc/rc.d/named restart >/dev/null
Корректируем права доступа:
chmod 700 /root/bin/dnssync.sh
Этот скрипт при запуске подключается к master серверу, скачивает список
доменов (проверяя его корректность), сравнивает с имеющимся файлов и в
случае изменений создаёт /etc/namedb/slave.conf, содержащий список slave
зон после чего перезапускает BIND. Запустите скрипт, в случае если всё
работает правильно вы должны получить файл /etc/namedb/slave.conf
содержащий конфигурацию slave зон. Чтобы named читал этот файл добавим
строчку 'include "slave.conf";' в файл /etc/named.conf и перезапустим
named. В случае отсутствия ошибок в директории /etc/namedb/slave
появятся файлы зон. Для автоматической работы скрипт dnssync.sh
добавляем в crontab пользователя root с требуемой вам периодичностью.
Для вторичных серверов поступаете аналогично.
TSIG - безопасная передача зон
Для увеличение безопасности работы я рекомендую использовать механизм
TSIG. Достаточно подробное описание настройки можно прочитать в статье
"Защита сервера DNS", так
что я не вижу смысла дублировать это в своей заметке.
Заключение
Описанная схема прекрасно подходит для сравнительно небольших
конфигураций. К её плюсам можно отнести простоту реализации (только
shell), высокую безопасность и лёгкую переносимость. Недостатки - каждый
раз передаётся полный список зон, в случае обновления требуется
перезапуск named. В масштабах большого регистратора рекомендую подумать
о более эффективных методах репликации, но для большинства других задач
эти недостатки совершенно не существенны. Как всегда - буду рад
замечаниям и советам.
Alex Samorukov, samm@os2.kiev.ua
980 Прочтений • [Автоматическая синхронизация файлов конфигурации master и slave DNS серверов (dns sync domain bind freebsd)] [08.05.2012] [Комментариев: 0]