Сделал специальный сервис для DNS – dns.1d.pw. Не торопитесь кликать – там нет A-записи, это именно что DNS-сервис, но он полезен для отладки и поиска причин возникновения проблем. Смысл вот в чём: если спросить в DNS TXT-запись для dns.1d.pw, то в ответ вернётся информация о том, как виден со стороны авторитативного сервера DNS-резолвер, который выполнил DNS-запрос. Вот простейший пример (здесь и далее используется утилита dig из пакета BIND):

$ dig dns.1d.pw -t TXT +short
"ns: dns-b"
"transport: UDP"
"src: [2a04:e4c0:10::145]:63761"
"target [id]: dns.1d.pw. [34301]"

Спрашивать нужно именно TXT: с A-записью – не получится. Кроме TXT – поддерживается только минимум: SOA и NS.

Ответ состоит из нескольких TXT-записей. Выясним, – пока кратко, – что в них видно (по порядку сверху вниз, как в примере):
внутренне имя авторитативного сервера, который обработал запрос (dns-b);
транспорт (UDP), по которому сервер получил запрос и ответил резолверу (то есть, не вашему клиенту, а именно резолверу);
IP-адрес узла, приславшего запрос, и номер порта ([2a04:e4c0:10::145]:63761); Здесь IPv6-адрес – сервис, естественно, поддерживает IPv6 тоже;
целевое имя, как его было видно в DNS-запросе, и код ID DNS-сообщения (dns.1d.pw. [34301]); дальше я объясню, почему это важно, хотя, казалось бы, имя и так известно.

И это не все параметры, которые присылает данный сервис.

Подобные сервисы существуют, и достаточно давно. Например, есть “очки” от Google: o-o.myaddr.google.com – показывает адрес резолвера и состав ECS, есть “пробник” от Akamai: whoami.ds.akahelp.net, и другие. Понятно, что у этих сервисов – свои ограничения. Например, я разу добавил поддержку DNS over TLS, поскольку данную технологию можно использовать между резолвером и авторитативными серверами (естественно, поддержка авторитативными серверам – редкость, но тем не менее).

Итак, технический смысл затеи: DNS-зона dns.1d.pw делегирована на специально разработанные NS-серверы, которые собирают данные о запросе, упаковывают их в TXT-записи, и отправляют в ответ. Такой способ позволяет информации пройти по цепочке, через резолвер. То есть, при штатной схеме работы, рекурсивный опрос для клиента выполняет рекурсивный резолвер, и именно это резолвер, в конце DNS-поиска, пришлёт запрос на авторитативный сервер. Например, если воспользоваться Google Public DNS, то мы увидим IP-адрес из пула DNS-сервисов Google (пример для 8.8.8.8):

$ dig @8.8.8.8 dns.1d.pw -t TXT +short
"ECS: 185.39.19.0/24/0"
"ns: dns-b"
"src: 74.114.29.150:43267"
"target [id]: dns.1d.Pw. [2909]"
"transport: UDP"

Обратите внимание, здесь добавилась информация о подсети источника запроса – ECS: 185.39.19.0/24/0. Это именно источник того запроса, который поступил в систему Google, а сервис DNS-резолвинга Google пронёс эту адресную информацию до авторитативного сервера. То есть, если вы используете сервис 8.8.8.8, то, – при прочих равных, – авторитативные серверы видят номер вашей подсети (обычно, это подсеть интернет-провайдера). Авторитативные серверы DNS – это не серверы Google, а подсеть видна даже в том случае, если прочий трафик завёрнут в VPN.

Кроме сведений о префиксе ECS, этот второй пример содержит другой адрес источника: 74.114.29.150 – IPv4-адрес резолвера Google. Сервис Google может приходить за DNS-данными и по IPv6, и по IPv4.

Приглядитесь к записи целевого имени – dns.1d.pw: при вызове dig имя записано строчными буквами, но в TXT-записи вернулось dns.1d.Pw (заглавная P). Именно так имя увидел авторитативный сервер. Что это? Это называется “рандомизация регистра символов” – один из дополнительных факторов защиты от спуфинга ответов, который применяет Google. Если воспользоваться аналогичным сервисом Cloudflare (1.1.1.1), то “рандомизации регистра” не случится:

$ dig @1.1.1.1 dns.1d.pw -t TXT +short
"target [id]: dns.1d.pw. [33389]"
"ns: dns-a"
"src: [2400:cb00:78:1024::ac44:b97b]:24308"
"transport: UDP"

Чтобы наблюдать такие эффекты и требуется возврат исходного имени в TXT-ответе. Дело в том, что изменяет имя резолвер, поэтому, без подобных хитростей, на DNS-клиенте резолвера обнаружить изменения нельзя.

Второй фактор защиты от спуфинга тоже можно видеть на распечатке выше: это номер транзакции (id – 33389). Сервер должен ответить с тем же номером, который отправил DNS-клиент в запросе. Третий типовой фактор – номер порта-источника (особенно актуально в UDP). Запросы в DNS отправляются на номер порта 53 (udp, tcp) и 853 (DNS over TLS), а номер порта-источника, соответственно, рандомизируется (должно быть сложно его угадать).

Сервис можно использовать для того, чтобы увидеть собственный внешний IP и параметры собственных DNS-запросов. Для этого нужно выступить в роли резолвера, направив DNS-запрос непосредственно узлу данного сервиса. Имена можно узнать, запросив список NS:

$ dig @8.8.8.8 dns.1d.pw -t NS +short
ns-dns-a.1d.pw.
ns-dns-b.1d.pw.

Спрашиваем напрямую ns-dns-a.1d.pw:

$ dig @ns-dns-a.1d.pw dns.1d.pw -t TXT +short
"target [id]: dns.1d.pw. [31841]"
"ns: dns-a"
"src: 185.39.19.199:26283"
"transport: UDP"

Получили в “src” IP-адрес, с которого отправлен локальный запрос (точнее: тот адрес, который видит внешний сервис – потому что может быть NAT и тому подобные штуки).

Основной транспорт для DNS – это UDP. Однако необходима и поддержка TCP. Сервис dns.1d.pw умеет отвечать по TCP. Да, контролировать протокол, который использует внешний резолвер, так просто не выйдет, но при локальнй подготовке запроса можно выбрать TCP при помощи флага +tcp утилиты dig. Проверяем:

$ dig @ns-dns-a.1d.pw dns.1d.pw -t TXT +short +tcp
"target [id]: dns.1d.pw. [9376]"
"ns: dns-a"
"src: 185.39.19.199:50169"
"transport: TCP"

Теперь указан TCP в качестве транспорта. TLS – не является обязательным. Однако это современная и весьма популярная технология, которая тут тоже поддерживается. Более того, сервис возвращает “расширенную информацию” – данные о версии TLS, о шифронаборах, о выбранном имени узла (SNI). Утилита dig поддерживает TLS (+tls). Проверяем:

$ dig @ns-dns-a.1d.pw dns.1d.pw -t TXT +tls +short
"target [id]: dns.1d.pw. [22366]"
"ns: dns-a"
"src: 185.39.19.199:59527"
"transport: TLS (1.3/X25519MLKEM768/TLS_CHACHA20_POLY1305_SHA256)"
"SNI: ns-dns-a.1d.pw"

Обратите внимание: здесь в записи имени DNS-узла – ns-dns-a.1d.pw – нельзя указывать крайнюю справа точку (которая превратила бы запись в FQDN, и которая для специалистов в DNS является чем-то само собой разумеющимся). Дело в том, что бэкенд сервиса использует реализацию TLS из типовой библиотеки Go. А типовая, “коробочная”, реализация TLS в Go строго не допускает финальные точки в составе хостнейма внутри расширения SNI – TLS-соединение просто не устанавливается. Такое поведение библиотеки, вообще говоря, вопрос весьма дискуссионный, но к теме этой записки он не относится: просто – не указывайте точку в конце, или используйте IP-адрес узла напрямую (возможно, я как-нибудь этот момент переделаю самостоятельно, ну или разработчики Go одумаются).

Вообще, TLS-сертификаты для авторитативных серверов, используемых в данном проекте, я выпустил через Let’s Encrypt, и это сертификаты для IP-адресов (v4/v6), что неплохо подходит для случая TLS на авторитативном DNS-сервере. А раз это сертификаты для IP-адресов, то для хостнеймов они так и так не валидны, но по умолчанию – dig здесь сертификаты и не проверяет на соответствие имён.

В поведение авторитативного сервера заложены и некоторые другие особенности, так что он не полностью соответствует “лучшим практикам” DNS, и это сделано специально. Например, как отмечено выше, в ответ на запрос A-записи – придёт ответ с флагом REFUSED, а это позволяет посмотреть на расширенные статусы DNS-ошибок, если запросить А-запись через сервис Google.



Комментировать »

Всё чаще попадаются попытки внедрения IPv6-only (только IPv6) веб-узлов. И всё чаще встречается типовая техническая ошибка, этот процесс сопровождающая: для DNS-имени, указывающего на веб-узел, присутствует только AAAA-запись (то есть, только IPv6-адрес), но при этом все авторитативные серверы имён (NS) соответствующей доменной зоны – имеют только A-записи, только v4-адреса. В некотором роде – это удивительное техническое противоречие, граничащее с “карго-культом”: с v4 – доступ к такому сайту получить невозможно, так как нет адресной записи, но и получить v6-доступ, не воспользовавшись v4, тоже невозможно – потому что необходимо обратиться по v4-адресам NS.

IPv6 – не такой уж плохой протокол: многое там сделано даже логичнее практики v4. Но внедрять его “эксклюзивность” нужно аккуратно. Естественное и правильное решение для NS – добавить для авторитативных серверов IPv6-адреса, обеспечить по ним доступность DNS, а уж потом запускать IPv6-эксклюзивный веб-узел под AAAA-записью. Потому что тогда, при верном выборе зоны, все необходимые прикладные процессы смогут работать по IPv6, который уже заслуженно будет в приоритете (в корневой зоне DNS – IPv6 есть). Конечно, при наличии полной поддержки и v6, и v4 на клиенте – запрашивать нужно сразу и A, и AAAA-запись, отдавая приоритет AAAA при соединении. Но если есть только v4, то возникают дополнительные сложности.

Формально, ничего не запрещает не держать в DNS-зоне A-записи, а держать только AAAA, но раздавать эти AAAA исключительно через четвёртую версию протокола. Однако выглядит такая настройка максимально некрасиво, совсем не так, как IPv6-адреса на NS, и только A-запись – для веб-узла.

Более того, ситуация, когда на клиенте нет полноценного IPv6, а в целевой зоне – нет A-записи, и при этом сведения об отсутствии такой записи можно получить только через v4, вполне может трактоваться клиентом как отсутствие IP-доступа к веб-узлу совсем, вне зависимости от версии IP: нет адресной записи и – всё. И такой сигнал отсутствия даже может кешироваться на клиенте, перекрывая повторный доступ после того, как IPv6 на клиенте включился (конечно, в рамках той же сессии прикладного ПО, но такое – вполне возможно, так как сетевой интерфейс с полноценным v6 мог подняться позже, по команде пользователя). Дело в том, что после включения v6 можно было бы спросить AAAA-запись в DNS, но этому мешает флаг “отсутствует адресная запись”, уже установленны прикладным или системным ПО, который флаг, предположим, является универсальным, то есть, не зависит от версий v4/v6.

(Бывают, кстати, и другие “косые” ситуации: в vk.com, например, IPv6-адреса у авторитативных NS есть, но вот только DNS по ним не отвечает.)



Комментарии (2) »

В Интернете криптография далеко не всегда позволяет уверенно говорить, что IP-узел не был подменён. Даже если речь про аутентификацию по конкретным открытым ключам. Уже неоднократно писал на эту тему, но, похоже, имеет смысл ещё раз повторить некоторые моменты – вдруг кому-то будет полезно.

1.

В IP-сетях ответить вместо “реального узла назначения” может любой промежуточный узел. Причём, ответить даже на уровне выше IP – то есть, речь не об ICMP и подобных инструментах, а о том, что промежуточный узел может полностью перехватить и поддерживать сессию. IP-адрес – это просто индекс, данные внутри пакета.

2.

Всякий промежуточный узел может прочитать адреса из состава пакета и, если они подходят, начать отвечать так, как если бы адрес назначения принадлежал этому узлу, в том числе, открыть контекст и выставить сокет на уровень приложений. Иногда, в реальном Интернете, могут приключиться всякие трудности, происходящие из того, что пути доставки пакетов в одну сторону и обратно – различаются, но и это не должно сильно мешать, если перехватывающий узел удачно встроен в цепочку, а ответные пакеты от него проходят на уровне IP. В общем, это детали, а основной вывод тут простой: в IP-сетях ответить может другой узел, и нельзя определить, отвечает ли тот узел, который планировался. Это свойство таких сетей.

3.

Один из эффективных методов противодействия такой подмене основан на приписывании узлам криптографических ключей. То есть, по криптографическим ключам осуществляется и дополнительная идентификация, и – аутентификация (в том или ином режиме). Предполагается, что узлу назначения известен некоторый секретный ключ. Именно к такой схеме относится описанный далее простой алгоритм с RSA-ключом. Предположим, что некоторое приложение мессенджера использует зашитый в это приложение открытый RSA-ключ для того, чтобы зашифровать некий сессионный секрет, прежде чем отправить его на центральный сервер (RSA-шифрование сейчас с такой целью использовать не рекомендуется, здесь оно только в качестве примера). Ожидается, что этот центральный сервер знает секретный ключ RSA, соответствующий открытому, а поэтому сможет расшифровать сессионный секрет. Перехватывающий промежуточный узел не знает секретного ключа RSA, и не сможет ничего расшифровать. Получается некоторая слабая аутентификация сервера, по схеме “запрос доказательства знания секрета и виртуализированный ответ” (“виртуализированный” потому, что корректная обработка именно на стороне доверенного сервера только подразумевается, но не проверяется строго – см. ниже, к чему это приводит). Здесь только два действительно важных момента: “секретный ключ RSA” и “центральный доверенный сервер”.

4.

И вот, почему-то думают, что описанный в предыдущем пункте механизм гарантирует, что связь устанавливается именно с подлинным сервером. Однако правильное понимание – сильно слабее: механизм гарантирует то, что вторая сторона смогла расшифровать секрет. Заметьте, тут даже нет привязки к отпечатку ключа – никто не просит доказывать, что конкретный узел, назвавшийся доверенным сервером, знает именно секретный ключ именно от данного открытого ключа. То есть, такая схема защиты – довольно эффективная, но она далеко не настолько строгая, как почему-то принято думать.

5.

Что означает предыдущий пункт на практике? Вот что: во-первых, подобные схемы с ключами никак не отменяют возможности подмены сессий в IP-сетях, они только позволяют обнаружить некорректную подмену; во-вторых, если секретный RSA-ключ передан от доверенного сервера перехватывающему узлу, то этот узел всё так же сможет прозрачно подменять сервер, перехватив IP-сессию, а внешний клиент не сможет обнаружить подмену (то есть, нет никакой истории – знания предыдущих сессий, знания корреспондента; нет никаких цепочек отпечатков, ничего подобного тут нет – схема слишком простая); в-третьих, вовсе не обязательно передавать сам секретный ключ – достаточно передать интерфейс расшифрования данных (или интерфейс подписывания ответа, в чуть более сложных схемах). Причём, этот интерфейс можно сделать защищённым и скрытым, так что на “подлинном сервере” не будет сохраняться ничего подозрительного: даже IP-адрес источника, видимый в сторону этого сервера, может соответствовать IP-адресу реального клиента – не забывайте, что IP-адрес – это всего лишь индекс, номер из нескольких байтов внутри пакета, а записать в пакет – можно что угодно, подходящее по формату, главное, сделать это аккуратно (что не так уж сложно: достаточно хорошо понимать устройство сетей).



Комментировать »

Нужно ли использовать DNSSEC? Хотелось бы просто написать: да. Но, к сожалению, многолетняя история данной технологии уже обставлена особенностями, которые не позволяют написать просто “да”.

Напомню, кратко, что такое DNSSEC: это технология, позволяющая удостоверять адресную информацию в DNS при помощи механизмов цифровой подписи. Основная особенность DNSSEC в том, что она пристраивает к “классической DNS” схему делегирования по криптографическим ключам, которая позволяет транслировать доверие между зонами, по иерархии. То есть, в “классической DNS” используется делегирование по именам авторитативных серверов: зона уровнем выше содержит имена серверов, которые отвечают за зону уровнем ниже. Например, если у нас есть example.com., то в зоне com. указывается перечень имён серверов (NS), которые администрация зоны com. уполномочила отвечать за example.com.

В DNSSEC нет делегирования по серверам имён (делегирующие ответы со списком NS даже не подписываются), но есть делегирование по криптографическим ключам, которые служат для проверки подписей: зона уровнем выше содержит отпечаток ключа для зоны уровнем ниже; в примере с example.com – в зоне .com размещается отпечаток целевого ключа к зоне example.com, при этом сам целевой ключ – находится только на серверах зоны example.com. Такое размещение ключа – важная особенность DNSSEC, которая несколько меняет логическое отношение зон разного уровня. Отпечаток ключа – это DS-запись, находящаяся в зоне уровнем выше, а сам ключ – это DNSKEY-запись, находящаяся в делегируемой зоне. Отпечаток должен сойтись со значением ключа. Связь “DS –> DNSKEY” – это и есть (безопасное) делегирование в DNSSEC. Это делегирование работает параллельно классическому делегированию по именам NS. (Кстати, с DS-записями связаны самые распространённые ошибки настройки DNSSEC в DNS-зонах.)

Нередко приходится слышать, что, мол, “у нас зона не подписана”, и поэтому “нас DNSSEC не касается”. Это не совсем так. В большинстве случаев, DNSSEC – касается “неподписанных” зон. Дело в том, что в DNSSEC подписывается и отсутствие делегирующих DNSSEC-записей – DS-записей. Иначе смысл данной технологии был бы полностью утрачен, так как можно было бы просто удалить из DNS-ответов DNSSEC-данные и – всё выглядело бы как “неподписанная” зона. Поэтому, если у вас зона example.com, но сама она не подписана, то DNSSEC на вашу зону всё равно распространяется, поскольку подписана зона уровнем выше – .com. То есть, в зоне .com криптографически удостоверен факт того, что в вашей зоне – нет доверенной DNSKEY-записи, а поэтому для вашей зоны удостоверен факт отсуствия DS-записи.

Что это означает? Это означает, что если для example.com радикально сломается DNSSEC в зоне com., то и ваша зона example.com окажется недоступна для валидирующих резолверов (“валидирующий” – это DNS-резолвер, проверяющий DNSSEC-записи). Сейчас очень многие используют валидирующие резолверы, поскольку DNSSEC валидируют крупнейшие провайдеры: Google Public DNS, Cloudflare 1.1.1.1 и др. Штатный опрос DNS начинается с корневого домена и обязательно проходит через зоны первого уровня. Поэтому, к сожалению, даже если у вас домен пятого (условно говоря) уровня внутри небезопасной зоны, для которой DNSSEC нет даже в зоне на два уровня выше, рекурсивный опрос всё равно где-то будет касаться зон с DNSSEC. (Пример, как говорится, “на символах”: 5.4.www.example.com – предположим, что DNSSEC тут нет уже в example.com, но это не помогает, если подписи сломались в .com). Поэтому DNSSEC влияет на вашу зону, даже если у вас в зоне нет DNSSEC-подписей, поскольку на каком-то уровне путь к вашей зоне – подписан, как небезопасный. Естественно, это не распространяется на невалидирующие резолверы: вот им – всё равно.

К сожалению, практическая “ломкость” DNSSEC, регулярно приводящая к авариям больших зон первого уровня, привела и к тому, что складывается нехорошая практика отключения DNSSEC на стороне валидирующих резолверов, если обнаружилась какая-то масштабная проблема. Есть соответствующий документ RFC 7646, который прямо предписывает так делать (кто бы мог подумать? представьте, что для TLS была бы спецификация, предписывающая “всё равно продолжить”, если ошибка “ожидаемая”; да; зато вот в DNSSEC – есть). Формально, речь там идёт о том, что оператор DNS-резолвера должен убедиться, что “эта нога – у кого надо нога!” (то есть, что сломалось там, где положено ломаться), и только потом отключать валидацию для конкретного поддерева (подмножества) DNS-зон. И, судя по сообщениям Cloudflare, именно так этот провайдер и поступил, когда поломались подписи в зоне первого уровня .de (крупнейший национальный домен).

Проблема тут в том, что практика типа “сигнализация опять зашумела – просто отключи”, поднятая на уровень спецификаций, не очень-то помогает развитию и внедрению криптографических технологий. Представьте, что через сервис Cloudflare домены большой популярной зоны резолвятся, а через небольшой корпоративный резолвер – нет, не резолвятся. Почему? Потому что Cloudflare смогли переговорить с большим оператором большой популярной зоны по своим каналам, и отключили DNSSEC у себя, решив, что “это не атака” (почему? как? нет ответа). А администратор небольшого корпоративного резолвера – не имеет возможности проверить все детали. Собственно, на следующем шаге и администратор небольшого резолвера просто отключает DNSSEC совсем, для всего, чтобы “не морочить голову себе и пользователям”. Ну и кому такая криптография нужна? Риторический вопрос. Тем более, когда есть TLS.

Что касается TLS и DNSSEC. Да, эти технологии задают совсем разные поверхности атаки: если DNSSEC работает, и работает верно, то, при обнаружении подмены адресной информации, до применения TLS даже не дойдёт дело. Но это только если DNSSEC работает. А если эту технологию отключают крупнейшие провайдеры, чтобы “пользователи могли заходить на сайты” в сломанной зоне, то, как бы, рассуждать про поверхности атаки становится сильно сложнее. Заметьте, что при этом нет спецификаций, предписывающих “отключать валидацию TLS-сертификатов по команде с сервера обновлений браузера”, если вдруг у крупного удостоверяющего центра “сломались ключи”. Естественно, у TLS другая архитектура и поломка “корневого оператора” пока что не может так повлиять на доступность, как в случае с DNS. Хотя, тут слова “пока что” я использовал неспроста: как только глобальная инфраструктура TLS для HTTPS перейдёт на сертификаты с хеш-деревьями, без подписей, то сразу возникнет похожая на DNS ситуация с раздачей промежуточных “аретфактов доверия”. Пойдёт ли тогда та же корпорация Google, как поставщик наиболее распространённых веб-браузеров, по схеме под условным названием “исправленному верить”? Не факт, но, как говорится, посмотрим: времена сейчас новые, так что всякое может приключиться, поди как и аутентификацию узлов в TLS избирательно отключат.

Вернёмся к DNSSEC в доменной зоне. Распространено ещё такое мнение, что наличие DNSSEC ухудшает работу электронной почты, если домен является почтовым. В отличие от мнения про “независимость от DNSSEC”, это мнение гораздо более обосновано и граздо ближе к реальности. Действительно, такое возможно. Это, буквально, ещё один “неожиданный эффект” DNS. Может показаться, что хотя бы при отправке почты DNSSEC не влияет: ну, какая разница, что там в DNS-зоне, если при отправке почты наш почтовик идёт на внешний сервер напрямую? А имена и адреса внешнего сервера – они в другой зоне. Это так, но вот только сейчас принимающий сервер, в подавляющем большинстве случаев, будет запрашивать записи из зоны отправителя. Например, SPF-записи, или TXT-записи с ключами DKIM, или ещё что-то. Если в зоне DNSSEC не работает, а принимающий почту сервер валидирует DNS-ответы, то он не сможет все эти записи получить. Ну а с доставкой почты в подписанный домен – должно быть очевидно: уже извлечение MX-записи затрагивает DNSSEC. Так что, да, на почту DNSSEC влияет. И в качестве бонуса тут идёт описанный выше момент: от DNSSEC всё равно не отделаться полностью, а отсутствие DNSSEC в собственной зоне лишь уменьшает шансы эту DNSSEC собственноручно же сломать, и “почётная” обязанность отламывания подписей – передаётся выше, по делегированию.

Тем не менее, DNSSEC сейчас поддерживается распространённым ПО “из коробки”. Внедрить DNSSEC в собственной зоне для тестирования можно без автоматического размещения DS-записей, это означает, что ключи и подписи в зоне будут, можно проверить их “сходимость”, но без привязки в глобальную цепочку. Главное – не перепутать шаги: DS-записи вообще нельзя размещать в вышестоящей зоне до того, как целевая зона корректно подписана. Ну и если, после неудачного опыта, отказались от DNSSEC в DNS-зоне, то нужно не забыть корректно почистить DS-записи. Как и раньше, забытые DS-записи – самая распространённая ошибка.

Итак, нужно ли использовать DNSSEC? Нужно. Однако прежде необходимо определить – можно ли.



Комментировать »

Сейчас много околотехнических обсуждений по теме методов определения того, пришёл ли веб-клиент на некий крупный веб-сервис “c VPN или без VPN”. Оставим за скобками набравшую сейчас популярность трактовку того, что такое VPN – термин обобщили до невозможности. Но в технической стороне процесса “определения” сетевых настроек есть пара занятных моментов, которые как-то пропускают.

Момент первый: измерение параметров времени для TCP-соединения. Например, к некоторому веб-сервису подключается клиент, скажем, браузер. При помощи выполнения некоторых скриптов не очень трудно померить время “сетевой задержки” между средой веб-страниц этого браузера и серверной средой. То есть, это будет время доставки запроса, измеренное от контекста DOM в браузере до веб-сервера. Предположим, это 50 ms. Но это всё по HTTP, а HTTP-соединение использует TCP.

TCP-соединение устанавливается не с браузером, а с логически ближайшим к серверному сетевому стеку узлом. Это может быть клиентский компьютер, то есть, ОС на этом компьютере. Но может быть и выходной узел, выполняющий трансляцию адресов, например. Обычно – именно так и есть: клиентский компьютер редко стоит прямо за маршрутизируемым IP-адресом. Тогда, если измерять и задержку в браузере, и задержку на серверном TCP, то получится, скажем, что, в рамках одной логической HTTP-сессии, TCP-задержка – 10 ms, а браузерная задержка, до DOM в HTTP-клиенте, – 50 ms. Большая разница – 40 ms. Это означает, что от клиента транслированные запросы ещё где-то там внутри долго ходят, пока доберутся до выходного узла, который к нам по TCP подключился.

Если же выходной TCP-узел примерно совпадает с логическим узлом, где работает клиентский браузер, то разница между двумя задержками будет минимальной, например: 10 ms TCP и 11 ms – браузерная задержка, читай – Javascript в DOM-контексте. Здесь под “примерно совпадает” имеется в виду, что между клиентским компьютером и выходным узлом нет большого сетевого плеча: компьютер и выходной узел стоят технически рядом (простейший случай: локальный пограничный “роутер” с NAT и подключенный к этому “роутеру” по локальному порту компьютер в локальной IP-сети над Ethernet-ом).

Естественно, измерять задержки TCP-стека для веб-сервиса (не веб-сервера) – несколько сложнее, чем померить что-то внутри веб-логики. Для таких измерений нужно зацепить “щупы” прямо в сетевой стек, причём, на входном узле, а не на бэкенде, куда проксируются HTTP-запросы. Очевидно, что на “веб-уровне”, даже для сервера, TCP в таких деталях не виден. Но измерять всё равно можно – это не суперсложная задача, и решение вполне под силу специализированной компании, сохранившей инженерный подход среди своих разработчиков. Мы же тут, как раз, речь ведём о крупных профильных компаниях, где, вполне возможно, понимающие инженеры есть – верно?

Понятно, что сравнение задержек по времени на уровне браузерного движка с задержками на уровне TCP-стека не является каким-то волшебным зеркалом, которое всё показывает: большие задержки бывают при использовании радиоканалов, из-за перегруженного оборудования, из-за потерь пакетов на стороне клиента и т.д. Тем не менее – фактор это достаточно важный, чтобы о нём не забывать.

Момент второй: геометрия сетевых подключений. Если наш гипотетический веб-сервис имеет только одно подключение к общему Интернету, – которое называют “аплинк”, – то этот веб-сервис не может различить пути поступления сетевых пакетов извне в локальную сеть, в рамках какой-то веб-сессии. Ну, как не может – путь для таких пакетов тут один, потому что один “аплинк”. Соответственно, различать нечего. Однако в совсем крупных компаниях, связанных с веб-сервисами, есть несколько подключений, несколько “аплинков”, своя автономная система (или несколько) и свой центр управления сетью, населённый инженерами NOC.

Для опытного инженера NOC, IP-адрес – это сетевой номер, идентификатор, а не “интернет-узел”. С точки зрения физической организаци сети, IP-адрес может указывать куда угодно, а доставка IP-пакетов – просто происходит на другом уровне, чем работает сама вверенная сеть. Поэтому IP-пакеты можно различать по физическим портам коммутаторов или по логическим маршрутам, которые ниже IP и связаны с внутренним устройством сетей оператора (см. MPLS и пр.). Так что для IP-пакетов, с разными адресами источника, и разными правилами, могут использоваться разные порты подключения – эти пакеты, проще говоря, приходят “с разных сторон”, что создаёт внутренний различительный признак. Как ни странно, но этот признак зависит от внешних факторов (где какие фильтры, кто к кому подключен и пр.).

Сюда же попадает и повсеместная путаница, связанная с распределением блоков IP-адресов (префиксов). У всякого IP-префикса есть администратор – автономная система (AS). Это верно. Но ещё есть маршрутизация и BGP. И вот в рамках BGP, технически, быть источником (origin) для данного IP-префикса может любая (подчёркиваю: технически – любая, даже с тестовым номером) автономная система. То есть, административно, префикс принадлежит одной AS, но анонсирует его в Интернет – совсем другая. Или даже несколько других AS – в зависимости от того, какой оператор из какой точки сети смотрит на BGP. Да, для штатного анонсирования префикса должно быть разрешение от его администратора, сейчас это даже подтверждается в RPKI. Да, конкретная ситуация с приёмом IP-пакетов зависит от фильтров, настроенных оператором. Но это только подчёркивает то, что одно дело – административная принадлежность, другое – BGP и маршрутизация в реальности.

BGP – это хорошо, но при чём здесь сетевые задержки? Вот при чём: даже во внешнем BGP, например, не видны многие и многие внутренние каналы между операторами, более того, административная принадлежность префикса не позволяет судить о реальных характеристиках сетевой связности вообще никак; однако разные пути доставки тут всё равно образуются, и разное время доставки, наблюдаемое внутри, вполне себе может служить признаком для классификации.



Комментарии (11) »

Колонка Дмитрия Буркова про реальные принципы построения NAT (это преобразование адресов, массово используемое сейчас для доступа к глобальной Сети), цитата:

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

Рекомендую почитать. Потому что, действительно, о том, какая именно логика соответствует NAT, постоянно забывают.



Комментировать »

Cloudflare пишут об утечке BGP-маршрутов крупного венесуэльского провайдера, случившейся в начале января этого года, непосредственно перед известной операцией США. Краткий вывод: утечки маршрутов происходят постоянно (это факт, не поспорить), поэтому единственное, на что эта утечка может косвенно указывать, так это на то, что были проблемы с сетевым оборудованием, точнее – с его настройками (тут тоже не поспорить – глобальные утечки в BGP вполне себе служат сигналами о том, что именно происходит на сетевом оборудовании провайдера, но для интерпретации сигнала – нужно знать схему сети; соответственно, если вы хорошо подготовленный атакующий, то и утечки маршрутов помогают).



Комментировать »

Spheres in greenПредположим, мы хотим идентифицировать устройство и, возможно, даже пользователя Интернета по некоторым сигнатурам, связанным с использованием различных приложений. Самая простая “сигнатура” подключения – это IP-адрес. Но тут даже слово “сигнатура” используется в кавычках, так как IP-адрес, сам по себе, это всего лишь самый очевидный и банальный “номер узла”: в современном Интернете далеко не всегда IP-адрес даже примерно соответствует реальному подключению. Трансляция адресов (NAT) используется и провайдерами доступа, и за “клиентским подключением”, и в составе VPN, и так далее. IP-адрес принадлежит к наиболее важным идентификаторам в IP-сетях, но точность конкретного адреса для нашей задачи, – то есть, как “сигнатуры”, рассматриваемой в направлении пользовательского, клиентского подключения, – не велика. Более того, задачу даже принято формулировать в других терминах: как определить, что с новым IP-адресом подключается то же самое устройство? (Вынесем тут за скобки пользователя.)

Ниже IP-уровня спуститься тоже можно, но, во-первых, это уже не Интернет, во-вторых, идентификаторы и сигнатуры уровней ниже IP обычно распространяются на малые расстояния (в сетевом смысле): каждый коммутирующий узел “вымывает” часть идентификаторов, так что следы быстро теряются. В качестве рельефного примера можно взять MAC-адрес оконечного устройства – если он и есть, то всё равно уже на следующем “хопе” подключения его не видно. Однако и сквозь низкие уровни коммутации могут “просачиваться” сигнатуры, связанные с последовательностями пакетов. Прежде всего, различные эффекты времени задержки: так, характеристики доставки серий, соответствующих потокам видеотрансляции (например), могут зависеть от характеристик канала передачи, которые находятся ниже IP – радиоканалы отличаются от проводного подключения “последней мили”, бывает специфический “шейпинг” потоков данных, и так далее, и тому подобное. На конкретное устройство, конечно, подобные характеристики “последней мили” не указывают, однако могут существенно уменьшить количество возможных вариантов: а если удалось составить цепочку различных подключений, то тут уже и пользователей можно начать различать, как ни странно.

На уровне IP есть источники сигнатур, сходные по происхождению с только что описанными. Это те же сдвиги времени доставки (в том числе, можно подсчитывать скорость изменения задержек – брать производную), а кроме того, можно предположить, что и в заголовках пакетов присутствуют сочетания значений (ID, опции и пр.), которые связаны с конкретным источником пакета, но, опять же, всё, что есть в заголовке, размывается в ходе передачи пакетов промежуточными узлами (и это даже без учёта NAT-ов).

TCP предоставляет некоторое количество новых сигналов: что-то можно специально добавить, да ещё и на разных этапах установления соединения (см. SYN-куки и т.д.), при этом сам процесс установления сессии позволяет выделить дополнительные особенности – сдвиги по меткам времени, характеристики из заголовков, взятые по разным сигналам. Отдельный новый базис TCP – это номера портов, а точнее, их изменение: тут экзотические методы использования, – вроде port knocking, – вообще могут позволить узнать конкретный источник сессии без всякой привязки к IP-адресу или к параметрам протоколов более высоких уровней.

И всё же, перечисленные варианты не так уж информативны, особенно, если речь только о пассивном анализе трафика. Дополнительную информацию приносят данные из более высоких уровней. Клиентские TLS-сертификаты, сертификаты электронной подписи, криптографические ключи, передаваемые в рамках разных протоколов уровня приложений – могут достаточно точно указывать на пользователя (и могут идентифицировать устройство). DNS не так трудно снабдить индивидуальными метками: а неконтролируемые и прямые запросы в DNS делают даже те приложения, которые позиционируются как “защищённые”. Эти источники сигнатур вообще не зависят от транспортных протоколов, то есть переходят от канала к каналу без изменений. Главное – их увидеть. А про куки-файлы, HTTP-запросы, конечно, можно и не напоминать.



Комментировать »

Метаинформация о свойствах сетевого трафика – это сведения, которые можно извлечь при помощи наблюдения за “поверхностными” особенностями того или иного протокола обмена данными. Самый простой пример – начальное установление соединения: очевидно, что если два узла обменялись начальными пакетами данных, соответствующих схеме некоторого протокола, то, как минимум, в качестве кусочка метаинформации можно записать адреса узлов, тип протокола и метку времени соединения. В моём описании протокола TLS есть небольшой раздел, посвящённый метаинформации о TLS-соединениях. Естественно, принцип подходит не только к TLS, да и далеко не только к IP-сетям или сетям передачи данных вообще. Однако в случае интернет-трафика возникают интересные возможности автоматического обогащения подобных данных.

Даже самые простые сведения, полученные по косвенным сигналам, становятся весьма полезными, если рассматривать последовательности событий. Предположим, что исследуется трафик некоторого центрального сервиса обмена сообщениями через Интернет – приложения-мессенджера. Это приложение работает через центральный сервер, который служит концентратором, пересылающим сообщения между пользователями. Естественно, полезное содержание сообщений зашифровано, возможно, даже с ключами в режиме “точка-точка”. Казалось бы, в такой конфигурации пассивным анализом трафика нельзя обнаружить, какие два пользователя обмениваются сообщениями между собой, потому что все пользователи соединяются с сервером, но не друг с другом напрямую, да и трафик зашифрован.

Пусть система инспекции трафика записывает метки времени, которые соответствуют пакетам, переданным клиентским устройством в сторону сервера приложений и пакетам, полученным клиентским устройством от сервера, а кроме того – записывается длина пакета. Тогда некоторому сеансу обмена несколькими (это важно) сообщениями в мессенджере (переписка между пользователями), со стороны одного клиента, соответствует последовательность из интервалов времени между метками передачи пакетов данных, а также размеров этих пакетов. Как ни странно, если не принимаются дополнительные меры маскировки трафика, такая последовательность, с увеличением длины, не только быстро станет уникальной, но её можно сопоставить с последовательностью другого клиента, который выступает в роли второй стороны переписки: отправленные сервером в его сторону сообщения будут приходить в примерно таком же наборе интервалов и размеров пакетов. То есть, можно определить, кто с кем переписывался (конечно, с точностью до сетевых реквизитов, но это часто телефонный номер, со всеми его атрибутами).

Естественно, тут вынесены за скобки многие важные аспекты: стабильность соединения с сервером (так, если был сбой, то много сообщений придёт одним кортежем – удивительно, но сбой можно было вызвать специально, впрочем, это уже активная атака), параллельный обмен сообщениями со многими пользователями, различные способы формирования пакетов разными версиями приложений клиента и сервера (вовсе не обязательно, что размер пакета строго коррелирует с сообщением, особенно, после того, как сообщение было преобразовано сервером; однако, на минуточку, сочетания разных версий приложений дают дополнительную сигнатуру) и так далее.

Основной момент в том, что если сообщения пишет настоящий пользователь-человек, и пишет их непосредственно в приложение, в диалоговом режиме, то интервалы времени и количество байтов полезной нагрузки, как отпечаток, скорее всего будут транслироваться и в “выходящий канал”, с другой стороны от сервера. И если трафик виден с обоих сторон (входящий и исходящий относительно сервера), то можно попытаться извлечь метаинформацию о том, кто с кем переписывался. Нужно учитывать, что нередко пересылают файлы изображений (сейчас принято то и дело отправлять скриншоты и тому подобные картинки), а это не только увеличивает объёмы трафика, но и создаёт новые сигнатуры, поскольку для доставки изображений мессенджер может использовать дополнительные серверы и дополнительные функции уровня протокола.

Вообще, последовательности (цепочки) некоторых событий, связанных с деятельностью персоны и возникающие в результате применения того или иного отношения порядка – часто уникальны. Отношение порядка тут может быть связано и со временем (открыл приложение “Блокнот”, а через две секунды – приложение “Калькулятор”), и с пространством (проехал базовую станцию “А”, потом базовую станцию “Д” и так далее), а может быть и ещё каким-то – главное, чтобы метки-события выстраивались друг за другом. Потому что тех, кто бывал и в магазине “Мебель”, и в магазине “Стекло”, и в магазине “Богатырь” – гораздо больше, чем тех, кто посетил эти три магазина строго в таком порядке: “Стекло” – “Мебель” – “Богатырь”. Что уж говорить про интервалы времени, взятые “между” магазинами.

Я ранее уже писал на dxdt.ru про идентификацию по цепочкам: например, про применение для деанонимизации мобильных телефонов (2010 год), про идентификацию людей по географическим координатам (2009 год) и не только.



Комментировать »

В статье из 2019 года, посвящённой блокировкам и блокированию протоколов в Интернете, я писал вот что:

Среди перспектив развития систем контроля трафика (именно контроля) можно отметить пропуск только авторизованного трафика. Конечно, такой вариант пока кажется фантастикой. Авторизация трафика — это развитие схемы с белыми списками. В этом случае доступ по спискам IP-адресов и имен не ограничивается, но промежуточные узлы пропускают только трафик, который содержит специальные криптографические маркеры, подтверждающие его легитимность.

Это момент, про который постоянно забывают, когда рассуждают, например, об использовании приложений с криптографически защищёнными каналами типа “точка-точка” (E2E). Схему можно реализовать в “пассивном” режиме: выдали ключи – и на уровне оконечных узлов, на уровне промежуточных узлов, а также на уровне приложений, в трафик добавляются метки. Но с этим же направлением, – авторизация трафика, – связаны и интерактивные решения, реализуемые на уровне прикладных “сокетов”.

Криптография, а точнее – криптология, работает, к сожалению, в обе стороны. Так, на первый взгляд, может показаться, что обеспечение строгой конфиденциальности подразумевает невозможность проверки содержания трафика на соответствие политикам блокировок: как же промежуточный узел будет инспектировать зашифрованный трафик, если раскрытие этого трафика нарушит конфиденциальность?

Но, оказывается, для внедрения политик блокирования не нужно нарушать конфиденциальность и раскрывать трафик. Пока, впрочем, больше в теории. Дело в том, что клиентское ПО может быть так устроено, что вместе с трафиком оно будет предоставлять промежуточному узлу доказательство, что внутри зашифрованного трафика нет “ничего запретного”, предположим, не содержится подстрок (ключевых слов) по заданному словарю. Доказательство предоставляется без раскрытия самого трафика. Если доказательство есть – трафик не блокируется, если нет доказательства – блокируется (тут возможны варианты как с блокировкой ответов постфактум, так и другие, это детали).

Используется некоторый вариант схем с нулевым разглашением, но “нулевое разглашение” тут относится только к трафику за вычетом признака наличия “запрещённых параметров”. Очевидно, что предоставленное криптографическое доказательство отсутствия каких-то свойств защищённого трафика всё же приносит новую информацию о соединении на промежуточный узел, однако можно так устроить протокол, что о прочих свойствах трафика этот промежуточный узел ничего нового не узнает (но “нулевое разглашение”, конечно, лучше тут ставить в кавычки – впрочем, на практике это беспокоит далеко не всех). Выглядит контринтуитивно, требует (пока что) много вычислительных ресурсов, но реализовать, тем не менее, можно: основной “маркетинговый момент” в том, что, как бы, не вносится никаких “бэкдоров” – сохраняется защита на уровне “точка-точка”, но каждый сеанс сопровождается работой “разрешающего” протокола, по которому клиент взаимодействует с ближайшим к нему промежуточным устройством и формирует нужные для пропуска трафика вычислительные доказательства.

Схема может выглядеть как получение от промежуточного узла закодированных специальным образом алгоритмических правил (например, поиск соответствия подстрок), которые клиент будет исполнять на своей стороне для содержания трафика, а криптографический результат выполнения, снабжённый строгой привязкой к соответствующим пакетам зашифрованного трафика, будет отправлять на авторизующий пропуск трафика узел. Это, естественно, не просто некоторый примитивный сигнал “нет запрещённых данных”, понятно, что такой сигнал легко подделать. Напротив, речь о том, что клиент должен выполнить защищённые “арифметические операции”, в точном соответствии с предложенным кодом, чтобы получившийся ответ проходил проверку.

Пример технического использования: предоставление гарантии отсутствия каких-то дополнительных (“запретных”) параметров в защищённой части сообщений “TLS-хендшейка” (читай: ECH и пр.). Но, конечно, схема пригодна и для других применений. Естественно, резко увеличивается нагрузка на оборудование и падает эффективность доставки пакетов (“замедляется скорость”), от этого аспекта уйти не удастся: трафик без “авторизационных изысков” будет ходить несравнимо быстрее. Ну так и программы в персональных компьютерах раньше быстрее стартовали: введение новых уровней абстракции для повышения безопасности в данной области не обладает запретительным эффектом, тем более, когда речь идёт о блокировании доступа “в этих ваших интернетах”.



Комментировать »

Ещё из области наблюдения над логами веб-сервера dxdt.ru: очень много записей со статусом 408 Request Timeout со стороны некоторых IP-адресов. Судя по всему, большинство из этих записей соответствует известной, в общем-то, ситуации: обычный клиент открывает TLS-сокет, но никаких HTTP-запросов не отправляет, поскольку сокет, например, был открыт заранее, на тот случай, если потребуется, однако – не потребовался; или просто соединение “зависло” где-то на промежуточных этапах доставки (скажем, не существует метода надёжно определить, что TCP-соединение фактически не завершено). В общем, раньше такое попадалось только на нагруженных веб-серверах, где большой трафик. Занятно, что большинство из таких “зависающих и пустых” сокетов от одного адреса связаны с мобильными устройствами (впрочем, предсказуемо).



Комментарии (2) »