Про публичный Wi-Fi принято говорить одно из двух. Либо «там воруют пароли, не подключайтесь», либо «сейчас везде HTTPS, всё в порядке». Обе формулировки неточные, и обе мешают понимать, что происходит на самом деле.

Пароли при работающем HTTPS действительно не украдут — с этим всё в порядке. А вот список сайтов, куда вы ходите, виден любому, кто сидит на том же канале — владельцу точки доступа, провайдеру, соседу с ноутбуком, если сеть открытая. Причём видно его в открытом виде, никакого взлома для этого не требуется.

Первое: DNS

Прежде чем открыть сайт, устройство спрашивает у DNS-сервера адрес по имени. Классический DNS работает по UDP без всякого шифрования, то есть имя сайта летит открытым текстом.

Это видно на собственном компьютере, без специальных условий. Запускаю захват и параллельно открываю пару сайтов:

tshark -i any -f "udp port 53" -T fields -e dns.qry.name -a duration:6
habr.com
example.org

Ровно то, что я запрашивал. Такую же картинку видит владелец точки доступа — с той разницей, что у него в списке будут все домены всех подключённых устройств.

Отдельная деталь: даже когда сайт вы закрыли, устройство продолжает спрашивать домены фоном — обновления, мессенджеры, синхронизация. По этому фону неплохо восстанавливается, чем вы пользуетесь.

Второе: SNI

Допустим, DNS вы зашифровали. Дальше устанавливается TLS-соединение, и в самом первом сообщении клиент сообщает серверу, к какому имени он обращается. Поле называется SNI, и нужно оно потому, что на одном адресе живут сотни сайтов — сервер должен понять, чей сертификат предъявлять.

Проблема в том, что это самое первое сообщение отправляется до того, как согласовано шифрование. То есть открытым текстом.

Проверяется так же:

tshark -i any -f "tcp port 443" -Y "tls.handshake.extensions_server_name" \
       -T fields -e ip.dst -e tls.handshake.extensions_server_name -a duration:8
178.248.237.68	habr.com
142.251.153.119	www.google.com

Соединение зашифровано, а имя сайта в нём — нет. Именно так работают блокировки и фильтрация по доменам: содержимое никто не расшифровывает, достаточно посмотреть на первое сообщение.

Что при этом действительно не видно

Чтобы не впасть в другую крайность, перечислю обратную сторону.

Не видно пути и параметров запроса. https://example.com/account/orders/17 для наблюдателя — просто example.com. Что именно вы там открыли, какой поисковый запрос ввели, какие данные отправили в форме — всё это внутри шифрованного канала.

Не видно содержимого страниц, файлов, сообщений, паролей и кук. Подменить содержимое тоже не получится: сертификат не сойдётся, и браузер поднимет тревогу.

Отсюда практический вывод про публичные сети: страшилка «подключился к Wi-Fi в кафе — украли пароль от банка» устарела лет на десять. Реальная утечка тут — не пароли, а сам факт: какие сервисы вы используете, когда и как часто. Для многих ситуаций это чувствительнее пароля.

Ещё остаются размеры и тайминги пакетов. По ним при большом желании различают, например, какое видео из известного набора вы смотрите. Это уже не бытовая история, но метод существует, и от него шифрование само по себе не спасает.

Как закрыть DNS

Современные браузеры умеют слать DNS-запросы внутри HTTPS — это называется DNS over HTTPS. Тогда имена перестают быть видны на канале и уходят к выбранному вами резолверу.

В Firefox: Настройки → Приватность и защита → DNS через HTTPS. В Chrome: Настройки → Конфиденциальность и безопасность → Безопасность → Использовать безопасный DNS.

Проверить, что оно включилось, можно тем же захватом: после включения домены, которые открывает браузер, в выводе udp port 53 пропадают. Останутся запросы от других программ — они настраиваются отдельно, на уровне системы.

Важная оговорка, которую редко проговаривают: DNS over HTTPS не делает вас невидимым, он меняет того, кто вас видит. Вместо провайдера или владельца точки список доменов получает тот, чей резолвер вы указали. Это осмысленный размен, если вы понимаете, кому доверяете больше.

Как закрыть SNI

Здесь сложнее. Шифрование этого поля — механизм Encrypted Client Hello — существует, но требует поддержки с двух сторон: и браузером, и стороной сайта, включая его инфраструктуру доставки. Крупные площадки постепенно включают, остальные — нет.

У Firefox переключатель лежит в настройках сети, у Chrome — среди экспериментальных флагов. Эффект пока частичный: для сайтов без поддержки имя уходит открытым текстом.

Поэтому на сегодня единственный способ надёжно спрятать список сайтов от локальной сети и провайдера — туннель. Который, опять же, не делает трафик невидимым, а переносит точку наблюдения к владельцу туннеля.

Когда туннель не помогает

Три ситуации, о которых стоит помнить.

Утечки DNS мимо туннеля. Система может продолжать спрашивать домены у прежнего сервера, и тогда имена сайтов утекают, хотя весь остальной трафик идёт через туннель. Проверяется тем же захватом, что и выше: включаете туннель и смотрите, остались ли открытые запросы к 53 порту.

Момент до подключения. Пока туннель поднимается, часть трафика уже ушла напрямую — мессенджеры и обновления начинают работать раньше. Помогает опция блокировки соединений вне туннеля, она есть у большинства клиентов.

И сам факт использования. Что вы пользуетесь туннелем, локальная сеть видит: адрес назначения и характер соединения никуда не деваются.