Home » Linux » Centos » Скрипт динамического обновления зон DNS для работы через Яндекс API

Скрипт динамического обновления зон DNS для работы через Яндекс API

Однажды возникла необходимость доступа из интернета через свой маршрутизатор к домашней сети. Пришлось вспомнить про динамический DNS, о котором я много слышал, но ни разу не применял на практике.

Мои домены делегированы на Яндекс, поэтому всё предельно упрощается – нужно просто воспользоваться API Яндекса для обновления DNS-записи, привязанной к маршрутизатору.

В интернете на эту тему написано довольно много статей с готовыми скриптами и даже полностью оформленная программа с GUI. Жаль, что с момента её выпуска API Яндекса изменился и она на поверку оказалась неработоспособной, а автор не имеет времени для её обновления.

Поэтому было решено адаптировать к новым реалиям какой-нибудь из уже написанных скриптов. Мой выбор пал на скрипт Евгения Табацкого, который за пару лет также устарел и требовал корректировки.

Итак, допустим, что мы решили назначить нашему маршрутизатору доменное имя ddns.domain.ru. Для успешного удалённого обновления зоны домена, делегированного на Яндекс, необходимо следующее:

  1. Административный токен для основного домена
    Сейчас его можно взять по адресу: https://pddimp.yandex.ru/api2/admin/get_token
  2. 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.

  3. Внешний скрипт, обращение к которому возвращало бы текущий внешний 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.

Добавить комментарий

Войти с помощью: 

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Do NOT follow this link or you will be banned from the site!