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

Ответ

Браузер использует систему доменных имен (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-сертификат сервера, который также привязан к доменному имени.

Ответ 18+ 🔞

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

Куда запрос шляется, пока не находит адрес:

  1. Свой карман (кеш браузера). Первым делом браузер шарит у себя в загашнике: «А не спрашивал ли я про этот домен пять минут назад?». Нашёл — красота, не паримся.
  2. Общий карман (кеш ОС). Не нашёл? Тогда стучится к операционке: «Э, система, у тебя случайно в памяти не валяется адресок?». В Винде это ipconfig /displaydns посмотреть, в Линуксе/маке свои команды. Опять мимо — пошёл дальше, бедолага.
  3. Дядя-резолвер (обычно от провайдера). Тут запрос вываливается в интернет к специальному DNS-серверу. Чаще всего это сервак твоего провайдера, но можно и крутых дядь позвать, типа Гугла (8.8.8.8) или Клаудфлэра (1.1.1.1).
  4. Верховные жрецы (корневые серверы). Если и у дяди-резолвера в голове пусто, он идёт на самый верх — к корневым DNS-серверам (это те, что отвечают за точку «.»). Те такие: «О, example.com? Иди к тем, кто рулит всеми .com, сынок».
  5. Начальники зон (серверы TLD). Серверы зоны .com получают запрос, чешут репу: «Ага, example.com... Это вот к их авторитативным серверам иди, они всё знают».
  6. Непосредственные боги домена (авторитативные серверы). И вот, наконец, запрос доползает до серверов, которые внатуре знают про example.com. Они выдают священную A-запись (для IPv4) или AAAA-запись (для IPv6) — тот самый IP-адрес. Ура, товарищи!

И чтобы каждый раз не бегать по всей этой хуйне, найденный адрес кешируется на всех этажах — у браузера, у ОС, у резолвера. Экономия времени — овердохуищная.

Чуть кода для наглядности

# Пример, как на Питоне домен в IP превратить
import socket

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}")

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

А ещё есть фишки для ускорения

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