Всем привет! Я написал скрипт для синхронизации записей DNS с DHCP-арендами, чтобы вам не приходилось вручную поддерживать два списка. По сути, он хранит все аренды и имена хостов в самом скрипте, а затем применяет (заменяет) их на DNS-сервере и DHCP-сервере. Так что заботиться нужно только о конфигурации в скрипте (что обеспечивает централизованность). Всё, что нужно, — это следующее:
#Вся статическая конфигурация DHCP&DNS в одной зоне (описано ниже) см. здесь. Этот скрипт обновит (удалит, а потом создаст заново) все записи, которые соответствуют описанной конфигурации. Поэтому менять что-либо на DHCP-сервере или во вкладке DNS бессмысленно. Если нужно изменить статические записи DNS/DHCP — читайте руководство здесь.
#Настройка окружения
:local dhcpserver "Internal Network"
:local zone “example.com”
:global hostListString
#Здесь задаём, сколько списков у вас есть. Правило именования фиксированное — hostListStringX
:local ifrom 1;
:local ito 2;
#Списки хостов (машин/устройств)
#Формат: $ip,$hostname,$mac_addr,$client_id
#Каждая запись — в ОДНОЙ строке!
#Между запятыми не должно быть пробелов!
#$client_id — это "1:" + MAC-адрес в нижнем регистре. Можно также взять из DHCP Server->Lease.
#Важно: :global нужен, потому что ниже используется :parse
#Особенности: последняя строка должна быть пустой.
#Ограничение: размер переменной не может быть больше 4096 байт — это жёстко заданное ограничение MikroTik. Возможно, придётся разбить на несколько списков. Лично я так же разделяю списки для разных подсетей. В общем, как удобно вам.
#Пример списков
:global hostListString1 "192.168.1.11,server1,00:DD:CC:EE:EE:11,1:0:dd:cc:ee:ee:11
192.168.1.12,server2,00:DD:CC:EE:EE:12,1:0:dd:cc:ee:ee:12
192.168.1.13,server3,00:DD:CC:EE:EE:13,1:0:dd:cc:ee:ee:13
";
:global hostListString2 "192.168.2.11,client1,00:DD:CC:EE:EE:21,1:0:dd:cc:ee:ee:21
192.168.2.12,client2,00:DD:CC:EE:EE:22,1:0:dd:cc:ee:ee:22
192.168.2.13,client3,00:DD:CC:EE:EE:23,1:0:dd:cc:ee:ee:23
";
#Начало скрипта
#Удаляем старые статические DNS-записи
/ip dns static remove [find where name ~ (".*\\.".$zone)]
:for i from=$ifrom to=$ito do={
:local changeList [:parse (":global hostListString". [:tostr $i] . "; :global hostListString; :set \$hostListString \$hostListString" . [:tostr $i])];
$changeList;
:local contentLen [ :len $hostListString ];
:local lineEnd 0;
:local line "";
:local lastEnd 0;
:local hostArray;
:do {
:set lineEnd [:find $hostListString "\n" $lastEnd ];
:set line [:pick $hostListString $lastEnd $lineEnd];
:set lastEnd ( $lineEnd + 1 );
:set hostArray [:toarray $line];
:if ([:len $line] >= 7 ) do={
#Возвращаем DNS-записи
/ip dns static add address=[:pick $hostArray 0] name=([:pick $hostArray 1].".".$zone)
#Ищем, есть ли хост на DHCP-сервере
/ip dhcp-server lease
:local searchingDHCP [find where mac-address=[:pick $hostArray 2]];
:if ($searchingDHCP != "") do={
#Хост найден! Запускаем make-static (вместо удаления и создания заново)
#Эти две команды вызывают предупреждение, ловим исключения.
:do { make-static number=$searchingDHCP } on-error={};
:do { set number=$searchingDHCP address=[:pick $hostArray 0] server=$dhcpserver comment="-)createdBy=DHCP2DNS" } on-error={};
} else={
#Хост не найден! Если есть — удаляем и создаём заново
:if ([find where mac-address=[:pick $hostArray 2]] != "") do={ remove number=(find where mac-address=[:pick $hostArray 2]) }
add address=[:pick $hostArray 0] mac-address=[:pick $hostArray 2] client-id=[:pick $hostArray 3] server=$dhcpserver comment="-)createdBy=DHCP2DNS"
}
} else={ :put "Пустая запись"; }
} while ($lineEnd < $contentLen-1)
}
Просто следуйте формату и вписывайте свои MAC, IP, hostname прямо в скрипт. Потом создайте задачу по расписанию для обновления (может и не понадобится). Внимание: обязательно сделайте резервную копию всей конфигурации и внимательно прочитайте примечания перед применением. Если конфигурация неверна, скрипт может удалить все ваши DHCP и DNS записи.
#Вся статическая конфигурация DHCP&DNS в одной зоне (описано ниже) см. здесь. Этот скрипт обновит (удалит, а потом создаст заново) все записи, которые соответствуют описанной конфигурации. Поэтому менять что-либо на DHCP-сервере или во вкладке DNS бессмысленно. Если нужно изменить статические записи DNS/DHCP — читайте руководство здесь.
#Настройка окружения
:local dhcpserver "Internal Network"
:local zone “example.com”
:global hostListString
#Здесь задаём, сколько списков у вас есть. Правило именования фиксированное — hostListStringX
:local ifrom 1;
:local ito 2;
#Списки хостов (машин/устройств)
#Формат: $ip,$hostname,$mac_addr,$client_id
#Каждая запись — в ОДНОЙ строке!
#Между запятыми не должно быть пробелов!
#$client_id — это "1:" + MAC-адрес в нижнем регистре. Можно также взять из DHCP Server->Lease.
#Важно: :global нужен, потому что ниже используется :parse
#Особенности: последняя строка должна быть пустой.
#Ограничение: размер переменной не может быть больше 4096 байт — это жёстко заданное ограничение MikroTik. Возможно, придётся разбить на несколько списков. Лично я так же разделяю списки для разных подсетей. В общем, как удобно вам.
#Пример списков
:global hostListString1 "192.168.1.11,server1,00:DD:CC:EE:EE:11,1:0:dd:cc:ee:ee:11
192.168.1.12,server2,00:DD:CC:EE:EE:12,1:0:dd:cc:ee:ee:12
192.168.1.13,server3,00:DD:CC:EE:EE:13,1:0:dd:cc:ee:ee:13
";
:global hostListString2 "192.168.2.11,client1,00:DD:CC:EE:EE:21,1:0:dd:cc:ee:ee:21
192.168.2.12,client2,00:DD:CC:EE:EE:22,1:0:dd:cc:ee:ee:22
192.168.2.13,client3,00:DD:CC:EE:EE:23,1:0:dd:cc:ee:ee:23
";
#Начало скрипта
#Удаляем старые статические DNS-записи
/ip dns static remove [find where name ~ (".*\\.".$zone)]
:for i from=$ifrom to=$ito do={
:local changeList [:parse (":global hostListString". [:tostr $i] . "; :global hostListString; :set \$hostListString \$hostListString" . [:tostr $i])];
$changeList;
:local contentLen [ :len $hostListString ];
:local lineEnd 0;
:local line "";
:local lastEnd 0;
:local hostArray;
:do {
:set lineEnd [:find $hostListString "\n" $lastEnd ];
:set line [:pick $hostListString $lastEnd $lineEnd];
:set lastEnd ( $lineEnd + 1 );
:set hostArray [:toarray $line];
:if ([:len $line] >= 7 ) do={
#Возвращаем DNS-записи
/ip dns static add address=[:pick $hostArray 0] name=([:pick $hostArray 1].".".$zone)
#Ищем, есть ли хост на DHCP-сервере
/ip dhcp-server lease
:local searchingDHCP [find where mac-address=[:pick $hostArray 2]];
:if ($searchingDHCP != "") do={
#Хост найден! Запускаем make-static (вместо удаления и создания заново)
#Эти две команды вызывают предупреждение, ловим исключения.
:do { make-static number=$searchingDHCP } on-error={};
:do { set number=$searchingDHCP address=[:pick $hostArray 0] server=$dhcpserver comment="-)createdBy=DHCP2DNS" } on-error={};
} else={
#Хост не найден! Если есть — удаляем и создаём заново
:if ([find where mac-address=[:pick $hostArray 2]] != "") do={ remove number=(find where mac-address=[:pick $hostArray 2]) }
add address=[:pick $hostArray 0] mac-address=[:pick $hostArray 2] client-id=[:pick $hostArray 3] server=$dhcpserver comment="-)createdBy=DHCP2DNS"
}
} else={ :put "Пустая запись"; }
} while ($lineEnd < $contentLen-1)
}
Просто следуйте формату и вписывайте свои MAC, IP, hostname прямо в скрипт. Потом создайте задачу по расписанию для обновления (может и не понадобится). Внимание: обязательно сделайте резервную копию всей конфигурации и внимательно прочитайте примечания перед применением. Если конфигурация неверна, скрипт может удалить все ваши DHCP и DNS записи.