Debian.pro/

Про Debian


Debian (Ubuntu, mint и т.д.), bind9, bind, secondary NS. Используем грязные хаки для удобства работы со связкой из двух NS.

Я обожаю простые и интуитивно понятные решения, которые в любой момент можно исключить из конфигурации. В данной статье я опишу, каким образом можно сконфигурировать 2 DNS сервера и комфортно управлять ими. Решение не претендует на правильно, корректность, нативность и т.д. и т.п. Но решение не является костылём, его можно использовать, ничего не сломается, если не ломать специально. Оно НЕ автоматизированное.

Если вам необходимо работающее решение, которое будет само синхронизировать все DNS записи — вам нужен ispmanager+dnsmanager или ispmanager+ispmanager. Проконсультировать и найти по низкой цене я для вас смогу обе панели, но они не бесплатны в любом случае. Остальные решения — либо кривые и постоянно отваливаются сами по себе молча, либо стоят столько, что дешевле арендовать пару безлимитных DNS серверов (я встречал их за 300-1000 рублей за 1 IP. То есть 600-1000 за primary+secondary).

По условию мы имеем 2 VDS. Мощности не так важны, главное, чтобы завелся LAMP (мне для этого вполне хватает 96 mb RAM). VDSки должны иметь IP адреса из разных подсетей класса С, желательно должны быть разнесены географически.
Master NS — условно имеет hostname ns1.debian.pro
Secondary NS — условно имеет hostname ns2.debian.pro

Если у вас больше 2х VDS серверов — то на всех VDSках, кроме первой, необходимо предпринять те же действия, что и на ns2.

Первым делом внимательно читаем статью Debian, bind9, bind установка. Конфигурируем master-NS с комфортом. Web-интерфейс для bind, smbind.

Проделываем всё указанное в статье на обоих VDS. Ещё раз повторюсь — если вы никуда не торопитесь, то сделайте так, как это описано в статье для Master NS. На всякий случай, если торопитесь, для краткости (обращайте внимание на hostname, на котором выполняется команда):

root@ns1.debian.pro:~# aptitude update && aptitude install bind9 && aptitude install smbind
root@ns2.debian.pro:~# aptitude update && aptitude install bind9 && aptitude install smbind

Во время установки smbind вас спросят mysql пароль для пользователя root, пароль для нового mysql пользователя для smbind и подтверждение mysql пароля. Естественно вы помните о безопасности, бла-бла-бла. Я исхожу из того, что на VDS не будет других пользователей кроме вас. Если будут — достаточные меры безопасности как для mysql, так и для LAMP я уже описывал.

Не забываем добавить строчку include «/etc/smbind/smbind.conf»; в файл /etc/bind/named.conf (не забудьте, что wordpress заменяет кавычки на типографские. Замените их на нормальные в конфиге).

Проверяем работоспособность smbind на обоих VDS (нам нужно, чтобы вебморда smbind писала все изменения в файл /etc/smbind/smbind.conf).

Теперь на ns2 удалим доступ к вебморде smbind (собственно можете и оставить, но тогда конечный скрипт перепишите сами). Строго говоря на втором сервере нам и не нужен smbind, но таким образом мы получаем возможность «написать что-то очень быстро в зоны на 2м NS, если вдруг оно откажется синхронизироваться».
root@ns2.debian.pro:~# mv /etc/apache2/conf.d/smbind.conf /root/smbind.conf
Если, вдруг, пожелаете вернуть:
root@ns2.debian.pro:~# mv /root/smbind.conf /etc/apache2/conf.d/smbind.conf

Ну и не забываем сделать apache2ctl restart после переноса конфига.

Собственно говоря, всё почти готово. Вам осталось зайти на http://ns1.debian.pro/smbind (дефолтный логин — admin, пароль — admin), сменить пароль для доступа к панели и создать первые записи.

После создания записей для нужного домена на NS1 нажимаем кнопку «Commit changes» в веб-морде на самом NS1. Собственно вы увидите ошибку о том, что rndc exited with code 1. Я уже описывал эту ошибку в первой статье — у пользователя www-data нет доступа к /usr/sbin/rndc. Чинить не будем — небезопасно да и толку мало.

Ну а теперь начинается самое интересное. Выполняем последовательность команд:
root@ns1.debian.pro:~# scp /etc/smbind/zones/ root@89.208.136.205:/etc/smbind/zones/
root@ns1.debian.pro:~# scp -r /etc/smbind/zones/ root@89.208.136.205:/etc/smbind/
root@ns1.debian.pro:~# /etc/init.d/bind9 restart
root@ns2.debian.pro:~# /etc/init.d/bind9 restart

Можно использовать команду rndc reload вместо /etc/init.d/bind9 restart, но она может не всегда срабатывать в неопытных руках. Да и bind9 может перестать работать. В общем смотрите внимательно /var/log/syslog на обоих VDS, если у вас есть какие-либо сообщения об ошибка при перезагрузке bind9

Ну и, так как мы ленивые, оформим синхронизацию в скриптик:
root@ns1.debian.pro:~# nano /usr/bin/syncbind
Запишем в файл следующее:
#!/bin/bash
scp /etc/smbind/smbind.conf root@ns2.debian.pro:/etc/smbind/smbind.conf
scp -r /etc/smbind/zones/ root@ns2.debian.pro:/etc/smbind/
/etc/init.d/bind9 restart
ssh root@ns2.debian.pro /etc/init.d/bind9 restart

Выдадим права файлу на выполнение:
root@ns1.debian.pro:~# chmod +x /usr/bin/syncbind

Последовательность ваших действий теперь такая:
1) вносим необходимые записи по адресу http://ns1.debian.pro/smbind (или другой адрес, на который вы повесили smbind)
2) нажимаем в веб-морде кнопку «commit changes»
3) выполняем команду:
root@ns1.debian.pro:~# syncbind
Чтобы у вас каждый раз не спрашивало пароль — организуйте возможность пользователю root@ns1.debian.pro авторизовываться по ssh-ключу на root@ns2.debian.pro

Собственно, те кто поопытнее — разберутся в том, как организовать всё тоже самое без участия smbind на slave. Ещё более умные разберутся, что на самом деле есть файл /usr/share/smbind/php/src/commit.php, который можно попробовать переписать для того, чтобы файл сам делал scp и ребутил bind9 на всех VDS. Тогда по нажатию «Commit changes» у вас всё будет синхронизироваться само. Если я найду время — то я предоставлю вам измененный файл. Вообще там вдумчиво посидеть нужно. Если кто-то его перепишет — большааая просьба скинуть новый скрипт.
Ну и не забываем про условия:
1) пользователь bind должен иметь доступ на чтение к файлам /etc/smbind/ на всех VDS
2) если вы желаете, чтобы работала кнопка commit changes — то пользователь www-data должен иметь доступ к файлу /usr/sbin/rndc на выполнение
3) корневая запись зоны (в большинстве случаев — домен второго уровня, например, example.ru) не должна ссылаться на другой домен посредством CNAME (то есть, при создании New zone в графе zone вы вписываете домен. Он должен быть представлен именно записью типа А всегда. При создании домена сделать иного вы не сможете, а вот потом некоторые делают. А я за эту получаю свои 20-30 рублей на телефон, хех).
4) все NS серверы, которые вы указываете в конфиге bind’a, файлах зон через smbind и так далее — должны являться записью типа А. Если для одного из ваших доменов указан домен, запись о котором фактически является CNAME записью — вы не сможете перезагрузить bind.

Удачного использования.
P.S. — я понимаю, что это несколько странно всё. Но более адекватного бесплатного решения я пока не видел.


Комментарии (18):

  1. anon :

    Изменилось ли что-то в данной ситуации за последние 4 года?

  2. Влад :

    rsync -avzP root@master.qs.biz:/etc/bind/ /etc/bind/ —exclude=*rndc.key; rndc reload

    Можно так делать.
    Если зоны не только в /etc/bind, то, соответственно, rsync на 2 каталога.

    Всё это запихивается в крон.

  3. Ну, само собой, имя сервера своё.

  4. anon :

    Имел ввиду немного другое. Не научился ли bind сам синхронизироваться с мастером? Появились notify сообщения же вроде, или это не про то?

  5. notify сообщения для зон у него всегда были, но они не работают для тех случаев, когда у вас туда постоянно добавляются новые конфиги/домены — каждую зону приходится отдельно идти и добавлять slav-ом.
    Протокола взаимодействия из коробки для таких случаев у биндов нет. Можно через mysql-базу добиться этого или любым другим вариантом с репликацией.

  6. anon :

    А если только записи добавляются? Имею сейчас конфигурацию Master-Slave. С master-а notify уходит, на slave приходит, даже зона обновляется в файле слейва. Но при этом пока руками ему не перезапустишь, клиентам он отдаёт старые данные :(

  7. конфиг для зоны покажите

  8. Можно в почту — root@vlad.pro

  9. anon :

    named.conf:

    options {
    listen-on port 53 { 10.46.64.145; };
    directory «/var/named»;

    dump-file «/var/named/data/cache_dump.db»;
    statistics-file «/var/named/data/named_stats.txt»;
    memstatistics-file «/var/named/data/named_mem_stats.txt»;

    dnssec-enable yes;
    dnssec-validation yes;
    dnssec-lookaside auto;

    bindkeys-file «/etc/named.iscdlv.key»;
    managed-keys-directory «/var/named/dynamic»;

    };

    logging {
    channel default_debug {
    file «data/named.run»;
    severity dynamic;
    };
    channel debug {
    file «/var/log/named.debug»;
    severity debug;
    print-time yes;
    };
    category notify { debug; };
    category queries { debug; };
    category xfer-in { debug; };
    category xfer-out { debug; };
    };

    acl «admin_gp1_network» {
    10.40.0.0/24;
    };
    acl «gp1_dc» {
    10.46.66.4;
    10.46.66.5;
    };
    acl «gp2_dc» {
    10.46.74.4;
    10.46.74.5;
    };
    acl «slave» {
    10.46.72.145;
    };
    include «/etc/named.root.key»;
    view «slave» {
    match-clients { «slave»; };

    allow-query { «slave»; };
    allow-transfer { «slave»; };
    include «/etc/named.rfc1912.zones»;
    include «/var/named/named.master.zones»;
    };
    view «domain_controllers» {
    match-clients { «gp1_dc»; «gp2_dc»; };

    forward only;
    forwarders { 127.0.0.1; };

    recursion yes;

    allow-query-cache { «gp1_dc»; «gp2_dc»; };
    allow-query { «gp1_dc»;»gp2_dc»;};

    dnssec-enable no;
    dnssec-validation no;
    dnssec-lookaside no;
    include «/etc/named.rfc1912.zones»;
    include «/var/named/named.master.zones»;

    };
    view «admin» {
    match-clients { «admin_gp1_network»; };

    forward only;
    forwarders { 10.45.120.93; };

    recursion yes;

    allow-query-cache { «admin_gp1_network»; };
    allow-query { «admin_gp1_network»; };

    dnssec-enable no;
    dnssec-validation no;
    dnssec-lookaside no;

    include «/etc/named.rfc1912.zones»;
    include «/var/named/named.master.zones»;
    };
    view «others» {
    match-clients { any; };

    include «/etc/named.rfc1912.zones»;
    include «/var/named/named.master.zones»;

    allow-query { «slave»; };
    };

  10. А чего то я вообще не вижу у вас описания слейв-зон

  11. anon :

    named.master.zones:
    zone «sw» {
    type master;
    file «zones/sw-zone»;
    };

  12. anon :

    а, билн, это с master.

    p.s. можно на ты

  13. anon :

    slave sw zone:
    zone «sw» {
    type slave;
    file «slaves/sw-zone»;
    masters { 10.46.64.145; };
    };

  14. Мхм.

    forward only;
    forwarders { 127.0.0.1; };

    а это зачем) ?

  15. anon :

    =) Сервер должен отвечать на запросы по зонам, для которых он является мастером. Так же он должен резолвить внешние зоны, но не все, а только некоторые из них (порядка 10-15). Как сделать это средствами бинда так и не нашел, поэтому заруливаю все запросы на локальный dnsmasq, и им уже фильтрую, будет ли пропущен запрос на внешний dns сервер
    как-то так )

  16. Почитайте про зоны с type forward.
    И вряд ли у вас dnsmasq и bind корректно сейчас работают вместе. Либо вы сейчас и slave зоны форвардите в dnsmasq (который не знает про изменения), либо у вас работает что-то одно, если вы не настроили для них listen (оба по дефолту висят на 53м порту).

  17. anon :

    Сейчас нагуглил-таки, почеу уменя не работало с type forward. Какие-то затыки с DNSSEC. Если их вырубить:
    dnssec-enable no;
    dnssec-validation no;
    dnssec-lookaside no;
    то оно работает.
    Спасибо за наводу, буду дальше ковырять.

  18. Та не за чт.

Написать комментарий