Примечание автора: упомянутые в этой статье атаки неприменимы к текущим версиям I2P.

As a self-organizing peer-to-peer network, I2P relies on the routers participating in the network to have a way to share information about what is on the network and how to reach it. I2P routers achieve this information sharing using the NetDB, a DHT based on Kademlia but modified to work for I2P. The NetDB needs to share two main kinds of entries, “RouterInfos” which peers will use to communicate with other routers directly, and “LeaseSets” which other peers will use to communicate with I2P clients through anonymous tunnels. Routers are frequently commmunicating NetDB entries with eachother, either by sending the information to a router or client, or requesting information from a router or client. This means that the entries can arrive directly or indirectly, anonymously or non-anonymously, depending on the needs of the network and the capabilities of the client. However, as an anonymizing network, it is also important that it remain impossible for information sent anonymously to be requested back non-anonymously. It is also important and for information sent non-anonymously to be impossible to request back anonymously. If it becomes possible for either of those situations to occur, then a linking attack may be carried out which allows an attacker to determine if a clients and routers are sharing a common view of the NetDB. If it can be reliably determined that the 2 targets share a common view of the NetDB, then there’s a very good chance they are on the same router, weakening the target’s anonymity drastically. Because there are so few anonymizing networks, and I2P is the only one where the routing table is shared via the operation of a DHT, this class of attack is all but unique to I2P and its resolution is important to I2P’s success.

Рассмотрим следующий сценарий: существует I2P router, на котором работает I2P клиент. Этот router публикует RouterInfo, а I2P клиент публикует свой LeaseSet. Поскольку оба они опубликованы в NetDB, другие I2P routers могут обращаться к NetDB, чтобы узнать, как с ними взаимодействовать. Это нормально и необходимо для работы оверлейной сети типа, реализованного в I2P. Злоумышленник запускает I2P router и запрашивает в NetDB целевой RouterInfo и целевой LeaseSet. Затем он формирует новый LeaseSet, уникальный и, возможно, даже поддельный, и отправляет его через tunnel к LeaseSet клиента, на которого направлена атака. Клиент обрабатывает сформированный LeaseSet и добавляет его в свою NetDB. Затем злоумышленник напрямую запрашивает этот созданный LeaseSet у router, используя RouterInfo, полученный из NetDB. Если созданный LeaseSet возвращается в ответ, злоумышленник может сделать вывод, что целевой клиент и целевой router имеют одинаковое представление о NetDB.

Это простой пример класса атак на деанонимизацию в NetDB, который опирается на добавление записи в NetDB другого пользователя под одной идентичностью, а затем на последующий запрос этой записи под другой идентичностью. В данном случае рассматриваемые идентичности — “router” и “client”. Однако связывание между клиентами, которое менее вредно, также возможно в некоторых архитектурах. Проектирование защиты от этого класса атак требует обеспечить router возможность определять, безопасно ли сообщать какую-либо информацию потенциальной идентичности.

Итак, как нам следует подходить к этой проблеме? По сути, то, с чем мы здесь имеем дело, связано со связываемостью различных “идентичностей” в сети. Возможность установления связи возникает потому, что все эти “идентичности” разделяют общую структуру данных, которая “помнит”, с кем она общалась и кто общался с ней. Она также “помнит”, как происходила эта коммуникация.

На мгновение представим, что мы злоумышленники. Представьте, что вы пытаетесь установить личность мастера перевоплощения. Вы точно знаете, что видели его настоящее лицо, и вы уверены, что регулярно общаетесь с одной из его масок. Как бы вы установили, что личность под маской и настоящая личность принадлежат одному и тому же человеку? Я мог бы рассказать человеку под маской секрет. Если человек без маски ответит, воспользовавшись этим секретом, то я смогу определить, что человек без маски знает этот секрет. При условии, что человек под маской никому больше этот секрет не сообщил, я могу считать, что человек без маски и человек под маской — на самом деле одно и то же лицо. Сколько бы масок ни носил мастер перевоплощения, ум у него один.

Чтобы успешно защищать личности клиентов I2P, I2P должно уметь маскироваться лучше, чем описано выше. Оно должно уметь “помнить” несколько важных сведений о том, как оно участвовало в NetDB, и соответствующим образом реагировать на основе этих сведений. Оно должно уметь вспоминать:

  • Whether a NetDB Entry was received directly, or received down a client tunnel
  • Whether a NetDB Entry was sent by a peer in response to our lookup, or sent unsolicited
  • Which NetDB Entry was received down Which client Tunnel
  • Multiple versions of the same entry for different client tunnels

С точки зрения структуры, наиболее понятный и надёжный способ обработать этот шаблон — использовать “Sub-DB” (вспомогательная база данных). Sub-DB — это миниатюрные NetDB, которые помогают NetDB организовывать записи, не теряя учёта. Каждый клиент получает свою собственную Sub-DB для собственного использования, а сам router получает полноценную NetDB. Используя Sub-DB, мы даём нашему мастеру маскировки картотеку секретов, упорядоченную по тому, кто поделился с ним этими секретами. Когда запрос отправляется клиенту, выполняется поиск только тех записей, которые были переданы этому клиенту; а когда запрос отправляется к router, используется только общая для router NetDB. Делая всё таким образом, мы устраняем не только простейшую форму атаки, но и подрываем эффективность всего класса атак.