Абонентский IP – логический адрес пользователя в сети. В малых сетях обычно используются статические адреса, прописанные вручную, а в более массовых – автоматическое назначение через DHCP. За каждый сегмент локальной или глобальной сети отвечает некое лицо или организация, в чьи обязанности входит управление маршрутизацией и контроль IP-адресов.
В большинстве случаев произвольная смена адреса, выданного администратором, не несет абоненту практической пользы, т.к. может отсечь его от сети. Более опытный пользователь знает про коллизию адресов и может этим злоупотребить: назначить своему устройству уже занятый адрес, тем самым лишив изначального хозяина IP-адреса возможности использовать сеть. В обычных сетях за подобным хулиганством бдит администратор, а что происходит в масштабируемых сетях с автоматической маршрутизацией, где контроль за пользователями вовсе отсутствует? Разберем решение этой задачи в Yggdrasil Network – масштабируемой меш-сети с оконечным шифрованием и IPv6-маршрутизацией в сети 200::/7.
Никакого мошенничества
Так как сеть имеет сквозное шифрование от абонента до абонента, очевидно наличие ключей. В Yggdrasil используется шифрование на эллиптических кривых – x25519, подразумевающее связку публичного и приватного ключа. Публичный ключ распространяется свободно, а приватный надежно хранится и служит для расшифровки.
Первый байт «02» адреса IPv6-Yggdrasil является константой, а дальше интереснее: от публичного ключа x25519 берется хеш SHA512, количество лидирующих единиц которого, т.е. битов, установленных в ненулевом состоянии, образует второй байт.
Нулевой бит, следующий за массивом единиц, равно как и первый нулевой бит при отсутствии лидирующих единиц, урезается. Следующие за ним 14 байт образуют оставшуюся часть адреса.
Таким образом получается бесконфликтная сеть, где при масштабировании небольшого сегмента сети, например, при подключении локального сегмента к глобальному через публичный пир, не возникает опасности коллизии адресов. Это обуславливается почти безграничным множеством вероятных ключей x25519, случайно генерируемых при первом запуске Yggdrasil.
Почва для размышлений
Хеш SHA512 составляет 64 байта, в том время как адрес IPv6 даже с учетом константы «02» – всего лишь 16 байт, а изначальный ключ x25519 – 32 байта.
Некоторые пользователи сомневаются в практической пользе такого решения и считают, что вполне реально найти ключи с коллизией адресов, т.к. массив данных ключа увеличивается вдвое, а затем от него берется лишь небольшая часть (примерно 1/5), которая образует IPv6. При всем желании, модель угрозы нахождения разных ключей с одинаковым адресом не была подтверждена практически, что говорит о сложно исчислимом количестве вариаций адресов даже при таком на первый взгляд необычном подходе к их образованию.
Разработчики Yggdrasil постарались усложнить подбор адресов. Первые непрерывно идущие единичные биты создают дополнительный фактор уникальности адреса. Вероятность подобрать последовательность из последних 14 байт IPv6 кажется весьма реалистичной, однако общий успех менее вероятен, т.к. напрямую зависит от количества лидирующих единиц в хеше – 2-го байта. Отсюда выходит понятие «высокого адреса» – адреса с большим значением во втором байте и, следовательно, с более обширным использованием 64-байтного массива от SHA512. Исходя из этого, имеет смысл майнить «высокие адреса» для серьезных проектов.
Желание найти коллизию, особенно при умозрительной вероятности успеха, побудило ни один десяток человек к беспощадному майнингу адресов. Однако, их попытки до сих безуспешны.
amarao
Я не до конца понял модель угроз. От кого и зачем защищаются с использованием секретных (?) ipv6 адресов. Каким образом эти адреса остаются секретными?
pureacetone Автор
Секретными являются приватные ключи, публичные от которых формируют адрес IPv6. Публичный — общеизвестен, приватный ключ — секретный и хранится в тайне, чтобы в сети не появился левый ресурс с вашим адресом. Похожим образом публичные ключи формируют внутрисетевые адреса в Tor и I2P, где потеря ключей также является потерей домена -onion или -i2p.
В статье используется термин "высоких адресов", подбор которых в теории намного сложнее. Их отличие — большое значение во втором байте адреса, который отображает количество лидирующих единиц в хеше от публичного ключа. Количество лидирующих единиц в хеше (в бинарном виде) после подсчета записывается во второй байт адреса, затем они урезаются, а последующие 14 байт хеша формируют оставшуюся часть IPv6-адреса. То есть: чем больше значение второго байта адреса, тем большее количество бит формирует адрес, и в этом его дополнительная надежность.
amarao
Я всё равно не понимаю модель угроз. Почему ip-адрес кто-то будет "перебирать"? Что мне мешает провести сессию с каким-то узлом и присвоить себе его же адрес (который я получил в силу коннективити с этим узлом)? У меня ощущение, что вы слишком тщательно считаете биты и слишком мало описываете модель угроз.
pureacetone Автор
Кажется, вы не совсем знакомы с темой ассиметричного шифрования, в котором существуют две неотъемлемые сущности: открытый ключ и закрытый. Открытым ключом, который распространяется свободно, информация шифруется. Затем информация может быть расшифрована исключительно секретным (приватным) ключом из той же связки.
Устанавливая соединение с кем угодно (в том числе в сетях Тоr и I2P) вы получаете лишь публичный ключ абонента, который формирует его адрес, и которым вы шифруете трафик, отправляемый ему. Но расшифровать массив данных конечный пользователь может только благодаря секретному ключу. В свою очередь воспроизведение секретного ключа из публичного практически (и даже в адекватной теории) невозможно. На этом стоит вся современная криптография.
Отсюда следует, что заполучить чужой адрес можно двумя путями: либо украсть из конфига, получив доступ к серверу, либо смайнить. Однако майнинг здесь чаще всего принимает вселенские масштабы в категориях тысяч и миллионов лет с гугловскими мощностями.
segment
Что такое майнить адрес и зачем это нужно? Публичный ключ на то и публичный. Я тоже не понимаю о какой угрозе здесь идет речь. Что было бы, если вместо этого кодирования адреса использовался просто хеш публичного ключа?
pureacetone Автор
Используется именно хеш публичного ключа. Только он конвертируется в IPv6 для соответствующей логической маршрутизации. Я не утверждаю, что это лучшее решение (даже наоброт, в рамках статьи сею семя сомнения). Именно в силу преобразования хеша в адрес IPv6 (грубо говоря, из 64 байт в 16) происходит сомнительная потеря большой части уникального хеша и коллизия становится более вероятной, т.к. подобрать два ключа с одинаковыми N-байтами в начале хеша проще, чем независимо найти два ключа с одинаковым хешем.
Под майнингом адреса понимается скоростной перебор секретных ключей x25519 и проверка IPv6 от их публичных ключей, выведенных обозначенным выше алгоритмом. Майнингом занимаются либо для поиска "красивого" адреса (например, 200:dead:ded:cafe:babe:...), либо в попытках подобрать уже существующий адрес с целью нарушить обращение к нему (пока практически не удалось никому).
segment
Я не совсем понимаю как обосновано использование схемы кодирования битов, тогда как все-равно адрес меньше чем публичный ключ. Почему такая схема дает меньшую вероятность коллизии? Чем это отличается от просто запихивания части хеша или, например, хеширования в 16 байт?
То есть в майнинге речь идет просто о подборе приватного ключа к публичным? И как проверять есть ли такой узел в сети Ygg, пингом? Расчет на то, что в сети много открытых ключей и какой-то, но попадется?
pureacetone Автор
Адрес майнится по конкретному паттерну: не случайное попадание пальцем в небо, а намеренная атака. Например, я знаю ваш адрес и буду майнить именного его. Если проверять каждый адрес пингом, скорость майнинга станет столь малой, что об успехе даже в теории говорить не придется.
По поводу обоснованности использования той или иной схемы преобразования изначального ключа в конечный IPv6-адрес: я не разработчик Yggdrasil, чтобы адекватно судить и аргументировать причины этого. В статье я изложил лишь очевидную суть, а глубинные замыслы от меня сокрыты.
Я сам задумываюсь над потенциальной возможностью преобразования публичного ключа вовсе без хеша сразу в IPv6, и немного удивляюсь, что это реализовано более замудренно.
segment
Я не до конца понимаю, почему это называется майнингом? Это ведь просто брутфорс? Ну то есть, взять любой сервис, у которого есть открытый публичный ключ, и… майнить? Ждать когда подберется подходящий приватный и можно сломать что-то? Или под майнингом подразумевается не подбор приватного под конкретный публичный ключ, а генерация новой пары публичный-приватный у которой будет такой же хеш?
pureacetone Автор
Второй вариант верен: подразумевается генерация новой пары ключей, у которой часть хеша, образующая IPv6-адрес, будет такой же, как и у целевого адреса, т.е. IPv6 адреса совпадут.
Так как мы поняли, что при формировании адреса используется не весь хеш (64 байта), а только часть (т.к. адрес IPv6 всего 16 байт), видим умозрительную возможность нахождения коллизии: возможно разных ключей, но с одинаковым началом хеша.
Об этой теории как раз заголовок "Почва для размышлений".
segment
Понял, спасибо. Но какой практический смысл такого подбора? Мы ведь не можем вмешаться в работающую сеть с таким адресом, а если можем, то зачем нам вообще что-то подбирать?
pureacetone Автор
Был проведен тест: в сети подняли два узла с одинаковыми ключами. В итоге трафик терялся: шел то на один узел, то на другой. Практического теста с разными ключами, но одинаковыми IPv6-адресами проведено не было, т.к. такие коллизии еще не были найдены. Как минимум, включение в сеть стороннего узла с вашим адресом нарушит вашу работу с сетью. Весьма вероятно, что сделает ее вовсе невозможной на прежнем адресе. Только такой сценарий в настоящее время может быть целью описанной нами атаки с майнингом уже существующего адреса.
amarao
Спасибо за сомнения в моей квалификации.
Я вас попросил ответить какая тут модель угроз, а вы мне рассказываете, что я плохо разбираюсь в асимметричной криптографии.
pureacetone Автор
В вашем вопросе вопиющее непонимание невозможности выведения закрытого ключа из открытого, который вы получаете в ходе сессии с участником сети. Вы меня троллите?
amarao
Я вас спрашиваю, какая у вас модель угроз?
https://en.wikipedia.org/wiki/Threat_model
blind_oracle
Насколько я понимаю у ноды Yggdrasil при начальном установлении соединения нет никакой информации о пире кроме его IPv6 адреса. Биты этого адреса и используются для поиска ноды в простанстве ключей DHT.
А т.к. NodeID длиной 512 бит, а IPv6 только 121 (весь меш живёт в 200::/7, но по факту и того меньше) то два NodeID вполне могут смапиться на один и тот же адрес. И твои пакетики полетят к другому адресату...
pureacetone Автор
Не думал, что такие дебри будут интересны читателям!
Маршрутизация в Yggdrasil происходит по DHT-координатам, которые отталкиваются от реальной топологии, а корень этого DHT-дерева определяется по некоторому критерию ключа подписи EdDSA. Т.е. ключи, образующие IPv6, в логике маршрутизации практически не участвуют.
Если тема интересна, могу оформить всё в небольшую статью.
P.S. Когда ковырялся в дебрях кода Yggdrasil, заметил, что NodeID там называется сырой хеш SHA512 от ключа. От него потом образуется IPv6.
blind_oracle
Я читал whitepaper.
С маршрутизацией это отдельная песня, это следующий этап. Но вот момент когда хост с адресом А хочет отправить пакет хосту с адресом B — ему нужно выяснить NodeID адресата имея только биты IPv6 адреса. И вот тут, как я понимаю, возможны коллизии.
pureacetone Автор
Да, в силу того, что IPv6 является лишь частью NodeID. Как раз эта вероятность описывается, как угроза.
amarao
Ага. Тогда, вроде бы, модель угроз в себя включает противника, пытающегося нарушить связность, за счёт коллизии по IP-адресам. Теперь вопрос интереснее — нарушить связность конкретного узла, или "хоть какого-то"? Потому что если "хоть какого-то", то угроза куда более серьёзная из-за birthday paradox.
pureacetone Автор
Вы будто мстите мне, осыпая занятной терминологией :) При написании статьи я имел ввиду связность конкретного узла.
Однако можно разобрать примерную схему против "хоть кого-то": предварительно сканируем сеть, записываем все обнаруженные IPv6 (которых сейчас в сети ~1500), затем запускаем майнер, и проверяем получаемые адреса на коллизию. Будет медленнее, чем с коротким паттерном поиска, но намного эффективнее пингования каждого полученного адреса.
amarao
Собственно, я это и хотел услышать, когда спрашивал про модель угроз. Криптографически стойкий случайный адрес в сети нужен для защиты от преднамеренных колллизий.
blind_oracle
Тут, как мне кажется, не просто нарушение связности — а полная замена адресата собой. Эдакий аналого старого доброго ARP Spoofing.
pureacetone Автор
Спуфинг — уместный термин. Статья с подобным заголовком и теоритическим разбором угрозы была написана еще минувшим летом на howto.ygg — внутрисетевой wiki Yggdrasil.
http://[300:529f:150c:eafe::6]/doku.php?id=yggdrasil:spoofing_theory
amarao
Если я правильно понимаю комментарии выше, то тут именно коллизия, а не подмена адресата.
Узел А хочет связаться с узлом B. У узла A есть публичный ключ 'b'. Узел A вычисляет адрес из публичного ключа 'b'.
Узел E хочет помешать (или даже имперсонализироваться). Он подбирает такую пару приватного и публичного ключа 'e', что адрес получается такой же.
(дальше я не знаю подробностей работы сети)
Но имперсонализация не получится, потому что A хочет общаться с B, а приватный ключ b (соответствующий ожиданию A) есть только у B.
blind_oracle
Нет у него ничего, откуда ключ?
С точки зрения ОС есть tun/tap интерфейс с твоим IPv6 адресом, полученным хешированием и прочей магией из твоего публичного ключа. И есть маршрут до 200::/7 в этот интерфейс.
Соответственно делая образный
ping 200::<какой-то адрес>
пакет улетает через tun в демона Yggdrasil и он уже каким-то образом должен сопоставить IP получателя с каким-либо из NodeID/TreeID/whatever в DHT сети и потом уже получить публичный ключ чтобы настроить криптографию.И вот на этом этапе коллизия приведёт к тому, что получить можно не тот публичный ключ, на который ты рассчитываешь, а вражины злобной.
Я не претендую на полное понимание, но механизм примерно такой как я понял.
amarao
Узел А хочет связаться с Б, но ничего не знает про "Б".
Мне кажется, это нерешаемая задача. По какому признаку "Б" отличается от "В"?
blind_oracle
Он знает IP-адрес. Который как-то зависит от NodeID, который есть SHA512 от публичного ключа.
Т.е. вся безопасность основана на том, что коллизий нет (хотя это бред), как только коллизия — извините, вы пишите не Алисе, а Бобу, не зная про это.
amarao
Насколько я знаю, yggdrasil использует криптографическую идентификацию узла, т.е. вам надо знать public key пира для общения с ним (иначе, зачем там приватные и публичные ключи?). Если нет, то для обсуждения возможности "самозахвата" IP нужно разбираться с протоколом маршрутизации.
… Потому что прямо сейчас я могу себе на интерфейс вписать любой ipv6-адрес. от захвата Ipv6 адреса гугла меня будет останавливать ближайший bgp-маршрутизатор, который трафик на этот адрес будет отправлять в AS гугла, а не в мою AS.
blind_oracle
Там нет PKI, центральных реестров и нет механизма ручного маппинга IP-адресов в публичные ключи. А автоматический маппинг — это то, о чём я тут пишу уже не первый коммент.
Для шифрования и аутентификации, очевидно.
Аутентификация тупая, как я уже выше писал — проверяем что из данного публичного ключа получается тот IPv6 адрес, на который мы долбимся. В случае коллизии это условие как раз выполняется и мы имеем спуфинг.
Ну, не совсем так, скорее у пира будет просто стоять фильтр на твои анонсы, где разрешены только префиксы твоей AS. В случае Yggrasil ничего такого нет, максимум — можно сделать вайтлист публичных ключей, от которых ты хочешь получать пакеты (
AllowedEncryptionPublicKeys
).amarao
А откуда "данный публичный ключ" берётся? Пир "б" показывает или у "А" эта информация уже есть?
В контексте нормальной маршрутизацией, если я впишу на себя чужой IP, то трафик я слать могу (если нет выходных фильтров), а вот получать не смогу, потому что я (пользователь обычного компьютера) никак не могу убедить маршрутизатор слать мне трафик. Сессий с ними (маршрутизаторами) у меня нет, так что маршрутизатору даже не надо ничего фильтровать, достаточно просто не принимать bgp от кого попало.
А вот как в Y это сделано — вопрос интересный.
blind_oracle
Почитай вайтпейпер, там всё есть.
Если упрощённо:
Просто ты начал говорить про AS, а это обычно подразумевает BGP-пиринг. В случае статики, конечно, всё проще.
amarao
Ага, тогда звучит рисованно. (Я не готов весь whitepaper вычитывать).
Насчёт bgp — я показал, что я (пользователь и админ localhost) могу творить что угодно с любыми адресами, но "интернетам" на это почти пофигу, потому что где-то там маршрутизаторы, которые на своём языке говорят и на мои настройки localhost им глубоко пофигу.