Определение DNS

Система доменных имен предоставляет распределенную базу данных которая хранит "записи о ресурсах" доменных имен. Локальных хост может участвовать в процессе разрешения доменного имени несколькими способами, самый простой показан ниже:

Host side resolving: Разрешение:

  Локальный хост                                                    | Удаленный хост
                                                                    |                   
+------------------+                          +----------+          |  +----------+
|                  | пользовательские запросы |          | запросы  |  |          |
| Пользовательская |------------------------->|          |----------|->|Удаленный |
| программа        |                          | Резолвер |          |  | сервер   |
|                  |<-------------------------|          |<---------|--|  имен    |
|                  | ответы пользователю      |          | ответы   |  |          |
+------------------+                          +----------+          |  +----------+
                                                |     A             |
                                проверка кэша   |     | сохраненные |
                                                V     | ответы      |
                                              +----------+          |
                                              |   кэш    |          |
                                              +----------+          |
  • Браузер проверяет наличие домена в своём кэше. Например, чтоб увидеть кэш Google Chrome следует ввести в адресной строке chrome://net-internals/#dns.

  • Если домена там нет, то браузер вызывает библиотечную функцию gethostbyname (отличается в разных ОС) для поиска нужного адреса.

  • Прежде, чем искать домен по DNS gethostbyname пытается найти нужный адрес в файле hosts (его расположение отличается в разных ОС).

    • В Linux порядок поиска можно настроить в файле /etc/nsswitch.conf, например, поведение по умолчанию:
    hosts:  files dns
    
  • Если домен нигде не закэширован и отсутствует в файле hosts, gethostbyname отправляет запрос к сетевому DNS-серверу. Как правило, это локальный роутер или DNS-сервер интернет-провайдера.

  • При отправке запроса к DNS-серверу будет использоваться настройка приоритета использования интерфейсов для исходящего трафика (например, файл /etc/gai.conf).

  • Если DNS-сервер находится в той же подсети, то сетевая библиотека выполняет ARP-запрос, который отправляется этому серверу.

  • Если DNS-сервер находится в другой подсети, , то сетевая библиотека выполняет ARP-запрос, который отправляется на IP-адрес шлюза по умолчанию (default gateway).

  • Если DNS-сервер не может найти IP-адрес имени хоста в кэше, он отправляет запрос резолверу, который специально настроен для получения IP-адреса любого имени хоста.

    • Когда резолвер задействован, он сначала проверяет свой собственный кэш, но если он не может найти запись, он связывается с TLD (домен верхнего уровня), вероятно, с сервером com-зоны. Com - это домен верхнего уровня.
    • TLD содержит информацию о серверах имен конкретных имен хостов. Зная имя хоста, которое пытается идентифицировать распознаватель, он может найти IP-адреса сервера имен вместе с их именами.
    • Резолвер использует IP-адреса для запроса от серверов имен, информацию об IP-адресах, которую он ищет для своего конкретного имени хоста. В зависимости от сервера имен и какой зоны он обрабатывает, он должен найти IP хоста.
    • После того, как резолвер обнаружил соответствующий IP-адрес, он возвращается на DNS-сервер, который возвращается в браузер. Повсюду серверы кэшируют имя хоста и его IP в соответствии с ограничениями времени жизни (TTL).

Процесс отправки ARP-запроса

Для того, чтобы отправить широковещательный ARP-запрос необходимо отыскать целевой IP-адрес, а также знать MAC-адрес интерфейса, который будет использоваться для отправки ARP-запроса (например, настройки из /etc/gai.conf)

Кэш ARP проверяется для каждого целевого IP-адреса — если адрес есть в кэше, то библиотечная функция возвращает результат: Target IP = MAC.

Если же записи в кэше нет:

  • Проверяется таблица маршрутизации — это делается для того, чтобы узнать, есть ли искомый IP-адрес в какой-либо из подсетей локальной таблицы. Если он там, то запрос посылается с помощью интерфейса, связанного с этой подсетью. Если адрес в таблице не обнаружен, то используется интерфейс подсети шлюза по умолчанию.
  • Определяется MAC-адрес выбранного сетевого интерфейса.
  • Отправляется ARP-запрос (второй или канальный(data link) уровень модели OSI):
ARP-запрос:
Sender MAC: interface:mac:address:here
Sender IP: interface.ip.goes.here
Target MAC: FF:FF:FF:FF:FF:FF (Broadcast)
Target IP: target.ip.goes.here

В зависимости от того, какое «железо» расположено между компьютером и роутером (маршрутизатором):

Прямое соединение:

  • Если компьютер напрямую подключён к роутеру, то это устройство отправляет ARP-ответ (ARP Reply).

Между ними концентратор (Хаб):

  • Если компьютер подключён к сетевому концентратору, то этот хаб отправляет широковещательный ARP-запрос со всех своих портов. Если роутер подключён по тому же «проводу», то отправит ARP-ответ.

Между ними коммутатор (свитч):

  • Если компьютер соединён с сетевым коммутатором, то этот свитч проверит локальную CAM/MAC-таблицу, чтобы узнать, какой порт в ней имеет нужный MAC-адрес. Если нужного адреса в таблице нет, то он заново отправит широковещательный ARP-запрос по всем портам, за исключением порта, откуда пришел запрос.
  • Если в CAM/MAC-таблице коммутатора есть нужная запись, то свитч отправит ARP-запрос на порт с искомым MAC-адресом. Если входящий MAC-адрес отличается от существующего, то свитч добавит входящий MAC-адрес отправителя в таблицу CAM/MAC, затем он отправит широковещательную рассылку ARP на все порты, кроме порта, с которого поступил запрос.
  • Если роутер «на одной линии» со свитчем, то он ответит (ARP Reply).
ARP-ответ:
Sender MAC: target:mac:address:here
Sender IP: target.ip.goes.here
Target MAC: interface:mac:address:here
Target IP: interface.ip.goes.here

Теперь у сетевой библиотеки есть MAC-адрес либо DNS-сервера либо шлюза по умолчанию, который можно использовать для разрешения доменного имени:

  • DNS-клиент устанавливает сокет для UDP-порта 53 на DNS-сервере, используя номер порта источника выше 1023.
  • Если размер ответа слишком велик, то вместо него будет использоваться TCP.
  • Если локальный или на стороне провайдера DNS-сервер «не знает» нужный адрес, то запрашивается рекурсивный поиск, который проходит по списку вышестоящих DNS-серверов, пока не будет найдена SOA-запись, а затем возвращается результат.