Однажды возникла необходимость доступа из интернета через свой маршрутизатор к домашней сети. Пришлось вспомнить про динамический DNS, о котором я много слышал, но ни разу не применял на практике.
Мои домены делегированы на Яндекс, поэтому всё предельно упрощается – нужно просто воспользоваться API Яндекса для обновления DNS-записи, привязанной к маршрутизатору.
В интернете на эту тему написано довольно много статей с готовыми скриптами и даже полностью оформленная программа с GUI. Жаль, что с момента её выпуска API Яндекса изменился и она на поверку оказалась неработоспособной, а автор не имеет времени для её обновления.
Поэтому было решено адаптировать к новым реалиям какой-нибудь из уже написанных скриптов. Мой выбор пал на скрипт Евгения Табацкого, который за пару лет также устарел и требовал корректировки.
Итак, допустим, что мы решили назначить нашему маршрутизатору доменное имя ddns.domain.ru. Для успешного удалённого обновления зоны домена, делегированного на Яндекс, необходимо следующее:
- Административный токен для основного домена
Сейчас его можно взять по адресу: https://pddimp.yandex.ru/api2/admin/get_token - record_id записи поддомена, для которого необходимо обновлять IP
Выполнив в браузере запрос для основного домена domain.ru:https://pddimp.yandex.ru/api2/admin/dns/list?token=JVP....&domain=domain.ru
получим текстовый файл json.txt со всеми доменными записями однотипного вида
…
{“content”:…“record_id”: 3570657, “subdomain”: “ddns”, “type”: “A”},
…
среди которых найдётся также и record_id = 3570657 для нашего поддомена ddns. - Внешний скрипт, обращение к которому возвращало бы текущий внешний IP-адрес
Можно воспользоваться либо неким внешним ресурсом, например https://myexternalip.com/raw, либо оформить простой запрос:<?php echo $_SERVER['REMOTE_ADDR']; ?>
в виде файла myip.php и положить на какой-нибудь внешний подконтрольный вам сервер.
Скрипт ddns.pl запрашивает внешний IP и сравнивает с ранее сохранённым в файле my_ip.txt, который должен лежать в том же каталоге. Если IP изменился, он редактирует запись для ddns.domain.ru и меняет его IP. Я также добавил возможность задания времени кеширования TTL, которое по умолчанию слишком велико (21600). Для удобства, в конце статьи размещена ссылка для скачивания.
#!/usr/bin/perl use LWP::UserAgent; my $current_ip = `curl https://myexternalip.com/raw`; if ($current_ip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) { my $new_ip = "$1.$2.$3.$4"; open (FILE,"my_ip.txt"); my @lines = <FILE>; $old_ip = $lines[0]; $old_ip =~ s/^\s+|\s+$//g; close(FILE); if ($old_ip eq $new_ip) { die "IP not changed"; # Выходим из скрипта, если IP не изменился } open (FILE,">my_ip.txt"); print FILE $new_ip; # Записываем в файл новый IP close(FILE); my $token = "JVP..."; #Токен для администратора DNS Яндекса my $domain = "domain.ru"; #Основной домен my $subdomain = "ddns"; #Поддомен my $id = "3570657"; #Идентификатор поддомена my $TTL = "900"; #Время кеширования записи my $uri ="https://pddimp.yandex.ru/api2/admin/dns/edit"; # URI запроса my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 } ); $response = $ua->post( $uri, [ 'domain' => $domain, 'subdomain' => $subdomain, 'record_id' => $id, 'content' => $new_ip, 'TTL' => $TTL, ], 'PddToken' => $token, ); if ( $response->is_success ) { print $response->decoded_content; } else { die $response->status_line; } }
После копирования на сервер, например в папку /root, его необходимо сделать исполнимым:
#chmod u+x ddns.pl
и создать файл my_ip.txt
#touch my_ip.txt
Скрипт можно запускать по Cron-у с необходимым интервалом, например 10 минут:
#crontab –e
10 * * * * root /root/ddns.pl
-- сохраняем файл --
Если с запуском возникли проблемы, почитайте статью о загрузке модулей Perl в Linux.