В прошлой части мы рассказывали, что такое Freenet и браузер Tor и что с их помощью можно делать в темном интернете.
В новой статье обсудим, что такое сеть I2P, как она работает и какие задачи решает.
В других статьях серии:
I2P — еще одна анонимная одноранговая сеть, которая работает поверх обычного интернета. Она децентрализована, поэтому в ней нет серверов DNS, а их место занимают автоматически обновляемые «адресные книги». Роль адресов играют криптографические ключи, которые не выдают реальные компьютеры. Каждый пользователь проекта получает свой ключ, который невозможно отследить.
Подробнее о том, как устроены одноранговые сети, рассказывали в статье «Темный интернет, часть 1: что такое Dark Web и зачем его используют».
Сама сеть появилась в 2003 году в качестве opensource проекта. Сейчас это также полностью открытый проект, который развивают и поддерживают энтузиасты со всего мира.
В I2P все запросы зашифровываются на стороне отправителя и расшифровываются на стороне получателя с помощью алгоритмов NTCP2 и SSU. Это крипто-аналоги TCP и UDP, которые шифруют всю информацию, передаваемую роутеру.
Поэтому никто не может перехватить запросы. Даже промежуточный узел. Он не узнает, что произошло с запросом после него: обработал ли его следующий запрос или передал куда-то дальше.
I2P состоит из:
Роутеры, транзитные узлы — часть цепочки серверов, которые формируют туннель для запроса. При этом никто не знает, какой запрос и в каком туннеле идет. Еще одна особенность — пользователь сам определяет точку назначения запроса, длину туннелей, а также их количество.
Туннель можно представить в виде обычного грузовика, который проезжает несколько блокпостов. Он не останавливается ни на одном из них и поэтому никто не знает, куда едет грузовик и что хранится в его кузове. При этом на машину могут смотреть все, а остановить — только блокпост-получатель.

Конечные точки устроены сложнее. По сути, конечные точки — что-то вроде «сервера» для обычной сети. Т.е. к ней идут запросы как к роутеру. Но про то, что конкретная точка сети конечная, не знает никто. Также никто не знает, кому и какие данные предназначаются. Только конечная точка назначения может понять, что данные для нее. Поэтому вычислить нахождение «точки» нельзя.
Чтобы разобраться, введем два понятия — лизсет (LeaseSet) и флудфил (Floodfill или Routerinfo).
Лизсет — совокупность информации в I2P, которая содержит данные о входных туннелях, криптографических ключах и конечном адресе.
Флудфил — роутер, который выступает в роли справочной книги, хранит лизсеты и знает нужные места, которые ищет пользователь. А если не знает — перенаправляет в другую справочную службу.
Когда пользователь ищет что-то в I2P — запрашивает определенный лизсет у случайного флудфила.
Если флудфил не знает запрошенного адреса, дает адрес трех других флудфилов и запрос идет к ним. А те, в свою очередь, проверяют лизсеты в своей базе. И так до тех пор, пока нужный адрес не будет найден.

Нужный флудфил выбирается на основе целевого адреса и текущей даты. Из этой информации выводится хеш SHA256 — получаются данные длинной с обычный адрес.
Потом система ищет флудфил в локальной базе роутера и выбирает тот, который при операции «ИСКЛЮЧАЮЩЕЕ ИЛИ» с блоком «целевой адрес + дата» даст наименьшее число.
По сути, это функция обращения к флудфилу, которая помогает найти нужный адрес. Вот только адрес генерируется случайный, поэтому флудфил сообщает адреса трех соседей, к которым мы обращаемся в поиске нужного адреса. А сам алгоритм выбора флудфила с датой нужен для рандомизации обращений. Так каждый запрос на новый адрес пройдет через новый флудфил и они будут меняться каждый день.
Активный узел сети имеет в своей базе в среднем 5000 активных роутеров и принимает сотни, а то и тысячи абсолютно случайных транзитных подключений.
А в качестве адресов конечных точек в I2P работают идентификаторы, которые выводятся из открытого ключа подписи. Хеш-сумма вычисляет уникальную строку определенной длины и в конце добавляет псевдодомен «.b32.i2p» — так получается привычный внутрисетевой адрес.
Дальше к внутрисетевому адресу привязывается обычный читаемый домен.
Туннели формируют путь через выбранный список маршрутизаторов. Они защищены многоуровневым шифрованием, а каждый из маршрутизаторов на пути может расшифровать только один слой. Расшифрованная информация содержит IP следующего маршрутизатора и следующий уровень зашифрованной информации, которая уйдет к следующему роутеру.
Информация по туннелям идет в одну сторону и каждый туннель имеет начальную и конечную точки. Чтобы получить обратное сообщение, требуется еще один туннель.
Работают туннели так: сначала строится исходящий туннель, который состоит из нескольких узлов. Каждый узел расшифровывает часть информации, в которой содержатся инструкции. Они сообщают, на какой узел передавать информацию дальше.
В последней точке исходящего туннеля узел расшифровывает часть информации в которой сказано о завершении построения цепочки.
А так как все цепочки однонаправлены, последнему узлу сообщается маршрут входного туннеля. В результате информация возвращается к пользователю.

В зависимости от типа туннеля — входящего или исходящего — последний узел называется Endpoint или Gateway. Endpoint означает конечную точку, а Gateway — входные ворота. Задача endpoint — собрать информацию по частям в более большой пакет данных и переслать через Gateway нужному пользователю.

Например, Богдан передает данные Ибрагиму. Для передачи данных Богдан строит выходной тоннель из 4 узлов. А Ибрагим строит входной на 5 узлов. Когда Богдан отправляет информацию, она сначала идет по выходному тоннелю к Endpoint через его 4 узла, а потом оттуда выходит через Gateway и идет через 5 входных узлов Ибрагима.
Если Ибрагим решит ответить, то построится новый путь. А количество узлов будет зависеть от желания Богдана и Ибрагима.
Сама сеть I2P работает при помощи чесночной маршрутизации.
Чесночную маршрутизацию разработали около 20 лет назад. Это метод построения туннелей для передачи информации, в котором несколько сообщений зашифрованы и собраны в один запрос.
Чесночную маршрутизацию называют продвинутой версией луковичной маршрутизации, которую использует сеть Tor. Ее используют, когда нужно отправить зашифрованное сообщение через транзитные узлы, скрыв содержимое от них.
Главное отличие двух методов маршрутизации — в чесночной могут шифроваться одновременно несколько сообщений в разных зубчиках, а в луковичной — одно.

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


В каждый чеснок входит информация для создателя каждого зубчика:
Каждый зубчик опознается по первым байтам информации, которая в нем содержится — это часть хеша его адреса. Когда получатель находит нужный зубчик — расшифровывает содержимое с помощью криптографического ключа. Информацию из других зубчиков расшифровать не получится, потому что она предназначена для других получателей и защищена другими ключами.
Сначала пользователь создает запрос и для него формируются туннели. Запрос идет по входному туннелю через несколько транзитных точек и приходит на конечные точки → запрашивает лизсеты у случайных флудфилов.
Транзитные точки используются для того, чтобы никто не смог отследить местоположение конечной точки.
Вместе с запросом к конечной точке приходят данные входного туннеля. Они нужны для того, чтобы запрос с ответом мог вернуться обратно к пользователю.
Когда запрос приходит на сервер, тот формирует ответ и отправляет его пользователю. Так как туннели в I2P однонаправленные, сервер отправляет ответ по своему исходящему туннелю. А адрес получателя — входной туннель, по которому изначально пришел запрос на сервер.
Вот как это выглядит на общей схеме.

Получилось сложно и запутанно, давайте рассмотрим все пошагово.

Первый шаг — сервер публикует свой лизсет на флудфиле. Для этого он отправляет его по исходящему туннелю.
Второй шаг — пользователь хочет подключиться к этому серверу. Для этого он отправляет запрос по своей исходящему туннелю на флудфил.
Третий шаг— флудфил отправляет ответ на компьютер человека по входящему туннелю пользователя.

Четвертый шаг — пользователь отправляет запрос на сервер. Сначала запрос идет по исходящему туннелю пользователя и попадает во входящий туннель сервера.

Пятый шаг — сервер отвечает пользователю. Он отправляет ответ по исходящему туннелю сервера, который потом попадает во входящий туннель пользователя и оказывается на ПК человека. После этого у человека открывается нужный ресурс.
I2P-сеть построена на двух технологиях: Java и C++. Изначально проект создали на Java и назвали его I2P, а в 2013 году энтузиаст с ником Original создал I2P-клиент на языке C++ и назвал его I2Pd. И он намного лучше предшественника. Объясняем, почему.
I2Pd архитектурно превосходит версию на Java. Дело в том, что I2P содержит массу криптографии, реализовывать которую через Java очень сложно из-за жутких тормозов. Эту проблему пытались решить и добавили в Джава-роутер библиотеки, написанные на языке С. И каждый вызов этих библиотек — большие накладные расходы.
А в C++ вся криптография встроена в сеть и работает нативно — не загружает сеть.
Кроме быстрой работы сети, роутеры в I2Pd потребляют меньше системных ресурсов. Потому что программа на C++ напрямую взаимодействует с системой. А в Java-версии все работает внутри виртуальной машины, которая выступает в роли прослойки между операционной системой и программным обеспечением.
Еще одно преимущество I2Pd — быстрая скорость. В обычном I2P соединение идет через несколько Java-роутеров, из-за чего запрос обрабатывается дольше и скорость интернета не превышает несколько десятков килобит в секунду. В C++ запросы обрабатываются быстрее, поэтому скорость соединения может доходить до одного мегабита в секунду.
Одно из главных отличий двух сетей — Tor является сетью клиентов, а I2P — серверов. Дело в том, что задача Tor — скрыть IP-адрес клиента, который сделал запрос. А задача I2P — скрыть сервер, к которому идет запрос от пользователя. Но есть и другие отличия:
Например, В 2016 году США внесли поправки в правило 41. Это дало право ФБР массово взламывать любое количество компьютеров в любой точке мира, используя один ордер. Поэтому правоохранительные органы получат право взломать узел и узнать вашу конфиденциальную информацию. Такой случай произошел в 2016 году. Тогда ФБР взломали 8 000 компьютеров в 120 странах.