Проверка работы DNS итеративный подход
Проверка работы DNS: итеративный подход
Мы потратили значительное время на создание конфигурационных файлов, используемых сетевыми службами имен, но это всего лишь одна из задач системного и сетевого администратора. Для поддержания сети в рабочем состоянии необходимо постоянно проверять данные службы, чтобы убедиться, что они ведут себя верно.
Например, для системного/сетевого администратора очень многое зависит от ответа на вопрос «Все ли DNS-серверы работают?». В ситуации, когда необходимо найти неисправности, практически настолько же важно знать, «Все ли серверы работают с одной и той же информацией?», или, более точно, «Отвечают ли они одинаково на одинаковые запросы? Синхронизированы ли они?». Данный раздел посвящен подобным вопросам.
По главе 2 можно судить, как действует основной принцип Perl «Всегда существует несколько способов сделать это». Именно такое свойство делает Perl отличным языком для «итеративной разработки». Итеративная разработка - это один из способов описания эволюционного процесса, имеющего место при создании программ системного администрирования (и не только), выполняющих определенную задачу. В случае с Perl можно быстро написать рабочую программу на скорую руку, а позднее вернуться к сценарию и переписать его более элегантным образом. Возможно, будет еще и третья итерация, на этот раз уже с использованием другого подхода к решению задачи.
Существует три различных подхода к одной и той же проблеме проверки согласованности DNS. Они представлены в том порядке, которому, действительно, мог бы последовать человек, пытаясь найти решение, а затем его совершенствуя. Этот порядок отражает взгляд на то, как решение проблемы может развиваться в Perl; ибо ваше отношение к подходу может меняться. Третий способ, использующий модуль Net: : DNS, вероятно, самый простой и наиболее защищенный от ошибок. Но существуют ситуации, когда Net: : DNS применять нельзя, поэтому сначала приведем несколько собственных решений. Обязательно обратите внимание на все за и против, перечисленные после каждого рассмотренного подхода.
Вот наша задача: написать сценарий на Perl, принимающий имя узла и проверяющий список DNS-серверов, чтобы убедиться, что все они возвращают одну и ту же информацию об узле. Чтобы упростить задачу, будем считать, что узел имеет единственный статический IP-адрес (т. е. у него один сетевой адаптер и один IP-адрес).
Перед тем как перейти к рассмотрению всех подходов, взглянем на сердцевину кода, который будем применять:
$hostname = $ARGV[0];
©servers = qw(nameserver1 nameserver2 nameserverS);
# серверы имен
foreach $server (servers) {
&lookupadrjress($hostname, $server);
заполняем %results
}
%inv = reverse %results;
# инвертируем полученный хэш
if (keys %inv > 1) {
print "Между DNS-серверами есть разногласия";
use Data::Dumper;
print Data::Dumper->Dump([\%results],["results"]), "\n"; }
Для каждого из DNS-серверов, перечисленных в списке @servers, вызывается подпрограмма &lookupaddress(), которая обращается к DNS-серверу, чтобы получить IP-адрес заданного имени узла, и помещает результаты в хэш %results. Для каждого DNS-сервера в хэше %results есть запись, значением которой является IP-адрес, возвращаемый этим сервером (ключом является имя сервера).
Существует много способов определить, равны ли друг другу значения из хэша %results (т. е. убедиться, что все DNS-серверы возвращают одну и ту же информацию в ответ на запрос). Мы инвертируем хэш %results в другую хэш-таблицу, преобразовывая все ключи в значения и наоборот. Если все значения из %results одинаковы, то в инвертированном хэше должен быть только один ключ. Если ключей несколько, значит, мы выловили прокол, и поэтому вызываем Data: :Duniper->Durrip() для СлужОа доменных имен вывода содержимого %results, над которым будет ломать голову системный администратор.
Вот как может выглядеть примерный результат, если что-то идет не так:
Между DNS-серверами есть разногласия: $results = {
nameserverl => '192.168.1.2',
nameserver2 => '192. 168. 1.5' ,
nameserverS => ' 192. 168. 1.2' ,
Теперь посмотрим на альтернативы подпрограмме &lookupaddress( ).