Обзор
I2P поставляется с универсальной библиотекой именования и базовой реализацией, предназначенной для работы с локальным сопоставлением имен и назначений, а также дополнительным приложением под названием address book . I2P также поддерживает Base32 hostnames , похожие на .onion адреса Tor.
Адресная книга - это основанная на сети доверия безопасная, распределенная и удобочитаемая система именования, жертвующая лишь требованием глобальной уникальности всех удобочитаемых имен, требуя только локальной уникальности. Хотя все сообщения в I2P криптографически адресуются по их destination (пункту назначения), разные люди могут иметь локальные записи в адресной книге для “Alice”, которые ссылаются на разные destination. Люди по-прежнему могут находить новые имена, импортируя опубликованные адресные книги узлов, указанных в их сети доверия, добавляя записи, предоставленные третьей стороной, или (если некоторые люди организуют серию опубликованных адресных книг, используя систему регистрации по принципу “первый пришел - первый обслужен”) люди могут выбрать рассматривать эти адресные книги как серверы имен, эмулируя традиционный DNS.
ПРИМЕЧАНИЕ: Обоснование системы именования I2P, распространенные возражения против неё и возможные альтернативы см. на странице обсуждения именования .
Компоненты системы именования
В I2P нет централизованного органа именования. Все имена хостов являются локальными.
Система именования довольно проста, и большая её часть реализована в приложениях, внешних по отношению к router, но поставляемых в комплекте с дистрибутивом I2P. Компоненты включают:
- Локальная служба именования , которая выполняет поиск и также обрабатывает Base32 имена хостов .
- HTTP proxy , который запрашивает у router поиск и направляет пользователя к удаленным jump службам для помощи с неудачными поисками.
- HTTP формы добавления хостов , которые позволяют пользователям добавлять хосты в свой локальный hosts.txt
- HTTP jump службы , которые предоставляют собственный поиск и перенаправление.
- Приложение адресная книга , которое объединяет внешние списки хостов, полученные через HTTP, с локальным списком.
- Приложение SusiDNS , которое представляет собой простой веб-интерфейс для настройки адресной книги и просмотра локальных списков хостов.
Службы имен
Все назначения в I2P представляют собой ключи размером 516 байт (или больше). (Точнее, это 256-байтовый публичный ключ плюс 128-байтовый ключ подписи плюс сертификат размером 3 или более байт, что в представлении Base64 составляет 516 или более байт. Сейчас используются ненулевые Сертификаты для указания типа подписи. Поэтому сертификаты в недавно сгенерированных назначениях имеют размер более 3 байт.
Если приложение (i2ptunnel или HTTP-прокси) хочет получить доступ к назначению по имени, router выполняет очень простой локальный поиск для разрешения этого имени.
Служба именования Hosts.txt
Служба имен hosts.txt выполняет простой линейный поиск по текстовым файлам. Эта служба имен была стандартной до версии 0.8.8, когда она была заменена на Blockfile Naming Service. Формат hosts.txt стал слишком медленным после того, как файл вырос до тысяч записей.
Он выполняет линейный поиск по трем локальным файлам по порядку, чтобы найти имена хостов и преобразовать их в 516-байтовый ключ назначения. Каждый файл имеет простой формат конфигурационного файла , с hostname=base64, по одному на строку. Файлы:
- privatehosts.txt
- userhosts.txt
- hosts.txt
Служба именования Blockfile
Служба имен Blockfile хранит несколько “адресных книг” в одном файле базы данных под названием hostsdb.blockfile. Эта служба имен используется по умолчанию начиная с версии 0.8.8.
Blockfile — это просто дисковое хранилище нескольких отсортированных карт (пар ключ-значение), реализованных как skiplist’ы. Формат blockfile описан на странице Blockfile . Он обеспечивает быстрый поиск Destination в компактном формате. Хотя накладные расходы blockfile существенны, destination’ы хранятся в двоичном формате, а не в Base 64, как в формате hosts.txt. Кроме того, blockfile предоставляет возможность произвольного хранения метаданных (таких как дата добавления, источник и комментарии) для каждой записи для реализации расширенных функций адресной книги. Требования к хранилищу blockfile лишь незначительно превышают формат hosts.txt, при этом blockfile обеспечивает примерно 10-кратное сокращение времени поиска.
При создании служба именования импортирует записи из трех файлов, используемых службой именования hosts.txt. Блочный файл имитирует предыдущую реализацию, поддерживая три карты, которые просматриваются по порядку: privatehosts.txt, userhosts.txt и hosts.txt. Он также поддерживает карту обратного поиска для реализации быстрого обратного поиска.
Другие возможности службы именования
Поиск нечувствителен к регистру. Используется первое совпадение, конфликты не обнаруживаются. При поиске не применяется принудительное соблюдение правил именования. Результаты поиска кэшируются на несколько минут. Разрешение Base 32 описано ниже . Полное описание API службы имён смотрите в Javadocs службы имён . Этот API был значительно расширен в версии 0.8.7 для обеспечения добавления и удаления, хранения произвольных свойств с именем хоста и других функций.
Альтернативные и экспериментальные службы имен
Служба именования указывается с помощью параметра конфигурации i2p.naming.impl=class. Возможны другие реализации. Например, существует экспериментальная возможность для поиска в реальном времени (как DNS) по сети внутри router. Для получения дополнительной информации см. альтернативы на странице обсуждения
.
HTTP-прокси выполняет поиск через router для всех имен хостов, заканчивающихся на ‘.i2p’. В противном случае он перенаправляет запрос на настроенный HTTP outproxy. Таким образом, на практике все HTTP (I2P Site) имена хостов должны заканчиваться псевдо-доменом верхнего уровня ‘.i2p’.
Если router не может разрешить имя хоста, HTTP прокси возвращает пользователю страницу с ошибкой со ссылками на несколько сервисов “jump”. См. подробности ниже.
Домен .i2p.alt
Ранее мы подавали заявку на резервирование домена верхнего уровня .i2p в соответствии с процедурами, указанными в RFC 6761 . Однако эта заявка и все остальные были отклонены, а RFC 6761 был объявлен “ошибкой”.
После многолетней работы команды GNUnet и других, домен .alt был зарезервирован как TLD специального использования в RFC 9476 в конце 2023 года. Хотя нет официальных регистраторов, санкционированных IANA, мы зарегистрировали домен .i2p.alt у основного неофициального регистратора GANA . Это не препятствует другим использовать этот домен, но должно помочь их отговорить.
Одно из преимуществ домена .alt заключается в том, что теоретически DNS-резолверы не будут перенаправлять запросы .alt после обновления для соответствия RFC 9476, и это предотвратит утечки DNS. Для совместимости с именами хостов .i2p.alt программное обеспечение и сервисы I2P должны быть обновлены для обработки этих имен хостов путем удаления TLD .alt. Эти обновления запланированы на первую половину 2024 года.
В настоящее время нет планов сделать .i2p.alt предпочтительной формой для отображения и обмена I2P-хостнеймами. Это тема для дальнейших исследований и обсуждений.
Адресная книга
Входящие подписки и слияние
Приложение адресной книги периодически получает файлы hosts.txt других пользователей и объединяет их с локальным hosts.txt после нескольких проверок. Конфликты имен разрешаются по принципу «первый пришел — первый получил».
Подписка на файл hosts.txt другого пользователя подразумевает определённый уровень доверия к нему. Вы не хотите, чтобы они, например, «захватили» новый сайт, быстро введя свой собственный ключ для нового сайта перед передачей вам новой записи хост/ключ.
По этой причине единственной подпиской, настроенной по умолчанию, является http://i2p-projekt.i2p/hosts.txt (http://udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p/hosts.txt), которая содержит копию файла hosts.txt, включенного в релиз I2P. Пользователи должны настроить дополнительные подписки в своем локальном приложении адресной книги (через subscriptions.txt или SusiDNS
).
Некоторые другие ссылки на публичные подписки адресной книги:
- http://i2host.i 2p/cgi-bin/i2hostetag
- http://stats.i 2p/cgi-bin/newhosts.txt
Операторы этих сервисов могут иметь различные политики для включения хостов в список. Присутствие в этом списке не означает одобрения.
Правила именования
Хотя в I2P, надеемся, нет технических ограничений на имена хостов, адресная книга накладывает несколько ограничений на имена хостов, импортируемые из подписок. Это делается для базовой типографической корректности и совместимости с браузерами, а также для безопасности. Правила в основном такие же, как в RFC2396 Section 3.2.2. Любые имена хостов, нарушающие эти правила, могут не передаваться другим router’ам.
Правила именования:
- Имена преобразуются в нижний регистр при импорте.
- Имена проверяются на конфликт с существующими именами в существующих userhosts.txt и hosts.txt (но не privatehosts.txt) после преобразования в нижний регистр.
- Должны содержать только [a-z] [0-9] ‘.’ и ‘-’ после преобразования в нижний регистр.
- Не должны начинаться с ‘.’ или ‘-’.
- Должны заканчиваться на ‘.i2p’.
- Максимум 67 символов, включая ‘.i2p’.
- Не должны содержать ‘..’.
- Не должны содержать ‘.-’ или ‘-.’ (начиная с версии 0.6.1.33).
- Не должны содержать ‘–’ кроме как в ‘xn–’ для IDN.
- Base32 имена хостов (*.b32.i2p) зарезервированы для использования base 32 и поэтому не разрешены для импорта.
- Определенные имена хостов, зарезервированные для использования проектом, не разрешены (proxy.i2p, router.i2p, console.i2p, mail.i2p, *.proxy.i2p, *.router.i2p, *.console.i2p, *.mail.i2p и другие)
- Имена хостов, начинающиеся с ‘www.’, не рекомендуются и отклоняются некоторыми службами регистрации. Некоторые реализации адресной книги автоматически удаляют префиксы ‘www.’ из запросов. Поэтому регистрация ‘www.example.i 2p’ не нужна, и регистрация разного назначения для ‘www.example.i 2p’ и ’example.i2p’ сделает ‘www.example.i 2p’ недоступным для некоторых пользователей.
- Ключи проверяются на валидность base64.
- Ключи проверяются на конфликт с существующими ключами в hosts.txt (но не privatehosts.txt).
- Минимальная длина ключа 516 байт.
- Максимальная длина ключа 616 байт (чтобы учесть сертификаты до 100 байт).
Любое имя, полученное через подписку и прошедшее все проверки, добавляется через локальную службу именования.
Обратите внимание, что символы ‘.’ в имени хоста не имеют значения и не обозначают какую-либо фактическую иерархию именования или доверия. Если имя ‘host.i2p’ уже существует, ничто не мешает кому-либо добавить имя ‘a.host.i2p’ в свой hosts.txt, и это имя может быть импортировано в адресные книги других пользователей. Методы запрета поддоменов для лиц, не являющихся ‘владельцами’ домена (сертификаты?), а также желательность и осуществимость таких методов являются темами для будущего обсуждения.
Международные доменные имена (IDN) также работают в i2p (используя форму punycode ‘xn–’). Чтобы доменные имена IDN .i2p корректно отображались в адресной строке Firefox, добавьте ’network.IDN.whitelist.i2p (boolean) = true’ в about:config.
Поскольку приложение адресной книги вообще не использует privatehosts.txt, на практике этот файл является единственным подходящим местом для размещения приватных псевдонимов или “личных имен” для сайтов, уже находящихся в hosts.txt.
Расширенный формат ленты подписок
Начиная с версии 0.9.26, сайты подписок и клиенты могут поддерживать расширенный протокол feeds hosts.txt, который включает метаданные, в том числе подписи. Этот формат обратно совместим со стандартным форматом hosts.txt hostname=base64destination. Подробности см. в спецификации .
Исходящие подписки
Address Book опубликует объединённый файл hosts.txt в определённое место (традиционно hosts.txt в домашней директории локального I2P сайта), чтобы другие могли получить к нему доступ для своих подписок. Этот шаг является необязательным и по умолчанию отключён.
Проблемы хостинга и HTTP-транспорта
Приложение адресной книги вместе с eepget сохраняет информацию Etag и/или Last-Modified, возвращаемую веб-сервером подписки. Это значительно снижает требуемую пропускную способность, поскольку веб-сервер вернет ‘304 Not Modified’ при следующем запросе, если ничего не изменилось.
Однако весь файл hosts.txt загружается, если он был изменен. См. обсуждение этого вопроса ниже.
Хостам, которые предоставляют статический файл hosts.txt или эквивалентное CGI-приложение, настоятельно рекомендуется отправлять заголовок Content-Length и либо заголовок Etag, либо Last-Modified. Также убедитесь, что сервер возвращает ‘304 Not Modified’ когда это уместно. Это значительно снизит потребление сетевой пропускной способности и уменьшит вероятность повреждения данных.
Службы добавления хостов
Служба добавления хостов — это простое CGI-приложение, которое принимает имя хоста и ключ Base64 в качестве параметров и добавляет их в свой локальный файл hosts.txt. Если другие router подписаны на этот hosts.txt, новое имя хоста/ключ будет распространено по сети.
Рекомендуется, чтобы службы добавления хостов применяли как минимум те ограничения, которые накладывает приложение адресной книги, перечисленное выше. Службы добавления хостов могут накладывать дополнительные ограничения на имена хостов и ключи, например:
- Ограничение на количество ‘поддоменов’.
- Авторизация для ‘поддоменов’ различными методами.
- Hashcash или подписанные сертификаты.
- Редакционная проверка имен хостов и/или контента.
- Категоризация хостов по контенту.
- Резервирование или отклонение определенных имен хостов.
- Ограничения на количество имен, зарегистрированных за определенный период времени.
- Задержки между регистрацией и публикацией.
- Требование, чтобы хост был доступен для верификации.
- Истечение срока и/или отзыв.
- Отклонение IDN спуфинга.
Jump-сервисы
Jump service — это простое CGI-приложение, которое принимает имя хоста в качестве параметра и возвращает 301 редирект на правильный URL с добавленной строкой ?i2paddresshelper=key. HTTP-прокси интерпретирует добавленную строку и использует этот ключ как фактическое назначение. Кроме того, прокси кеширует этот ключ, поэтому address helper не требуется до перезапуска.
Обратите внимание, что как и с подписками, использование jump-сервиса подразумевает определенную степень доверия, поскольку jump-сервис может злонамеренно перенаправить пользователя к неправильному назначению.
Для обеспечения наилучшего сервиса jump-сервис должен быть подписан на несколько провайдеров hosts.txt, чтобы его локальный список хостов был актуальным.
SusiDNS
SusiDNS — это просто веб-интерфейс для настройки подписок на адресные книги и доступа к четырем файлам адресных книг. Всю реальную работу выполняет приложение ‘address book’.
В настоящее время в SusiDNS слабо применяются правила именования адресной книги, поэтому пользователь может вводить имена хостов локально, которые были бы отклонены правилами подписки на адресную книгу.
Имена Base32
I2P поддерживает Base32 имена хостов, похожие на .onion адреса Tor. Base32 адреса намного короче и проще в обращении, чем полные 516-символьные Base64 Destinations или addresshelpers. Пример: ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p
В Tor адрес состоит из 16 символов (80 бит) или половины хеша SHA-1. I2P использует 52 символа (256 бит) для представления полного хеша SHA-256. Формат выглядит как {52 символа}.b32.i2p. У Tor есть предложение перейти на идентичный формат {52 символа}.onion для их скрытых сервисов. Base32 реализован в службе именования, которая запрашивает router через I2CP для поиска leaseSet и получения полного Destination. Поиск Base32 будет успешным только когда Destination работает и публикует leaseSet. Поскольку разрешение имени может потребовать поиска в базе данных сети, это может занять значительно больше времени, чем поиск в локальной адресной книге.
Base32 адреса можно использовать в большинстве мест, где используются имена хостов или полные destination, однако есть некоторые исключения, где они могут не работать, если имя не разрешается немедленно. I2PTunnel, например, завершится с ошибкой, если имя не разрешается в destination.
Расширенные имена Base32
Расширенные имена base 32 были введены в релизе 0.9.40 для поддержки зашифрованных lease sets. Адреса для зашифрованных leasesets определяются по 56 или более закодированным символам, не включая “.b32.i2p” (35 или более декодированных байт), по сравнению с 52 символами (32 байта) для традиционных адресов base 32. Смотрите предложения 123 и 149 для дополнительной информации.
Стандартные Base 32 (“b32”) адреса содержат хеш назначения. Это не будет работать для зашифрованных ls2 (предложение 123).
Вы не можете использовать традиционный base 32 адрес для зашифрованного LS2 (предложение 123), поскольку он содержит только хэш назначения. Он не предоставляет незашифрованный публичный ключ. Клиенты должны знать публичный ключ назначения, тип подписи, тип зашифрованной подписи и необязательный секретный или приватный ключ для получения и расшифровки leaseset. Поэтому одного base 32 адреса недостаточно. Клиенту нужно либо полное назначение (которое содержит публичный ключ), либо сам публичный ключ. Если клиент имеет полное назначение в адресной книге, и адресная книга поддерживает обратный поиск по хэшу, то публичный ключ может быть получен.
Поэтому нам нужен новый формат, который помещает публичный ключ вместо хеша в base32 адрес. Этот формат также должен содержать тип подписи публичного ключа и тип подписи схемы блайндинга.
В этом разделе документируется новый формат b32 для данных адресов. Хотя во время обсуждений мы называли этот новый формат адресом “b33”, фактический новый формат сохраняет обычный суффикс “.b32.i2p”.
Создание и кодирование
Создайте имя хоста {56+ символов}.b32.i2p (35+ символов в двоичном виде) следующим образом. Сначала сформируйте двоичные данные для кодирования в base 32:
flag (1 byte)
bit 0: 0 for one-byte sigtypes, 1 for two-byte sigtypes
bit 1: 0 for no secret, 1 if secret is required
bit 2: 0 for no per-client auth,
1 if client private key is required
bits 7-3: Unused, set to 0
public key sigtype (1 or 2 bytes as indicated in flags)
If 1 byte, the upper byte is assumed zero
blinded key sigtype (1 or 2 bytes as indicated in flags)
If 1 byte, the upper byte is assumed zero
public key
Number of bytes as implied by sigtype
Постобработка и контрольная сумма:
Construct the binary data as above.
Treat checksum as little-endian.
Calculate checksum = CRC-32(data[3:end])
data[0] ^= (byte) checksum
data[1] ^= (byte) (checksum >> 8)
data[2] ^= (byte) (checksum >> 16)
hostname = Base32.encode(data) || ".b32.i2p"
Любые неиспользуемые биты в конце b32 должны быть равны 0. Для стандартного адреса из 56 символов (35 байт) неиспользуемых битов нет.
Декодирование и верификация
Strip the ".b32.i2p" from the hostname
data = Base32.decode(hostname)
Calculate checksum = CRC-32(data[3:end])
Treat checksum as little-endian.
flags = data[0] ^ (byte) checksum
if 1 byte sigtypes:
pubkey sigtype = data[1] ^ (byte) (checksum >> 8)
blinded sigtype = data[2] ^ (byte) (checksum >> 16)
else (2 byte sigtypes) :
pubkey sigtype = data[1] ^ ((byte) (checksum >> 8)) || data[2] ^ ((byte) (checksum >> 16))
blinded sigtype = data[3] || data[4]
parse the remainder based on the flags to get the public key
Биты секретного и приватного ключа
Биты secret и private key используются для указания клиентам, прокси или другому клиентскому коду, что secret и/или private key потребуются для расшифровки leaseset. Конкретные реализации могут запросить у пользователя необходимые данные или отклонить попытки подключения, если требуемые данные отсутствуют.
Примечания
- XOR первых 3 байт с хэшем обеспечивает ограниченную возможность контрольной суммы и гарантирует, что все base32 символы в начале рандомизированы. Действительны только несколько комбинаций флагов и sigtype, поэтому любая опечатка скорее всего создаст недействительную комбинацию и будет отклонена.
- В обычном случае (1-байтовые sigtypes, без секрета, без пер-клиентской аутентификации), имя хоста будет {56 символов}.b32.i2p, декодируясь в 35 байт, как в Tor.
- 2-байтовая контрольная сумма Tor имеет частоту ложных отрицательных результатов 1/64K. С 3 байтами, минус несколько игнорируемых байт, наша приближается к 1 из миллиона, поскольку большинство комбинаций flag/sigtype недействительны.
- Adler-32 - плохой выбор для малых входных данных и для обнаружения небольших изменений. Вместо этого мы используем CRC-32. CRC-32 быстр и широко доступен.
- Хотя это выходит за рамки данной спецификации, router-ы и/или клиенты должны помнить и кэшировать (вероятно, постоянно) отображение публичного ключа на назначение и наоборот.
- Отличать старые вкусы от новых по длине. Старые b32 адреса всегда {52 символа}.b32.i2p. Новые - {56+ символов}.b32.i2p
- Обсуждение Tor здесь
- Не ожидайте, что 2-байтовые sigtypes когда-либо появятся, мы пока только на 13. Нет необходимости реализовывать сейчас.
- Новый формат может использоваться в jump ссылках (и обслуживаться jump серверами) при желании, точно так же, как b32.
- Любой секрет, приватный ключ или публичный ключ длиннее 32 байт превысил бы максимальную длину DNS-метки в 63 символа. Браузерам, вероятно, всё равно.
- Нет проблем с обратной совместимостью. Более длинные b32 адреса не смогут быть преобразованы в 32-байтовые хэши в старом программном обеспечении.