Имена компьютеров отделяются от их адресов путем использования удобочитаемых высокоуровневых имен. Таким образом, к веб-серверу компании можно обращаться по имени www.cs.uchicago.edu, независимо от того, какой у него IP-адрес. Поскольку устройства на сетевом пути пересылают трафик к получателю, руководствуясь его IP-адресом, эти удобочитаемые доменные имена нужно конвертировать в IP-адреса; именно это и делает DNS. В следующих разделах мы узнаем, как DNS выполняет это преобразование и каким изменениям она подверглась за прошедшие десятилетия. В частности, серьезное развитие в последние годы получила защита личной информации пользователей. Мы подробно обсудим эти вопросы и последние разработки в области шифрования DNS, связанные с обеспечением конфиденциальности.
7.1.1. История и общие сведения
Во времена сети ARPANET имена всех компьютеров сети и их IP-адреса сохранялись в файле hosts.txt. Каждую ночь все хосты получали этот файл с сайта, на котором он хранился. В сети, состоящей из нескольких сотен больших компьютеров, работающих в системе с разделением времени, такой подход оправдывал себя.
Однако еще задолго до того, как к сети были подключены миллионы компьютеров, всем стало ясно, что этот способ не может работать вечно. Во-первых, размер файла рано или поздно стал бы слишком большим. Что еще важнее, если не управлять именами хостов централизованно, неизбежно возникнут конфликты имен. В то же время в гигантской международной сети такое управление вряд ли возможно. Для решения всех этих проблем в 1983 году и была разработана DNS. С тех пор она является ключевой составляющей интернета.
DNS представляет собой сочетание иерархической схемы именования с распределенной базой данных, реализующей эту схему. В первую очередь DNS служит для преобразования имен хостов в IP-адреса, но у нее есть и ряд иных применений, которые мы подробно обсудим ниже. Система DNS является одним из наиболее активно развивающихся протоколов интернета. Она описана в документах RFC 1034, RFC 1035, RFC 2181 и доработана в ряде других RFC.
7.1.2. Процесс поиска DNS
DNS работает следующим образом. Для преобразования имени в IP-адрес прикладная программа вызывает библиотечную процедуру (обычно это gethostbyname или ее аналог), передавая ей имя в качестве параметра. Этот процесс иногда называют оконечным распознавателем (stub resolver). Он отправляет запрос с именем локальному DNS-распознавателю, или, как его еще часто называют, локальному рекурсивному распознавателю (local recursive resolver) или просто локальному распознавателю, который выполняет рекурсивный поиск (recursive lookup) имени, используя некоторый набор DNS-распознавателей. В итоге локальный распознаватель возвращает ответ с соответствующим IP-адресом оконечному распознавателю, который затем передает результат той функции, от которой поступил исходный запрос. И запрос, и ответ передаются как UDP-пакеты. После этого, уже имея IP-адрес, программа может связаться с хостом, соответствующим тому DNS-имени, которое она искала. Далее в этой главе мы рассмотрим этот процесс более подробно.
Обычно оконечный распознаватель направляет запрос рекурсивного поиска локальному распознавателю, то есть он просто выдает запрос и ожидает ответа. Локальный распознаватель, в свою очередь, направляет ряд запросов соответствующим серверам имен для каждого элемента именной иерархии. Сервер имен, отвечающий за определенную часть этой иерархии, при этом считается авторитетным сервером имен (authoritative name server) для этого домена. Как мы увидим позже, система DNS использует кэширование, но кэш при этом может устаревать. Авторитетный сервер имен обладает, как понятно из названия, непререкаемым авторитетом. Он по определению всегда прав. Перед тем как переходить к более детальному рассмотрению работы DNS, давайте немного поговорим об иерархии серверов имен DNS и процессе выделения имен.
Получив запрос от оконечного распознавателя хоста, локальный распознаватель осуществляет процесс разрешения имен, пока не найдет нужный ответ (или не найдет его вовсе). Он не возвращает частичные ответы. С другой стороны, корневой сервер имен (и каждый последующий) не отправляет запрос локальному серверу имен рекурсивно. Он возвращает частичный ответ и переходит к следующему запросу. Локальный распознаватель обеспечивает продолжение процесса разрешения имен путем выдачи дальнейших итеративных запросов.