При современных тенденциях, направленных на тотальное прослушивание и сбор всевозможной информации, использование защищённых средств коммуникации как никогда актуально. Шифрование самих передаваемых данных решает проблему лишь частично, поскольку сам факт обмена информацией между участниками важнее его содержания.
В большинстве современных систем будь то электронная почта, ICQ или твиттер, владелец серверов обладает всеми этими данными и может, при необходимости, поделиться ими при получении официального или неофициального запроса об этом. Ниже предлагается проект сети, построенной поверх I2P, в которой владелец использует свои узлы только для обеспечения более стабильной работы и в качестве шлюзов в обычный интернете, имея информации не больше, чем обычные узлы I2P.
Рассмотрим механизмы обеспечения анонимности и конфиденциальности I2P, на которые будем опираться для построения нашей сети:
- Всякий участник I2P представляет собой известный остальной сети маршрутизатор и один или несколько адресов, образующих собственно «невидимую» сеть. Смысл I2P заключается в практической невозможности узнать на каком маршрутизаторе располагается тот или иной адрес
- Адрес I2P представляет собой пару открытых ключей для асимметричного шифрования и подписи. Закрытая пара ключей хранится у владельца и является подтверждением подлинности адреса. Иначе говоря, для авторизации вместо паролей используется этот файл с ключами — аналог электронно-цифровой подписи, может быть, при необходимости, реализовано в виде токена
- Соединения между маршрутизаторами шифруются с использованием AES, сеансовый ключ для которого согласовывается в несколько шагов, включающих в себя проверку подписи адреса узла с целью противостояния атакам типа «man-in-the-middle»
Ранее было показано, что фактически I2P представляет собой двухуровневую конструкцию: маршрутизатор, обеспечивающий взаимодействие с другими маршрутизаторами и работу тоннелей, и протоколы, предназначенные для передачи данных между приложениями. Если протоколы для маршрутизатора представляются тщательно продуманными и эффективными, то прикладные протоколы оставляют желать лучшего и представляют собой нагромождение различных концепции и идей, обусловленных стремлением сделать их максимально универсальными и «прозрачными» для уже существующих приложений. В нашем случае задача существенно упрощается, поскольку мы предполагаем обмен между нашими клиентами, потому можем использовать собственный протокол.
Другая проблема I2P заключается в том, что при попытке обратиться к адресу возникает ошибка «адрес не найден» хотя ресурс с указанным адресом в данный момент находится онлайн. Происходит это вследствие неполноты сетевой базы данных, например, сразу после старта, когда информация о многих маршрутизаторах становится устаревшей и требуется время для ее обновления. А поскольку адреса публикуют свои LeaseSet-ы на «ближайщих» к себе floodfill-ах, то нужных floodfill-ов у клиента в базе еще может просто не быть. Наши клиенты будут использовать вторую сетевую базу данных, содержащую набор узлов, соответствующие нашим серверам и публиковать свои LeaseSet-ы только на этих узлах, что позволит находить LeaseSet-ы друг друга немедленно.
Каждый узел I2P идентифицируется I2P адресом, представляющим собой 2 пары открытых и закрытых ключей, генерируемых в момент создания узла случайным образом, без какой-либо корреляции с IP адресом или местоположением. Центрального источника адресов нет, предполагается, что вероятность совпадения двух случайно сгенерированных адресов пренебрежимо мала. Владельцем узла является тот, у кого имеется файл с полным набором ключей. Два открытых ключа и 3-х байтный сертификат (на настоящий момент всегда нулевой) образуют 387-байтный идентификатор узла, под которым узел становится известен в I2P. Поскольку полный 387-байтный идентификатор довольно неэффективен для сравнения, сортировки и передачи данных, то для обозначения узла используется 32-х байтный SHA-256 хэш от идентификатора, используемый нами для идентификации клиента. Поскольку адрес содержит ключ подписи, то выдавать себя за другого клиента злоумышленнику будет затруднительно, это эквивалентно подбору такой пары ключей, хэш от которой будет соответствовать данному идентификатору. При необходимости клиент может подтвердить, что за I2P адресом скрывается именно он, подписав некий документ своей ключом.
Итак, наша сеть будет состоять из запускаемых на компьютерах клиентов нашей сети и принадлежащим нам серверов. И клиенты и сервера представляют собой полноценные I2P маршрутизаторы, при этом сервера объявлены высокоскоростными и рассчитаны в первую очередь на пропускание транзитного трафика, клиенты же в основном используют собственные тоннели, а транзитный трафик — для маскировки своей активности. Информация о серверах является публичной и известной клиентам, в то же время сервера ничего не знают о клиентах и не имеют возможности отличить клиентов от обычных узлов I2P. Клиенты будут выбирать узлы для тоннелей с тем расчетом, чтобы в тоннеле был ровно один сервер, а остальные узлы принадлежали другим участникам обычной I2P. Даже если все наши сервера окажутся под контролем злоумышленника, то одного узла будет недостаточно, чтобы определить другой конец стандартного для I2P 3-х шагового тоннеля. У пользователя всегда будет возможность увидеть маршруты тоннелей, а также исключать подозрительные узлы.
С другой стороны, один наш сервер в тоннеле необходим для повышения надежности работы тоннелей за счет раннего выявления переставших работать тоннелей. Это одна из фундаментальных проблем I2P: если узел согласился участвовать в транзитном тоннеле, а потом перестал работать (например, пользователь его остановил), то создатель тоннеля ничего об этом не знает и продолжает использовать неработающий тоннель в течение продолжительного времени. В отличие от обычного I2P наши клиенты будут активно посылать в тоннель тестовые сообщения, и как только наш сервер обнаружит отсутствие трафика в тоннеле, то опубликует об этом уведомление для клиентов, позволяя тем самым клиенту прекратить использование такого тоннеля немедленно.
Для обмена данными между нашими клиентами может использоваться I2NP сообщение типа 20 — Data, содержащее произвольные данные, либо же сообщение типа 11 — Garlic. Первоначально в I2P предполагалась следующая схема обмена между адресами: следовало запросить LeaseSet адресата, затем следовало сформировать сообщение типа Garlic, указав адрес в качестве места назначения, зашифровать его публичным ключом шифрования из LeaseSet-а и отправить в соответствующий тоннель. Маршрутизатор, получив такое сообщение, расшифровывал его и далее определял, кому предназначено сообщение. Но в этом случае ключ шифрования должен был быть одинаковым для всех адресов, сидящих на данном маршрутизаторе, что порождало большую «дыру» в безопасности, поэтому в современной реализации I2P у каждого адреса свой набор входящих тоннелей и ключ шифрования, соответственно маршрутизатор может определить адрес и без «чесночного» сообщения. Отказавшись от использования «чесночного» шифрования мы избавляемся еще от одной громоздкой конструкции I2P — AES/ElGamal engine, и можем использование более эффективное для наших задач шифрование, в то же время отправляя сообщения типа 11, чтобы сделать наш трафик неотличимым от обычного I2P.
Клиенты могут обмениваться почтой как между собой внутри сети, так и с внешними адресатами. В первом случае используются непосредственно I2P адреса, и сообщения пересылаются через тоннели из LeaseSet-а адресата. Если клиент не может обнаружить LeaseSet с таким адресом, то будет продолжать делать это в течение определенного времени, после чего сгенерирует сообщение о невозможности доставки.
В втором случае клиенту следует воспользоваться одним из наших серверов в качестве исходящего SMTP сервера. У каждого из наших серверов будет свой адрес, а адресу клиента будет соответствовать назначенное сервером имя пользователя, вместе образующих действительный почтовый адрес. Если клиент желает отправить почтовое сообщение за пределы сети, он должен найти LeaseSet сервера (а он его найдет обязательно), после чего сервер распознает сообщение как почтовое и отправит его адресату как обычный SMTP сервер. Получатель будет знать лишь адреса нашего SMTP сервера, и даже если кто-то захочет узнать у нас, кто скрывается за тем или иным адресом, максимум, что мы сообщить, это I2P адрес, а чей это адрес нам по-прежнему неизвестно. Если сервер получает сообщение извне, то по имени пользователю находит его I2P адреса и далее посылает обычным образом внутри нашей сети.
С целью борьбы со спамом мы введем ограничения на количество сообщений, отправляемых с каждого I2P адреса. Чтобы адрес мог отправлять сообщения наружу он будет должен зарегистрироваться на сервере и узнать свое имя, при этом мы потребуем от него сертификат, получающийся в результате некоторой ресурсоемкой вычислительной задачи, тем самым затруднив массовую генерацию адресов, в то же время не создавая проблем тем, кому нужен всего один или несколько адресов.
Таким образом мы получаем сеть, с одной стороны обеспечивающую анонимность и конфиденциальность передаваемой информации, раскрытие которой невозможно без доступа к компьютеру клиента, а с другой стороны поддерживающую высокий уровень доверия между клиентами с помощью средств криптографической идентификации. Использование собственного протокола и только его между клиентами позволяет существенно упростить реализацию и повысить надежность работы сети, появление же новых высокоскоростных маршрутизаторов улучшит работу и пропускную способность самой I2P.
Хотелось бы услышать мнение уважаемого хабрсообщества по поводу предложенного проекта в целом, и в первую очередь о потенциальных атаках с целью деанонимизации клиентов, а также иные слабых местах и уязвимостях.
Автор: orignal