Недавно встала задача развернуть виртуальный сервер Ubuntu 12.04 на Amazon EC2 для некоего сервиса и присвоить ему доменное имя в существующей доменной зоне, но как известно Amazon меняет публичный и локальный адреса после перезагрузки или выключения машины, поэтому было решено использовать bash (для *nix) и bat (для Windows) для автоматизации обновления динамического адреса для хостинга.
Такой скрипт на bash уже существует Marius Ducea Jun 1st, 2009 года. Он был немного неактуальным в плане которых команд API от Amazon, но в большинстве своём остался практически неизменным.
Всё же повторюсь как настроить работающий BIND для получения команды на синхронизацию, хотя на хабре уже есть несколько статей описывающих данный метод:
habrahabr.ru/post/101380
habrahabr.ru/post/45921
и много других.
Я лишь исправил некоторые команды, засунул его в автозагрузку с системой и сделал аналогичный bat-скрипт для Windows, использовав cURL и некоторые файлы от BIND.
Долго мучился почему не получается обновить зону (master и slave были на другом хостинге, работающим на Ubuntu 10.04 с установленным BIND), пришлось включить на нём логирование:
В файле /etc/bind/named.conf прописал правила для создания логов, которые будут записаны в папку в /var/log/named/
После
логи появились и можно было попробовать обновить зону скриптом, который был немного модифицирован, но вначале надо было создать ключи, я использовал 512 бит:
Получили 2 файла:
В скрипте необходимо указать путь к полученному private — ключу:
, а в DNS сервере указать содержимое публичного ключа в файле подгружаемых зон (у меня это named.conf.local):
Содержимое публичного ключа:
Перезагружаем на хостинге с master/slave–записьсью DNS сервер и смотрим логи при попытке обновить зону полученным скриптом на хостинге Amazon.
Был получен отлуп:
named.log
update-debug.log
в логах было написано что нет разрешения за запись, хотя на файлах и папках стояло разрешение записи для пользователя и группы bind.
Поиски в интернете гласили что надо поправить строчку в /etc/apparmor.d/usr.sbin.named
c
на
, но это означает уменьшить безопасть зон, расположенных в этой директории, но я как обычно полагаюсь на авось.
Далее надо перезагрузить разрешения и сам BIND
После очередного рестарта сервиса на DNS хостинге ошибка исчезла и зона благополучно обновилась, но все закомментированные в ней данные были утеряны, т.к. bind «навёл порядок» в записях и поудалял лишнее, поэтому следует сделать копию всех зон.
Так же следовало данный скрипт сделать автозапускаемым, т.к. после включения виртуалки неудобно заходить через ssh на ужасное имя ec2-55-240-2-74.compute-1.amazonaws.com (постоянно меняется) и руками его запускать что бы обновить зону.
Для этого я сделал его исполняемым и скопировал в /etc/init.d/
Для Windows оказалось всё намного проще:
И поместить его в шедулер с запуском при старте системы.
Последнюю версию cURL брал здесь: www.paehl.com/open_source
BIND: www.isc.org/software/bind
От BIND нужны только файлы:
Их можно положить рядом со скриптом или же закинуть в %WINDIR%\system32
Вывод из всего этого:
Хоть я и выполнил данное задание, безопасть DNS сервера стала ещё меньше, т.к. добавилась ещё одна уязвимость и риск потерять правильно настроенную зону.
Прежде чем повторять написанное здесь, следует чётко понимать что же надо получить, сделать копию всех критически важных и изменяемых объектов, надо быть уверенным что в случае какого-либо сбоя можно получить доступ к машине и исправить ситуацию.
За последствия я не отвечаю, т.к. сам не уверен в её правильности.
P.S.
Прошу прощения за такой сумбурный текст, и возможные ошибки.
Такой скрипт на bash уже существует Marius Ducea Jun 1st, 2009 года. Он был немного неактуальным в плане которых команд API от Amazon, но в большинстве своём остался практически неизменным.
Всё же повторюсь как настроить работающий BIND для получения команды на синхронизацию, хотя на хабре уже есть несколько статей описывающих данный метод:
habrahabr.ru/post/101380
habrahabr.ru/post/45921
и много других.
Я лишь исправил некоторые команды, засунул его в автозагрузку с системой и сделал аналогичный bat-скрипт для Windows, использовав cURL и некоторые файлы от BIND.
Долго мучился почему не получается обновить зону (master и slave были на другом хостинге, работающим на Ubuntu 10.04 с установленным BIND), пришлось включить на нём логирование:
В файле /etc/bind/named.conf прописал правила для создания логов, которые будут записаны в папку в /var/log/named/
logging {
channel bind_log {
file "/var/log/named/named.log";
print-time yes;
print-category yes;
print-severity yes;
};
channel update_debug {
file "/var/log/named/update-debug.log";
severity debug 3;
print-time yes;
print-category yes;
print-severity yes;
};
channel security_info {
file "/var/log/named/security-info.log";
severity info;
print-time yes;
print-category yes;
print-severity yes;
};
category default { bind_log;};
category xfer-in { bind_log;};
category xfer-out { bind_log;};
category update { update_debug;};
category security { security_info;};
};
После
/etc/init.d/bind9 restart
логи появились и можно было попробовать обновить зону скриптом, который был немного модифицирован, но вначале надо было создать ключи, я использовал 512 бит:
dnssec-keygen -a HMAC-MD5 -b 512 -r /dev/urandom -n USER example.com
Получили 2 файла:
Kexample.com.+157+10000.key
Kexample.com.+157+10000.private
В скрипте необходимо указать путь к полученному private — ключу:
#!/bin/bash
#Путь к приватному ключевому файлу
DNS_KEY="/etc/bind/key/Kexample.com.+157+10000.private"
#Имя домена
DOMAIN=example.com
#Имя поддомена статически
HOSTNAME=site1
#Раскомментировать нижние 2 строки, если надо использовать динамическое имя (возможны ошибки при внесении записи в DNS)
#USER_DATA=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/local-hostname`
#HOSTNAME=`echo $USER_DATA`
#Установить имя до следующей перезагрузки
hostname $HOSTNAME.$DOMAIN
echo Поддомен и домен: $HOSTNAME.$DOMAIN
PUBIP=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/public-ipv4`
echo Публичный адрес: $PUBIP
cat<<EOF | /usr/bin/nsupdate -k $DNS_KEY -v
server ns1.$DOMAIN
zone $DOMAIN
update delete $HOSTNAME.$DOMAIN A
update add $HOSTNAME.$DOMAIN 60 A $PUBIP
send
EOF
LOCIP=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/local-ipv4`
echo Локальный адрес: $LOCIP
cat<<EOF | /usr/bin/nsupdate -k $DNS_KEY -v
server ns1.$DOMAIN
zone $DOMAIN
update delete local.$HOSTNAME.$DOMAIN A
update add local.$HOSTNAME.$DOMAIN 60 A $LOCIP
send
EOF
, а в DNS сервере указать содержимое публичного ключа в файле подгружаемых зон (у меня это named.conf.local):
key example.com. {
algorithm HMAC-MD5;
secret "ynl7o+JFPekH4iUaptw7z12xLhkUBJTmqbmTYa1xe+Gpt26HVaff+qQW hlmWcvAUeYdg19B+M4YeFrfhAvlcLQ==";
};
zone "example.com" {
type master;
file "/etc/bind/master/example.com";
allow-update { key example.com.; };
allow-query { any; };
};
Содержимое публичного ключа:
example.com. IN KEY 0 3 157 ynl7o+JFPekH4iUaptw7z12xLhkUBJTmqbmTYa1xe+Gpt26HVaff+qQW hlmWcvAUeYdg19B+M4YeFrfhAvlcLQ==
Перезагружаем на хостинге с master/slave–записьсью DNS сервер и смотрим логи при попытке обновить зону полученным скриптом на хостинге Amazon.
Был получен отлуп:
named.log
26-Jan-2013 22:53:27.780 update-security: info: client 192.168.254.1#58180: signer "example.com" approved
26-Jan-2013 22:53:27.782 general: error: /etc/bind/master/example.com.jnl: create: permission denied
26-Jan-2013 22:53:27.881 update-security: info: client 192.168.254.1#52062: signer "example.com" approved
26-Jan-2013 22:53:27.883 general: error: /etc/bind/master/example.com.jnl: create: permission denied
update-debug.log
26-Jan-2013 22:53:27.780 update: info: client 192.168.254.1#58180: updating zone 'example.com/IN': deleting rrset at 'flussonic.example.com' A
26-Jan-2013 22:53:27.781 update: info: client 192.168.254.1#58180: updating zone 'example.com/IN': adding an RR at 'flussonic.example.com' A
26-Jan-2013 22:53:27.781 update: debug 3: client 192.168.254.1#58180: updating zone 'example.com/IN': checking for NSEC3PARAM changes
26-Jan-2013 22:53:27.782 update: info: client 192.168.254.1#58180: updating zone 'example.com/IN': error: journal open failed: unexpected error
26-Jan-2013 22:53:27.882 update: info: client 192.168.254.1#52062: updating zone 'example.com/IN': deleting rrset at 'local.flussonic.example.com' A
26-Jan-2013 22:53:27.882 update: info: client 192.168.254.1#52062: updating zone 'example.com/IN': adding an RR at 'local.flussonic.example.com' A
26-Jan-2013 22:53:27.882 update: debug 3: client 192.168.254.1#52062: updating zone 'example.com/IN': checking for NSEC3PARAM changes
26-Jan-2013 22:53:27.883 update: info: client 192.168.254.1#52062: updating zone 'example.com/IN': error: journal open failed: unexpected error
в логах было написано что нет разрешения за запись, хотя на файлах и папках стояло разрешение записи для пользователя и группы bind.
Поиски в интернете гласили что надо поправить строчку в /etc/apparmor.d/usr.sbin.named
c
/etc/bind/** r,
на
/etc/bind/** rw,
, но это означает уменьшить безопасть зон, расположенных в этой директории, но я как обычно полагаюсь на авось.
Далее надо перезагрузить разрешения и сам BIND
/etc/init.d/apparmor restart
/etc/init.d/bind9 restart
После очередного рестарта сервиса на DNS хостинге ошибка исчезла и зона благополучно обновилась, но все закомментированные в ней данные были утеряны, т.к. bind «навёл порядок» в записях и поудалял лишнее, поэтому следует сделать копию всех зон.
Так же следовало данный скрипт сделать автозапускаемым, т.к. после включения виртуалки неудобно заходить через ssh на ужасное имя ec2-55-240-2-74.compute-1.amazonaws.com (постоянно меняется) и руками его запускать что бы обновить зону.
Для этого я сделал его исполняемым и скопировал в /etc/init.d/
chmod +x ec2-hostname.sh
cp ec2-hostname.sh /etc/init.d/
update-rc.d ec2-hostname.sh defaults
Для Windows оказалось всё намного проще:
@echo off
Setlocal enabledelayedexpansion
rem Путь к приватному ключевому файлу
set DNS_KEY="Kexample.com.+157+10000.private"
rem Имя домена
set DOMAIN=example.com
rem Имя поддомена
set HOSTNAME=site1
echo Поддомен и домен: %HOSTNAME%.%DOMAIN%
for /F "Delims=" %%P In ('curl -s http://169.254.169.254/latest/meta-data/public-ipv4') Do Set PUBIP=%%~P
echo Публичный адрес: %PUBIP%
(
@echo server ns1.%DOMAIN%
@echo zone %DOMAIN%
@echo update delete %HOSTNAME%.%DOMAIN% A
@echo update add %HOSTNAME%.%DOMAIN% 60 A %PUBIP%
@echo send
) | nsupdate -k %DNS_KEY% -v
for /F "Delims=" %%L In ('curl -s http://169.254.169.254/latest/meta-data/local-ipv4') Do Set LOCIP=%%~L
echo Локальный адрес: %LOCIP%
(
@echo server ns1.%DOMAIN%
@echo zone %DOMAIN%
@echo update delete local.%HOSTNAME%.%DOMAIN% A
@echo update add local.%HOSTNAME%.%DOMAIN% 60 A %LOCIP%
@echo send
) | nsupdate -k %DNS_KEY% -v
:eof
И поместить его в шедулер с запуском при старте системы.
Последнюю версию cURL брал здесь: www.paehl.com/open_source
BIND: www.isc.org/software/bind
От BIND нужны только файлы:
libisc.dll
liblwres.dll
libisccfg.dll
libbind9.dll
libeay32.dll
libdns.dll
libxml2.dll
nsupdate.exe
Их можно положить рядом со скриптом или же закинуть в %WINDIR%\system32
Вывод из всего этого:
Хоть я и выполнил данное задание, безопасть DNS сервера стала ещё меньше, т.к. добавилась ещё одна уязвимость и риск потерять правильно настроенную зону.
Прежде чем повторять написанное здесь, следует чётко понимать что же надо получить, сделать копию всех критически важных и изменяемых объектов, надо быть уверенным что в случае какого-либо сбоя можно получить доступ к машине и исправить ситуацию.
За последствия я не отвечаю, т.к. сам не уверен в её правильности.
P.S.
Прошу прощения за такой сумбурный текст, и возможные ошибки.
Использованный материал:
www.ducea.com/2009/06/01/howto-update-dns-hostnames-automatically-for-your-amazon-ec2-instances
www.k-max.name/linux/howto-dns-server-bind
www.k-max.name/linux/osnovnye-komandy-linux-ili-shpargalka-nachinayushhego-linuksojda/#dns
www.networkcenter.info
cruw.blogspot.ru/2012/03/dig-dns.html
forum.ubuntu.ru/index.php?topic=29295.0
forum.ubuntu.ru/index.php?topic=28580.0
help.ubuntu.ru/wiki/%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA%D0%B0
www.paehl.com/open_source
www.isc.org/software/bind
wiki.inisec.com/index.php/Nsupdate_for_windows
google.com
и многое другое
www.k-max.name/linux/howto-dns-server-bind
www.k-max.name/linux/osnovnye-komandy-linux-ili-shpargalka-nachinayushhego-linuksojda/#dns
www.networkcenter.info
cruw.blogspot.ru/2012/03/dig-dns.html
forum.ubuntu.ru/index.php?topic=29295.0
forum.ubuntu.ru/index.php?topic=28580.0
help.ubuntu.ru/wiki/%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B0_%D0%B0%D0%B2%D1%82%D0%BE%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA%D0%B0
www.paehl.com/open_source
www.isc.org/software/bind
wiki.inisec.com/index.php/Nsupdate_for_windows
google.com
и многое другое