Этот перевод был создан с помощью машинного обучения и может быть не на 100% точным. Просмотреть английскую версию

База данных сети

Понимание распределенной сетевой базы данных I2P (netDb) - специализированной DHT для контактной информации router'ов и поиска назначений

Обзор

netDb I2P представляет собой специализированную распределенную базу данных, содержащую только два типа данных - контактную информацию router’ов (RouterInfos) и контактную информацию назначений (LeaseSets). Каждый фрагмент данных подписывается соответствующей стороной и проверяется любым, кто его использует или сохраняет. Кроме того, данные содержат информацию о жизнеспособности, что позволяет удалять неактуальные записи, заменять старые записи новыми и обеспечивать защиту от определенных классов атак.

netDb распространяется с помощью простой техники под названием “floodfill”, где подмножество всех router’ов, называемых “floodfill router’ами”, поддерживает распределенную базу данных.


RouterInfo

Когда I2P router хочет связаться с другим router, ему необходимо знать некоторые ключевые фрагменты данных - все они объединяются и подписываются router в структуру под названием “RouterInfo”, которая распространяется с SHA256 идентификатора router в качестве ключа. Сама структура содержит:

  • Идентичность router’а (ключ шифрования, ключ подписи и сертификат)
  • Контактные адреса, по которым к нему можно обратиться
  • Когда это было опубликовано
  • Набор произвольных текстовых опций
  • Подпись вышеперечисленного, созданная ключом подписи идентичности

Ожидаемые опции

Следующие текстовые параметры, хотя и не являются строго обязательными, ожидаются присутствующими:

  • caps (Флаги возможностей - используются для указания участия в floodfill, приблизительной пропускной способности и воспринимаемой доступности)
    • D: Средняя перегрузка (с релиза 0.9.58)
    • E: Высокая перегрузка (с релиза 0.9.58)
    • f: Floodfill
    • G: Отклонение всех туннелей (с релиза 0.9.58)
    • H: Скрытый
    • K: Менее 12 КБ/с общей пропускной способности
    • L: 12 - 48 КБ/с общей пропускной способности (по умолчанию)
    • M: 48 - 64 КБ/с общей пропускной способности
    • N: 64 - 128 КБ/с общей пропускной способности
    • O: 128 - 256 КБ/с общей пропускной способности
    • P: 256 - 2000 КБ/с общей пропускной способности (с релиза 0.9.20, см. примечание ниже)
    • R: Доступный
    • U: Недоступный
    • X: Свыше 2000 КБ/с общей пропускной способности (с релиза 0.9.20, см. примечание ниже)

“Общая пропускная способность” == (доля %) * min(входящая пропускная способность, исходящая пропускная способность)

Для совместимости со старыми router’ами, router может публиковать несколько букв пропускной способности, например “PO”.

Примечание: граница между классами пропускной способности P и X может составлять либо 2000, либо 2048 КБ/с, на выбор разработчика.

  • netId = 2 (Базовая совместимость сети - router откажется взаимодействовать с узлом, имеющим другой netId)
  • router.version (Используется для определения совместимости с новыми функциями и сообщениями)

Заметки о возможностях R/U: Router обычно должен публиковать возможность R или U, если только состояние доступности в данный момент неизвестно. R означает, что router напрямую доступен (не требуются introducers, нет firewall) по крайней мере по одному транспортному адресу. U означает, что router НЕ доступен напрямую ни по одному транспортному адресу.

Устаревшие опции: - coreVersion (Никогда не использовался, удален в версии 0.9.24) - stat_uptime = 90m (Не использовался с версии 0.7.9, удален в версии 0.9.24)

Эти значения используются другими router’ами для принятия базовых решений. Должны ли мы подключиться к этому router’у? Должны ли мы попытаться проложить tunnel через этот router? Флаг пропускной способности, в частности, используется только для определения того, соответствует ли router минимальному порогу для маршрутизации tunnel’ей. Выше минимального порога заявленная пропускная способность не используется и не является доверенной нигде в router’е, за исключением отображения в пользовательском интерфейсе и для отладки и анализа сети.

Допустимые номера NetID:

ИспользованиеНомер NetID
Зарезервировано0
Зарезервировано1
Текущая сеть (по умолчанию)2
Зарезервированные будущие сети3 - 15
Форки и тестовые сети16 - 254
Зарезервировано255

Дополнительные опции

Дополнительные текстовые опции включают небольшое количество статистических данных о состоянии router, которые агрегируются такими сайтами, как stats.i2p , для анализа производительности сети и отладки. Эти статистические данные были выбраны для предоставления информации, критически важной для разработчиков, такой как показатели успешности построения tunnel, при этом балансируя потребность в таких данных с побочными эффектами, которые могут возникнуть от раскрытия этой информации. Текущие статистические данные ограничены:

  • Показатели успешного построения, отклонения и таймаутов разведочных туннелей
  • Среднее количество участвующих туннелей за 1 час

Эти параметры являются необязательными, но если они включены, помогают анализировать производительность всей сети. Начиная с API 0.9.58, эта статистика упрощена и стандартизирована следующим образом:

  • Ключи опций имеют вид stat_(имя_статистики).(период_статистики)
  • Значения опций разделяются символом ‘;’
  • Статистики для подсчета событий или нормализованных процентов используют 4-е значение; первые три значения не используются, но должны присутствовать
  • Статистики для средних значений используют 1-е значение, и разделитель ‘;’ не требуется
  • Для равного веса всех router в анализе статистик и для дополнительной анонимности, router должны включать эти статистики только после времени работы в один час или более, и только один раз каждые 16 раз публикации RI.

Пример:

stat_tunnel.buildExploratoryExpire.60m = 0;0;0;53.14
stat_tunnel.buildExploratoryReject.60m = 0;0;0;15.51
stat_tunnel.buildExploratorySuccess.60m = 0;0;0;31.35
stat_tunnel.participatingTunnels.60m = 289.20

Floodfill роутеры могут публиковать дополнительные данные о количестве записей в их сетевой базе данных. Эти данные необязательны, но если они включены, помогают анализировать производительность всей сети.

Следующие два параметра должны быть включены floodfill роутерами в каждый публикуемый RI:

  • netdb.knownLeaseSets
  • netdb.knownRouters

Пример:

netdb.knownLeaseSets = 158
netdb.knownRouters = 11374

Опубликованные данные можно увидеть в пользовательском интерфейсе router, но они не используются и не являются доверенными для любого другого router.

Параметры семейства

Начиная с версии 0.9.24, router могут заявлять, что они являются частью “семьи”, управляемой одним и тем же субъектом. Несколько router из одной семьи не будут использоваться в одном tunnel.

Параметры семейства:

  • family (Имя семейства)
  • family.key Код типа подписи семейства Signing Public Key (в ASCII цифрах), объединенный с ‘:’ и объединенный с Signing Public Key в base 64
  • family.sig Подпись ((имя семейства в UTF-8), объединенное с (32-байтным хешем router)) в base 64

Истечение срока RouterInfo

RouterInfo не имеют установленного времени истечения срока действия. Каждый router может свободно поддерживать свою собственную локальную политику для балансировки между частотой поиска RouterInfo и использованием памяти или дискового пространства. В текущей реализации действуют следующие общие политики:

  • В течение первого часа работы срок действия не истекает, поскольку постоянно хранимые данные могут быть устаревшими.
  • Срок действия не истекает, если имеется 25 или менее RouterInfos.
  • По мере роста количества локальных RouterInfos время истечения срока действия сокращается в попытке поддерживать разумное количество RouterInfos. Время истечения при менее чем 120 роутерах составляет 72 часа, в то время как время истечения при 300 роутерах составляет около 30 часов.
  • RouterInfos, содержащие SSU introducers, истекают примерно через час, поскольку список introducer истекает примерно за это время.
  • Floodfills используют короткое время истечения срока действия (1 час) для всех локальных RouterInfos, поскольку действительные RouterInfos будут часто переопубликовываться в них.

Постоянное хранилище RouterInfo

RouterInfo периодически записываются на диск, чтобы они были доступны после перезапуска.

Может быть желательно постоянно хранить Meta LeaseSet с длительными сроками действия. Это зависит от реализации.

Смотрите также


LeaseSet

Второй тип данных, распространяемых в netDb, это “LeaseSet” - документирующий группу точек входа в туннель (leases) для конкретного клиентского назначения. Каждый из этих leases указывает следующую информацию:

  • Router-шлюз туннеля (указав его идентификатор)
  • ID туннеля на этом router для отправки сообщений (4-байтовое число)
  • Когда истечет срок действия этого туннеля.

Сам leaseSet хранится в netDb под ключом, полученным из SHA256 назначения. Одним исключением являются зашифрованные leaseSet (LS2), начиная с релиза 0.9.38. SHA256 от байта типа (3), за которым следует затемнённый публичный ключ, используется для ключа DHT, а затем ротируется как обычно. См. раздел «Метрика близости Kademlia» ниже.

В дополнение к этим lease, LeaseSet включает:

  • Сам destination (ключ шифрования, ключ подписи и сертификат)

  • Дополнительный открытый ключ шифрования: используется для сквозного шифрования garlic-сообщений

  • Дополнительный открытый ключ подписи: предназначен для отзыва LeaseSet, но в настоящее время не используется.

  • Подпись всех данных LeaseSet для обеспечения того, что destination опубликовал LeaseSet.

  • Спецификация Lease

  • Спецификация LeaseSet

  • Javadoc для Lease

  • Javadoc для LeaseSet

Начиная с релиза 0.9.38, определены три новых типа leaseSet: LeaseSet2, MetaLeaseSet и EncryptedLeaseSet. См. ниже.

Неопубликованные LeaseSets

LeaseSet для назначения, используемого только для исходящих соединений, является неопубликованным. Он никогда не отправляется для публикации на floodfill router. “Клиентские” туннели, такие как те, что используются для веб-браузинга и IRC-клиентов, являются неопубликованными. Серверы по-прежнему смогут отправлять сообщения обратно этим неопубликованным назначениям благодаря сообщениям хранения I2NP .

Отозванные LeaseSet

LeaseSet может быть отозван путем публикации нового LeaseSet с нулевым количеством аренд. Отзывы должны быть подписаны дополнительным ключом подписи в LeaseSet. Отзывы не полностью реализованы, и неясно, имеют ли они какое-либо практическое применение. Это единственное запланированное использование для этого ключа подписи, поэтому в настоящее время он не используется.

LeaseSet2 (LS2)

Начиная с релиза 0.9.38, floodfill поддерживают новую структуру LeaseSet2. Эта структура очень похожа на старую структуру LeaseSet и служит той же цели. Новая структура обеспечивает гибкость, необходимую для поддержки новых типов шифрования, множественных типов шифрования, опций, ключей автономного подписания и других функций. Подробности см. в предложении 123.

Meta LeaseSet (LS2)

Начиная с релиза 0.9.38, floodfill поддерживают новую структуру Meta LeaseSet. Эта структура обеспечивает древовидную структуру в DHT для ссылок на другие LeaseSet. Используя Meta LeaseSet, сайт может реализовать крупные многодомные сервисы, где несколько различных Destination используются для предоставления общего сервиса. Записи в Meta LeaseSet являются Destination или другими Meta LeaseSet и могут иметь долгое время истечения, до 18,2 часов. Используя эту возможность, должно быть возможно запускать сотни или тысячи Destination, размещающих общий сервис. Подробности смотрите в предложении 123.

Зашифрованные LeaseSets (LS1)

Этот раздел описывает старый, небезопасный метод шифрования LeaseSets с использованием фиксированного симметричного ключа. См. ниже версию LS2 для зашифрованных LeaseSets.

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

Зашифрованные LeaseSets (LS2)

Начиная с релиза 0.9.38, floodfill поддерживают новую структуру EncryptedLeaseSet. Destination скрыт, и только слепой публичный ключ и время истечения видны floodfill. Только те, кто имеет полный Destination, могут расшифровать структуру. Структура хранится в DHT по местоположению, основанному на хеше слепого публичного ключа, а не на хеше Destination. Подробности см. в предложении 123.

Истечение leaseSet

Для обычных LeaseSets срок истечения — это время последнего истечения срока его лизов. Для новых структур данных LeaseSet2 срок истечения указан в заголовке. Для LeaseSet2 срок истечения должен соответствовать последнему сроку истечения его лизов. Для EncryptedLeaseSet и MetaLeaseSet срок истечения может варьироваться, и максимальный срок истечения может быть принудительно установлен — это предстоит определить.

Постоянное хранение LeaseSet

Постоянное хранение данных LeaseSet не требуется, поскольку они истекают очень быстро. Однако постоянное хранение данных EncryptedLeaseSet и MetaLeaseSet с длительными сроками истечения может быть целесообразным.

Выбор ключа шифрования (LS2)

LeaseSet2 может содержать несколько ключей шифрования. Ключи расположены в порядке предпочтения сервера, самый предпочтительный идет первым. Поведение клиента по умолчанию заключается в выборе первого ключа с поддерживаемым типом шифрования. Клиенты могут использовать другие алгоритмы выбора на основе поддержки шифрования, относительной производительности и других факторов.


Начальная загрузка

netDb децентрализована, однако вам нужна как минимум одна ссылка на узел, чтобы процесс интеграции подключил вас. Это достигается путем “пересева” вашего router с RouterInfo активного узла - конкретно, путем получения их файла routerInfo-$hash.dat и сохранения его в вашей директории netDb/. Любой может предоставить вам эти файлы - вы даже можете предоставлять их другим, открыв доступ к своей собственной директории netDb. Чтобы упростить процесс, волонтеры публикуют свои директории netDb (или их подмножество) в обычной (не-i2p) сети, а URL этих директорий жестко прописаны в I2P. Когда router запускается впервые, он автоматически загружает данные с одного из этих URL, выбранного случайным образом.


Floodfill

Floodfill netDb представляет собой простой механизм распределённого хранения. Алгоритм хранения прост: отправить данные ближайшему узлу, который объявил себя как floodfill router. Когда узел в floodfill netDb получает запрос на сохранение netDb от узла, не находящегося в floodfill netDb, он отправляет его подмножеству узлов floodfill netDb. Выбираются узлы, которые находятся ближе всего (согласно XOR-метрике ) к определённому ключу.

Определить, кто является частью floodfill netDb, тривиально - это выявляется в опубликованной routerInfo каждого router’а как возможность.

Floodfill не имеют центрального органа управления и не формируют “консенсус” - они только реализуют простое DHT-наложение.

Добровольное участие в качестве Floodfill Router

В отличие от Tor, где серверы каталогов жестко заданы и являются доверенными, и управляются известными организациями, участники набора floodfill-узлов I2P не требуют доверия и изменяются со временем.

Для повышения надежности netDb и минимизации влияния трафика netDb на router, floodfill автоматически включается только на router’ах, настроенных с высокими ограничениями пропускной способности. Router’ы с высокими ограничениями пропускной способности (которые должны быть настроены вручную, поскольку значение по умолчанию намного ниже) предполагаются работающими на соединениях с низкой задержкой и более вероятно доступными 24/7. Текущая минимальная пропускная способность для floodfill router’а составляет 128 КБ/сек.

Кроме того, router должен пройти несколько дополнительных тестов работоспособности (время очереди исходящих сообщений, задержка задач и т.д.) перед автоматическим включением floodfill операций.

При текущих правилах автоматического участия примерно 6% router’ов в сети являются floodfill router’ами.

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

Роли Floodfill Router

Единственные дополнительные сервисы floodfill router по сравнению с обычными роутерами — это принятие данных для хранения в netDb и ответы на запросы к netDb. Поскольку они обычно имеют высокую пропускную способность, они с большей вероятностью участвуют в большом количестве tunnel (то есть выступают в качестве “ретрансляторов” для других), но это не связано напрямую с их сервисами распределённой базы данных.


Метрика близости Kademlia

netDb использует простую метрику XOR в стиле Kademlia для определения близости. Для создания ключа Kademlia вычисляется SHA256 хэш RouterIdentity или Destination. Одним исключением являются Encrypted LeaseSets (LS2), начиная с версии 0.9.38. Для ключа DHT используется SHA256 байта типа (3), за которым следует скрытый публичный ключ, а затем он поворачивается как обычно.

Модификация этого алгоритма выполняется для увеличения стоимости атак Сибиллы . Вместо хеша SHA256 от искомого или хранимого ключа, берется хеш SHA256 от 32-байтового двоичного ключа поиска, к которому добавляется дата UTC, представленная в виде 8-байтовой ASCII строки yyyyMMdd, т.е. SHA256(key + yyyyMMdd). Это называется “routing key” (ключ маршрутизации), и он меняется каждый день в полночь по UTC. Таким образом изменяется только ключ поиска, а не хеши floodfill router’ов. Ежедневная трансформация DHT иногда называется “поворотом пространства ключей” (keyspace rotation), хотя это не является поворотом в строгом смысле.

Routing keys никогда не передаются по сети ни в одном I2NP сообщении, они используются только локально для определения расстояния.


Сегментация сетевой базы данных - Подбазы данных

Традиционно DHT в стиле Kademlia не заботятся о сохранении неотслеживаемости информации, хранящейся на любом конкретном узле в DHT. Например, фрагмент информации может быть сохранен на одном узле в DHT, а затем безусловно запрошен обратно с этого узла. В I2P при использовании netDb это не так - информация, хранящаяся в DHT, может быть передана только при определенных известных обстоятельствах, когда это “безопасно”. Это сделано для предотвращения класса атак, при которых злоумышленник может попытаться связать client tunnel с router, отправив данные для хранения в client tunnel, а затем запросив их обратно напрямую с предполагаемого “хоста” client tunnel.

Структура сегментации

I2P router могут реализовать эффективную защиту от данного класса атак при соблюдении нескольких условий. Реализация базы данных сети должна быть способна отслеживать, была ли запись базы данных получена через клиентский tunnel или напрямую. Если она была получена через клиентский tunnel, то также должно отслеживаться, через какой именно клиентский tunnel она была получена, используя локальное назначение клиента. Если запись была получена через несколько клиентских tunnel, то netDb должна отслеживать все назначения, где была зафиксирована данная запись. Также должно отслеживаться, была ли запись получена как ответ на запрос или как сохранение.

И в Java, и в C++ реализациях это достигается путем использования единой “основной” netDb для прямых поисков и floodfill операций в первую очередь. Эта основная netDb существует в контексте router. Затем каждому клиенту предоставляется своя собственная версия netDb, которая используется для захвата записей базы данных, отправляемых в tunnel клиентов, и ответа на поисковые запросы, отправляемые через tunnel клиентов. Мы называем их “клиентскими сетевыми базами данных” или “под-базами данных”, и они существуют в контексте клиента. NetDb, управляемая клиентом, существует только в течение времени жизни клиента и содержит только записи, которые передаются через tunnel клиента. Это делает невозможным пересечение записей, отправляемых через tunnel клиентов, с записями, отправляемыми напрямую в router.

Дополнительно, каждая netDb должна быть способна запоминать, была ли запись базы данных получена потому, что она была отправлена к одному из наших назначений, или потому, что она была запрошена нами в рамках поиска. Если запись базы данных была получена как сохранение, то есть какой-то другой router отправил её нам, то netDb должна отвечать на запросы этой записи, когда другой router ищет ключ. Однако, если она была получена как ответ на запрос, то netDb должна отвечать на запрос записи только в том случае, если запись уже была сохранена в том же назначении. Клиент никогда не должен отвечать на запросы с записью из основной netDb, только из своей собственной клиентской базы данных сети.

Эти стратегии следует принимать и использовать в комбинации, чтобы применялись обе. В сочетании они “Сегментируют” netDb и защищают её от атак.


Механизмы Хранения, Проверки и Поиска

Хранение RouterInfo у пиров

I2NP DatabaseStoreMessages, содержащие локальную RouterInfo, обмениваются с узлами как часть инициализации транспортного соединения NTCP или SSU .

Хранение LeaseSet у пиров

I2NP DatabaseStoreMessages, содержащие локальный LeaseSet, периодически обмениваются с узлами путем упаковки их в garlic-сообщение вместе с обычным трафиком от связанного Destination. Это позволяет отправить начальный ответ и последующие ответы на соответствующий Lease без необходимости поиска LeaseSet или требования публикации LeaseSet взаимодействующими Destination вообще.

Выбор Floodfill

DatabaseStoreMessage должно отправляться на floodfill, который находится ближе всего к текущему ключу маршрутизации для сохраняемого RouterInfo или LeaseSet. В настоящее время ближайший floodfill находится путем поиска в локальной базе данных. Даже если этот floodfill фактически не является самым близким, он передаст сообщение “ближе”, отправив его нескольким другим floodfill. Это обеспечивает высокую степень отказоустойчивости.

В традиционной Kademlia узел выполнял бы поиск “найти ближайший” перед вставкой элемента в DHT к ближайшей цели. Поскольку операция проверки будет стремиться обнаружить более близкие floodfill, если они присутствуют, router быстро улучшит свои знания о “соседстве” DHT для RouterInfo и LeaseSets, которые он регулярно публикует. Хотя I2NP не определяет сообщение “найти ближайший”, если это станет необходимым, router может просто выполнить итеративный поиск ключа с инвертированным младшим значащим битом (т.е. key ^ 0x01) до тех пор, пока в DatabaseSearchReplyMessages не будут получены более близкие узлы. Это гарантирует, что истинно ближайший узел будет найден, даже если более удаленный узел имел элемент netDb.

Хранение RouterInfo на Floodfill

Router публикует свою собственную RouterInfo, напрямую подключаясь к floodfill router и отправляя ему I2NP DatabaseStoreMessage с ненулевым Reply Token. Сообщение не зашифровано end-to-end garlic encryption, поскольку это прямое соединение, то есть нет промежуточных router’ов (и нет необходимости скрывать эти данные в любом случае). Floodfill router отвечает I2NP DeliveryStatusMessage с Message ID, установленным в значение Reply Token.

В некоторых обстоятельствах router может также отправить RouterInfo DatabaseStoreMessage через исследовательский tunnel; например, из-за ограничений подключения, несовместимости подключений или желания скрыть фактический IP от floodfill. Floodfill может не принять такое сохранение во времена перегрузки или на основе других критериев; вопрос о том, следует ли явно объявить непрямое сохранение RouterInfo незаконным, является темой для дальнейшего изучения.

Хранение LeaseSet на Floodfill-узлах

Хранение LeaseSet гораздо более чувствительно, чем для RouterInfo, поскольку router должен позаботиться о том, чтобы LeaseSet нельзя было связать с router.

Router публикует локальный LeaseSet, отправляя I2NP DatabaseStoreMessage с ненулевым Reply Token через исходящий клиентский tunnel для данного Destination. Сообщение зашифровано методом garlic encryption с использованием Session Key Manager данного Destination для сокрытия сообщения от конечной точки исходящего tunnel. Floodfill router отвечает I2NP DeliveryStatusMessage с Message ID, установленным в значение Reply Token. Это сообщение отправляется обратно в один из входящих tunnel клиента.

Flooding

Как и любой router, floodfill использует различные критерии для проверки LeaseSet или RouterInfo перед их локальным сохранением. Эти критерии могут быть адаптивными и зависеть от текущих условий, включая текущую нагрузку, размер netDb и другие факторы. Вся проверка должна быть выполнена до распространения.

После того как floodfill router получает DatabaseStoreMessage, содержащее действительный RouterInfo или LeaseSet, который новее ранее сохраненного в его локальной NetDb, он выполняет “flooding” (распространение). Для распространения записи NetDb он ищет несколько (в настоящее время 3) floodfill router’ов, ближайших к ключу маршрутизации записи NetDb. (Ключ маршрутизации - это SHA256 хеш RouterIdentity или Destination с добавленной датой (yyyyMMdd).) Распространяя к тем, кто ближе всего к ключу, а не к себе, floodfill обеспечивает попадание хранилища в нужное место, даже если сохраняющий router не имел хороших знаний о DHT “окрестности” для ключа маршрутизации.

Floodfill затем напрямую подключается к каждому из этих узлов и отправляет им I2NP DatabaseStoreMessage с нулевым Reply Token. Сообщение не шифруется сквозным garlic encryption, поскольку это прямое соединение, и промежуточных router-ов нет (да и скрывать эти данные не нужно). Другие router-ы не отвечают и не повторно распространяют сообщение, поскольку Reply Token равен нулю.

Floodfill не должны выполнять flood через туннели; DatabaseStoreMessage должно отправляться через прямое соединение.

Floodfill никогда не должны распространять устаревший LeaseSet или RouterInfo, опубликованный более часа назад.

Поиск RouterInfo и LeaseSet

I2NP DatabaseLookupMessage используется для запроса записи netDb от floodfill router. Запросы отправляются через один из исходящих исследовательских tunnel маршрутизатора. Ответы должны возвращаться через один из входящих исследовательских tunnel маршрутизатора.

Запросы обычно отправляются параллельно двум “хорошим” (соединение не обрывается) floodfill роутерам, наиболее близким к запрашиваемому ключу.

Если ключ найден локально floodfill router, он отвечает сообщением I2NP DatabaseStoreMessage. Если ключ не найден локально floodfill router, он отвечает сообщением I2NP DatabaseSearchReplyMessage, содержащим список других floodfill router, близких к ключу.

Поиск LeaseSet осуществляется с использованием garlic encryption от конца до конца начиная с версии 0.9.5. Поиск RouterInfo не шифруется и поэтому уязвим для перехвата исходящей конечной точкой (OBEP) клиентского tunnel. Это связано с высокой вычислительной стоимостью ElGamal шифрования. Шифрование поиска RouterInfo может быть включено в будущих релизах.

Начиная с релиза 0.9.7, ответы на запрос leaseSet (DatabaseStoreMessage или DatabaseSearchReplyMessage) будут шифроваться путем включения ключа сессии и тега в запрос. Это скрывает ответ от входящего шлюза (IBGW) tunnel ответа. Ответы на запросы RouterInfo будут шифроваться, если мы включим шифрование запросов.

(Справка: Hashing it out in Public Разделы 2.2-2.3 для терминов ниже, выделенных курсивом)

Из-за относительно небольшого размера сети и избыточности flooding, поиск обычно имеет сложность O(1) вместо O(log n). Router с большой вероятностью знает floodfill router, достаточно близкий к ключу, чтобы получить ответ с первой попытки. В релизах до 0.8.9 router’ы использовали избыточность поиска равную двум (то есть два поиска выполнялись параллельно к разным узлам), и ни рекурсивная, ни итеративная маршрутизация для поиска не была реализована. Запросы отправлялись через множественные маршруты одновременно для снижения вероятности сбоя запроса.

Начиная с релиза 0.8.9, реализованы итеративные поиски без избыточности поиска. Это более эффективный и надежный поиск, который будет работать намного лучше, когда не все floodfill-узлы известны, и он устраняет серьезное ограничение роста сети. По мере роста сети и когда каждый router знает только небольшое подмножество floodfill-узлов, поиски будут выполняться за O(log n). Даже если узел не возвращает ссылки, более близкие к ключу, поиск продолжается со следующим ближайшим узлом для дополнительной надежности и для предотвращения возможности злонамеренного floodfill создать “черную дыру” для части пространства ключей. Поиски продолжаются до тех пор, пока не будет достигнут общий тайм-аут поиска или не будет опрошено максимальное количество узлов.

ID узлов являются верифицируемыми, поскольку мы используем хеш router напрямую как в качестве ID узла, так и в качестве ключа Kademlia. Некорректные ответы, которые не являются более близкими к ключу поиска, обычно игнорируются. Учитывая текущий размер сети, router имеет детальное знание окрестности пространства ID назначения.

Проверка хранения RouterInfo

Примечание: Проверка RouterInfo отключена начиная с версии 0.9.7.1 для предотвращения атаки, описанной в работе Practical Attacks Against the I2P Network . Неясно, можно ли переработать проверку так, чтобы она выполнялась безопасно.

Чтобы проверить успешность хранения, router просто ждет около 10 секунд, затем отправляет запрос на поиск другому floodfill router, близкому к ключу (но не тому, которому был отправлен запрос на хранение). Запросы на поиск отправляются через один из исходящих исследовательских tunnel роутера. Запросы на поиск зашифрованы end-to-end с использованием garlic encryption для предотвращения подслушивания конечной точкой исходящего туннеля (OBEP).

Проверка хранения LeaseSet

Чтобы проверить успешность сохранения, router просто ждет около 10 секунд, затем отправляет запрос поиска другому floodfill router, близкому к ключу (но не тому, которому было отправлено сохранение). Запросы поиска отправляются через один из исходящих клиентских tunnel для назначения проверяемого LeaseSet. Чтобы предотвратить подслушивание со стороны OBEP исходящего tunnel, запросы поиска шифруются end-to-end с помощью garlic encryption. Ответы должны возвращаться через один из входящих tunnel клиента.

Начиная с версии 0.9.7, ответы для поиска как RouterInfo, так и LeaseSet (DatabaseStoreMessage или DatabaseSearchReplyMessage) будут зашифрованы, чтобы скрыть ответ от входящего шлюза (IBGW) tunnel ответа.

Исследование

Exploration — это особая форма поиска в netDb, при которой router пытается узнать о новых router’ах. Это делается путем отправки floodfill router’у I2NP DatabaseLookup Message, ищущего случайный ключ. Поскольку этот поиск завершится неудачей, floodfill обычно ответил бы I2NP DatabaseSearchReplyMessage, содержащим хеши floodfill router’ов, близких к ключу. Это было бы бесполезно, поскольку запрашивающий router, вероятно, уже знает эти floodfill’ы, и было бы непрактично добавлять все floodfill router’ы в поле “не включать” DatabaseLookup Message. Для запроса exploration запрашивающий router устанавливает специальный флаг в DatabaseLookup Message. Тогда floodfill ответит только с не-floodfill router’ами, близкими к запрашиваемому ключу.

Примечания по ответам на запросы поиска

Ответ на запрос поиска представляет собой либо Database Store Message (в случае успеха), либо Database Search Reply Message (в случае неудачи). DSRM содержит поле хэша router ‘from’ для указания источника ответа; DSM его не содержит. Поле ‘from’ в DSRM не аутентифицировано и может быть подделано или недействительно. Других тегов ответа нет. Поэтому при выполнении нескольких параллельных запросов сложно отслеживать производительность различных floodfill router.


Многодомность

Destinations могут размещаться на нескольких router одновременно, используя одни и те же приватные и публичные ключи (традиционно хранящиеся в файлах eepPriv.dat). Поскольку оба экземпляра периодически публикуют свои подписанные leaseSet в floodfill узлы, самый недавно опубликованный leaseSet будет возвращен узлу, запрашивающему поиск в базе данных. Поскольку leaseSet имеют время жизни максимум 10 минут, если конкретный экземпляр выйдет из строя, простой составит максимум 10 минут, а обычно намного меньше. Функция мультихостинга была протестирована и используется несколькими сервисами в сети.

Начиная с версии 0.9.38, floodfill поддерживают новую структуру Meta LeaseSet. Эта структура обеспечивает древовидную организацию в DHT для ссылок на другие LeaseSet. Используя Meta LeaseSet, сайт может реализовать крупные мультидомные сервисы, где несколько различных Destination используются для предоставления общего сервиса. Записи в Meta LeaseSet являются Destination или другими Meta LeaseSet и могут иметь длительные сроки действия, до 18,2 часов. Используя эту возможность, должно быть возможно запускать сотни или тысячи Destination, обслуживающих общий сервис. Подробности см. в предложении 123.


Анализ угроз

Также обсуждается на странице модели угроз .

Злонамеренный пользователь может попытаться нанести вред сети, создав один или несколько floodfill роутеров и настроив их для предоставления плохих, медленных или отсутствующих ответов. Ниже рассматриваются некоторые сценарии.

Общее смягчение через рост

В настоящее время в сети насчитывается около 1700 floodfill роутеров. Большинство из следующих атак станут более сложными или будут иметь меньшее воздействие по мере увеличения размера сети и количества floodfill роутеров.

Общее снижение рисков через избыточность

Через flooding все записи netDb хранятся на 3 floodfill роутерах, ближайших к ключу.

Подделки

Все записи netDb подписаны их создателями, поэтому ни один router не может подделать RouterInfo или LeaseSet.

Медленная или неотвечающая работа

Каждый router ведет расширенный набор статистики в профиле узла для каждого floodfill router, охватывающий различные метрики качества для этого узла. Набор включает:

  • Среднее время отклика
  • Процент запросов, отвеченных с запрошенными данными
  • Процент хранилищ, которые были успешно проверены
  • Последнее успешное сохранение
  • Последний успешный поиск
  • Последний отклик

Каждый раз, когда router нужно определить, какой floodfill router ближе всего к ключу, он использует эти метрики для определения того, какие floodfill router являются “хорошими”. Методы и пороговые значения, используемые для определения “качества”, относительно новые и подлежат дальнейшему анализу и улучшению. В то время как полностью неотвечающий router будет быстро обнаружен и исключен, router, которые лишь иногда ведут себя злонамеренно, могут быть гораздо сложнее для обнаружения.

Атака Сибиллы (полное пространство ключей)

Атакующий может осуществить атаку Сибиллы , создав большое количество floodfill router’ов, распределённых по всему пространству ключей.

(В связанном примере исследователь недавно создал большое количество relay-узлов Tor .) В случае успеха это могло бы стать эффективной DOS-атакой на всю сеть.

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

  • Составить список хешей или IP-адресов плохих router’ов и объявить список через различные средства (новости консоли, веб-сайт, форум и т.д.); пользователям придется вручную загружать список и добавлять его в свой локальный “черный список”.
  • Попросить всех в сети включить floodfill вручную (бороться с Sybil с помощью большего количества Sybil)
  • Выпустить новую версию программного обеспечения, которая включает жестко закодированный список “плохих”
  • Выпустить новую версию программного обеспечения, которая улучшает метрики и пороги профиля узлов, в попытке автоматически идентифицировать “плохие” узлы.
  • Добавить программное обеспечение, которое дисквалифицирует floodfill’ы, если слишком много из них находятся в одном IP-блоке
  • Реализовать автоматический черный список на основе подписки, контролируемый одним лицом или группой. Это по сути реализовало бы часть модели “консенсуса” Tor. К сожалению, это также дало бы одному лицу или группе власть блокировать участие любого конкретного router’а или IP в сети, или даже полностью отключить или уничтожить всю сеть.

Эта атака становится более сложной по мере роста размера сети.

Атака Сивиллы (Частичное пространство ключей)

Злоумышленник может провести Sybil-атаку , создав небольшое количество (8-15) floodfill router’ов, расположенных близко в пространстве ключей, и широко распространив RouterInfo для этих router’ов. Тогда все запросы и сохранения для ключа в этом пространстве ключей будут направлены к одному из router’ов злоумышленника. В случае успеха это может стать эффективной DOS-атакой на конкретный I2P Site, например.

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

В качестве частичной защиты от этой атаки алгоритм, используемый для определения “близости” в Kademlia, изменяется со временем. Вместо использования хеша ключа (т.е. H(k)) для определения близости мы используем хеш ключа, к которому добавлена строка текущей даты, т.е. H(k + YYYYMMDD). Функция под названием “генератор routing key” выполняет это преобразование, превращая исходный ключ в “routing key”. Другими словами, всё пространство ключей netDb “поворачивается” каждый день в полночь по UTC. Любая атака на частичное пространство ключей должна была бы возобновляться каждый день, поскольку после поворота атакующие router больше не будут близки к целевому ключу или друг к другу.

Эта атака становится более сложной по мере роста размера сети. Однако недавние исследования показывают, что ротация пространства ключей не особенно эффективна. Злоумышленник может заранее предвычислить множество хешей router’ов, и достаточно лишь нескольких router’ов, чтобы “затмить” часть пространства ключей в течение получаса после ротации.

Одним из последствий ежедневной ротации пространства ключей является то, что распределенная сетевая база данных может стать ненадежной на несколько минут после ротации – поиски будут неудачными, поскольку новый “ближайший” router еще не получил данные для хранения. Масштаб проблемы и методы ее устранения (например, “передача” netDb в полночь) являются темой для дальнейшего изучения.

Атаки на начальную загрузку

Злоумышленник может попытаться загрузить новые router’ы в изолированную или контролируемую большинством сеть, захватив веб-сайт reseed или обманом заставив разработчиков добавить его веб-сайт reseed в жестко запрограммированный список в router’е.

Возможно несколько способов защиты, и большинство из них запланированы:

  • Запретить переключение с HTTPS на HTTP для reseed. MITM-атакующий может просто заблокировать HTTPS, а затем отвечать на HTTP.
  • Включение данных reseed в установщик

Реализованные средства защиты:

  • Изменение задачи reseed для получения подмножества RouterInfo из нескольких reseed сайтов вместо использования только одного сайта
  • Создание внешнего сервиса мониторинга reseed, который периодически опрашивает reseed веб-сайты и проверяет, что данные не устарели и согласуются с другими представлениями сети
  • Начиная с релиза 0.9.14, данные reseed упаковываются в подписанный zip-файл, и подпись проверяется при загрузке. См. спецификацию su3 для подробностей.

Перехват запросов

См. также поиск (Справочник: Hashing it out in Public Разделы 2.2-2.3 для терминов ниже, выделенных курсивом)

Подобно атаке через bootstrap, злоумышленник, использующий floodfill router, может попытаться “направить” узлы к подмножеству роутеров, контролируемых им, возвращая ссылки на них.

Это вряд ли сработает через исследование, поскольку исследование является низкочастотной задачей. Router’ы получают большинство ссылок на узлы через обычную активность построения tunnel’ей. Результаты исследования обычно ограничиваются несколькими хэшами router’ов, и каждый запрос исследования направляется к случайному floodfill router’у.

Начиная с версии 0.8.9 реализованы итеративные поиски. Для ссылок на floodfill router, возвращаемых в ответе I2NP DatabaseSearchReplyMessage на поиск, эти ссылки проверяются, если они ближе (или следующие по близости) к ключу поиска. Запрашивающий router не доверяет тому, что ссылки действительно ближе к ключу (т.е. они верифицируемо корректны). Поиск также не останавливается, когда не найден более близкий ключ, а продолжается опросом следующего ближайшего узла, пока не достигнут таймаут или максимальное количество запросов. Это предотвращает возможность злонамеренного floodfill создать “чёрную дыру” в части пространства ключей. Кроме того, ежедневная ротация пространства ключей требует от атакующего регенерировать информацию router в желаемом регионе пространства ключей. Такой дизайн гарантирует, что атака перехвата запросов, описанная в Hashing it out in Public , становится значительно сложнее.

Выбор Relay на основе DHT

(Справочник: Hashing it out in Public Раздел 3)

Это не имеет большого отношения к floodfill, но смотрите страницу выбора узлов для обсуждения уязвимостей выбора узлов для tunnel.

Утечки информации

(Справка: В поисках анонимного и безопасного поиска Раздел 3)

Данная статья рассматривает слабости в DHT-поиске “Finger Table”, используемом Torsk и NISAN. На первый взгляд, это не касается I2P. Во-первых, использование DHT в Torsk и NISAN значительно отличается от того, как это делается в I2P. Во-вторых, поиск в сетевой базе данных I2P лишь слабо связан с процессами выбора пиров и построения tunnel ; для tunnel используются только ранее известные пиры. Кроме того, выбор пиров не связан с каким-либо понятием близости ключей DHT.

Часть этого может оказаться более интересной, когда сеть I2P станет намного больше. Прямо сейчас каждый router знает большую часть сети, поэтому поиск определенной Router Info в базе данных сети не является сильным индикатором будущего намерения использовать этот router в tunnel. Возможно, когда сеть станет в 100 раз больше, поиск может быть более показательным. Конечно, большая сеть делает атаку Sybil намного сложнее.

Однако общая проблема утечки информации DHT в I2P требует дальнейшего исследования. Floodfill роутеры находятся в позиции для наблюдения за запросами и сбора информации. Безусловно, при уровне f = 0.2 (20% злонамеренных узлов, как указано в статье) мы ожидаем, что многие из Sybil угроз, которые мы описываем (здесь , здесь и здесь ), становятся проблематичными по нескольким причинам.


История

Перенесено на страницу обсуждения netDb .


Будущая работа

Сквозное шифрование дополнительных запросов и ответов netDb.

Улучшенные методы отслеживания ответов на запросы поиска.

Was this page helpful?