Как браузер по доменному имени находит IP-адрес сервера?

«Как браузер по доменному имени находит IP-адрес сервера?» — вопрос из категории HTTP и веб-протоколы, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Браузер использует систему доменных имен (DNS) для преобразования человекочитаемого доменного имени (например, www.example.com) в машинный IP-адрес (например, 93.184.216.34). Этот процесс называется DNS-резолвинг и состоит из нескольких шагов, выполняемых иерархически:

Последовательность запросов DNS

  1. Кеш браузера: Браузер сначала проверяет свой собственный кеш DNS на наличие ранее полученной записи.
  2. Кеш ОС: Если не найдено, запрос передается операционной системе, которая также имеет кеш DNS (в Windows — ipconfig /displaydns, в Linux/macOS — sudo systemd-resolve --statistics).
  3. Резолвер провайдера (ISP): При отсутствии записи в кешах ОС, запрос отправляется на DNS-сервер, указанный в настройках сети (обычно предоставляемый интернет-провайдером или публичный, например, Google DNS 8.8.8.8 или Cloudflare 1.1.1.1).
  4. Корневые DNS-серверы: Если резолвер провайдера не знает адрес, он начинает рекурсивный запрос с корневых серверов (.), которые указывают на серверы домена верхнего уровня (TLD), например, .com.
  5. Серверы TLD: Серверы .com направляют запрос к авторитативным (уполномоченным) DNS-серверам домена example.com, которые хранят окончательную запись.
  6. Авторитативные серверы: Эти серверы возвращают A-запись (для IPv4) или AAAA-запись (для IPv6) с IP-адресом сервера.

Практический пример и код

Полученный IP-адрес кешируется на всех уровнях для ускорения последующих запросов.

# Пример разрешения доменного имени в Python с помощью стандартной библиотеки
import socket

# Получение IP-адреса по доменному имени
try:
    hostname = "www.example.com"
    ip_address = socket.gethostbyname(hostname)
    print(f"Домен '{hostname}' имеет IP-адрес: {ip_address}")
except socket.gaierror as e:
    print(f"Ошибка DNS: {e}")

# Пример получения всех DNS-записей (может потребоваться установка dnspython)
# import dns.resolver
# answers = dns.resolver.resolve('example.com', 'A')
# for rdata in answers:
#     print('IP', rdata.to_text())

Дополнительные механизмы

  • DNS Prefetching: Браузеры могут предварительно разрешать DNS для ссылок на странице, чтобы ускорить переходы.
  • HTTPS и SSL/TLS: После получения IP-адреса браузер устанавливает TCP-соединение и для HTTPS проводит рукопожатие TLS, проверяя SSL-сертификат сервера, который также привязан к доменному имени.