пятница, 16 апреля 2010 г.

Свой DynDns сервер или мое первое знакомство с BIND

Задача настроить динамически обновляемый dns сервер для регистрации внешних ip адресов филиалов.
Что нам надо для успешной работы связки клиент - динамически-обновляемый dns сервер
1.FreeBsd с установленным и настроенным BIND. Поднятый apache c поддержкой php
2. Клиент с поддержкой обновлений по стандарту RFC 2136 или nsupdate утилита от BIND

Настройка BIND9.x на FREEBSD 8.0 для динамического обновления.
Включаем службу в файле /etc/rc.conf

named_enable="YES"

Вносим изменения в файл настроек BIND:
1. Прописываем адреса, которые будет слушать bind

listen-on { 192.168.101.101; };

2. Прописываем в файле resolve.conf сервера имен. А в host задаем соответствия ip адресов нашим серверам имен.
3. Прописываем настройки логирования. При этом необходимо помнить что в FreeBSD 8.0 BIND автоматически создает себе песочницу в /var/named/ и соответственно логи буду писаться в /var/named/etc/log/

logging {
channel "log_default" {
file "/var/log/named.log" versions 10 size 10m;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};

channel "log_security" {
file "/var/log/named-security.log" versions 5 size 10m;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};

category "default" { "log_default"; };
category "security" { "log_security"; };
};

Более подробно о настройках логирования BIND можно посмотреть тут
4. Выдача прав на доступ к рабочим папкам. Здесь есть один маленький нюанс при запуске BIND проверяет права на папки и изменяет их в соответствии с прописанными в настройках. Поэтому настройки BIND в файле /etc/mtree/BIND.Chroot.dist должны соответствовать пользователю под которым запущен BIND.
У меня named запущен из под пользователя bind

5783 ?? Is 0:00.10 /usr/sbin/named -t /var/named -u bind

соответственно файл должен выглядит так:

/set type=dir uname=bind gname=wheel mode=0755
.
dev mode=0555
..
etc
namedb
dynamic uname=bind
..
master uname=bind
..
slave uname=bind
..
..
..
/set type=dir uname=bind gname=wheel mode=0755
var uname=root
dump
..
log
..
run
named
..
..
stats
..
..

помните, если у вас неправильно розданы права на директории BIND, он не сможет получить доступ к папкам, создавать журналы и соответственно обновлять зоны

5. Теперь описываем зону которая будет у нас динамически обновятся и создаем ключи для клиентов.
Генерируем ключи для клиентов следующим образом:
dnssec-keygen -a HMAC-MD5 -b 128 -n USER Donetsk2
если у вас в хеше ключа появится / измените имя пользователя, при указании ключа с / BIND воспринимает его как синтаксическую ошибку.
Вносим изменения в файл named.conf

//прописываем ключ
key Donetsk2 { algorithm HMAC-MD5; secret gTgQ8OeOf0D4BLxuh2PkIw==; };
//описываем зону
zone "pupkin.firma.local" {
type master;
allow-update { key "Dn1";
key "Donetsk2"; };
file "master/filial_pupkin_local.db"; };

Создаем файл для нашей зоны. Я не уверена в том что он на 100% оформлен правильно. Bind при проверке не нашел в нем ошибок, и с ним у меня все работает

$TTL 3600

@ IN SOA dyndns.pupkin.firma.local. postmaster.pupkin.firma.
(
2010042601 ; serial number YYMMDDNN
28800 ; Refresh
7200 ; Retry
864000 ; Expire
3600 ; Min TTL
)
NS dyndns.pupkin.firma.local.
$ORIGIN pupkin.firma.local.
myip A 192.168.1.1



Создаем php файл при помощи которого будем получать внешний адрес клиента. Потом мы будем его использовать для для изменения файла конфигурации nsupdate. Более подробно про установку apache читаем тут


$ip=$_SERVER['REMOTE_ADDR'];
$ip2=$_SERVER['LOCAL_ADDR'];
$userIP=$ip;
$userIP2=$ip2;
if ($userIP=="") echo $userIP2; else echo $userIP;


Теперь осталось сконфигурированный и автоматизировать клиента. В моем случае клиентом выступает WinXp за NAT
1. Качаем BIND for Windows
2. Качаем Microsoft Visual C++ 2005 Redistributable Package
3. Еще нам понадобится wget.
Необходимо установить С++ пакет в систему и извлечь следующие файлы из пакета BIND:

libisc.dll
liblwres.dll
libisccfg.dll
libbind9.dll
libeay32.dll
libdns.dll

и nsupdate. Рекомендовано распаковать из в %Systemroot%\System32\, я положила их рядом в папку с nsupdate и скриптом для обновления записи.
Создаем два файла которые нам понадобятся в процессе обновления dns записи.
first.txt и second.txt

First.txt В конце последней строки пробел. Ни в коем случае не добавляем перенос на новую строку.

server 192.168.101.101
zone filial.pupkin.local
update delete donetsk2.filial.pupkin.local
update add donetsk2.filial.pupkin.local 600 A


Second.txt

show
send


Создаем cmd файл, который в последствии добавим в задание для регулярного обновления зоны.

wget.exe http://192.168.101.101/index2.php
copy first.txt+index2.php+second.txt cmd.txt
del /q/s index2.php
nsupdate.exe -k Kdonetsk2.+157+07312.private -v cmd.txt
del /q/s cmd.txt


Пара ключей указанная в командном файле должна лежать рядом с ним.

Вот и все, dns запись у нас обновляется. И мы в любой момент можем узнать новый динамический адрес нашего филиала.

Отдельное спасибо Puzzlew & Purgen за помощь

Комментариев нет: