Перевод: Сгибнев Михаил
Резюме
В этой статье рассказывается, как автоматизировать порядок обновлений динамического DNS сервера через SSH.
Введение
Моя домашняя сеть подключена к Internet через модем и провайдер назначает мне внешний IP через DHCP.
Довольно часто мне необходимо получать доступ к моей внутренней сети, находясь в этот момент на работе, но желание
разбивается о суровую правду жизни в виде непонятно-как-назначенного-провайдером адреса шлюза моей сети. Собственно, именно для
этого нам и понадобится DNS: необходимо привязать имя хоста к постоянно изменяющемуся адресу и выполнить необходимые обновления.
Решение
Проблема поддержания в актуальном виде записей DNS при динамическом IP имеет много решений, коммерческих и бесплатных.
В моем случае я управляю DNS сервером в своей организации и поэтому самым простым способом лично для меня будет обновление
таблиц DNS через защищенный канал, используя
openssh, всякий раз, как меняется адрес шлюза моей домашней сети.
Так как нам необходимо полностью автоматизировать процесс, то мы будем использовать
беспарольную аутентификацию
с помощью ключей (нам придется не указывать кодовую фразу, доверившись что наш приватный ключ не попадет в чужие руки).
Чтобы снизить риск компрометации системы предпримем следующие шаги:
- Ограничим область действия ключа, определив имя выполняемой программы в authorized_keys
- Открывать ssh-сессию будем от имени непривилегированного пользователя
В случае определения выполняемой команды в authorized_keys от клиента требуется лишь подтвердить свою подлинность.
Никаких других действий ему производить не требуется, да и незачем.
Установка учетной записи пользователя
По традиции, таблицами DNS управляет пользователь root, но процесс запущен от имени другого пользователя (обычно, named).
Создадим учетную запись 'dnsadmin' и делегируем ей функции модификации таблиц. Вот так это выглядит на RedHat-based системе:
- Создаем учетную запись:
$ adduser dnsadmin -s /bin/sh -d /etc/tinydns/root
- Предоставляем права на файлы DNS пользователю dnsadmin:
$ chown -R dnsadmin:dnsadmin /etc/tinydns/root
- Создаем каталог .ssh в ~dnsadmin:
$ su dnsdmin -c 'mkdir /etc/tinydns/root/.ssh'
-
Копируем публичный ключ в /etc/tinydns/yo/.ssh/authorized_keys. Выполним следующие шаги:
-
Редактируем публичный ключ, внося ограничения:
command="/usr/bin/perl /etc/tinydns/dynupdate",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
Этим мы значительно увеличим безопасность системы, так как при компрометации приватного ключа, злоумышленник сможет выполнить только одну единственную
безобидную программу.
-
Копируем приватный ключ dns.key на шлюз домашней сети и размещаем в соответствующий каталог. В моем случае это /yo/.ssh/dns.key
-
Копируем отредактированный публичный ключ dns.key.pub на DNS сервер и добавляем его в /etc/tinydns/yo/.ssh/authorized_keys.
-
Файл "/etc/tinydns/dynupdate" является скриптом, написанным на языке Perl.
Я использую djbns, так как он особенно удобен для использования в скрипте из-за
линейно-ориентированного файла конфигурации. Скрипт извлекает IP адрес клиента из переменной среды SSH_CONNECTION
и пишет соответствующую строку конфигурации для tinydns (в данном случае, запись типа A), производит изменения в каталоге
конфигурации tinydns и запускает make, который обьединяет динамические и статические данные в файл, имеющий формат cdb.
Данный сценарий не имеет средств обработки ошибок, при желании, модифицируйте его.
#!/usr/bin/perl
use strict;
my $d='/etc/tinydns/root';
my $host = 'ext.praxis-sw.com';
my $ttl = 1800;
my $e;
unless ($e = $ENV{SSH_CONNECTION}){
die "cannot get connection environment variable\n";
}
if (my ($client_ip) = $e =~ /^(\S+)/){
my $f=qq[$d/dynamic.data];
my $t=$f . 'tmp';
open(F, ">$t") or die "cannot open file $t. $!\n";
print F qq[=$host:${client_ip}:$ttl\n];
close F or die "cannot close file $t. $!\n";
rename $t, $f or die "cannot rename file $t to $f. $!\n";
chdir($d) or die "cannot chdir to $d. $!\n";
exec '/usr/bin/make -s';
}
else {
warn "cannot get client ip\n";
exit 1;
}
Вот текст файла Makefile:
data.cdb: static.data dynamic.data
test -e data && chmod 0600 data
( echo "#Do not edit. Generated data!"; cat static.data dynamic.data ) > data
chmod 0400 data
/usr/local/bin/tinydns-data
-
Теперь, когда создается ssh соединение с шлюза домашней сети на DNS сервер, происходит обновление записи для хоста
ext.praxis-sw.com.
-
Финал. Строка для запуска ssh сессии
ssh -i /yo/.ssh/dns.key -n joad.praxis-sw.com
из скрипта dhcp. Я использую dhcpcd, сценарий запуска его находится в /etc/dhcpcd/ .
-
Заключение
Был бы рад, если этот совет Вам пригодился. Предложения и замечания принимаются.
По материалам Praxis Software
Примечание переводчика. Логин пользователя в тексте не yo, а root, было заменено специально, так как под root работать нехорошо.
Хотя, когда я был молод, работал с Linux и не знал что такое "sudo", я тоже работал под root.