Статус
Одобрено на втором обзоре 2025-04-01; спецификации обновлены; еще не реализовано.
Обзор
У I2P отсутствует централизованная система DNS. Тем не менее, адресная книга вместе с системой b32 хостнеймов позволяет роутеру искать полные адресаты и получать наборы аренды, которые содержат список шлюзов и ключей, чтобы клиенты могли подключаться к этому адресу.
Итак, наборы аренды несколько похожи на запись DNS. Но в настоящее время нет возможности узнать, поддерживает ли этот хост какие-либо службы, как на этом адресе, так и на другом, подобно записям DNS SRV SRV RFC2782.
Первым приложением для этого может быть одноранговая электронная почта. Другие возможные приложения: DNS, GNS, серверы ключей, центры сертификации, серверы времени, bittorrent, криптовалюты, другие одноранговые приложения.
Связанные предложения и альтернативы
Списки служб
Предложение LS2 123 Prop123 определило ‘записи служб’, которые указывали, что адресат участвовал в глобальной службе. Избыточные узлы агрегировали бы эти записи в глобальные ‘списки служб’. Это никогда не было реализовано из-за сложности, отсутствия аутентификации, безопасности и опасений по поводу спама.
Это предложение отличается тем, что предоставляет поиск службы для конкретного адреса, а не глобального пула адресов для какой-то глобальной службы.
GNS
GNS GNS предлагает, чтобы каждый запускал свой собственный DNS сервер. Это предложение является дополнением, в том смысле, что мы можем использовать записи служб, чтобы указать, что GNS (или DNS) поддерживается, с стандартным именем службы “domain” на порту 53.
Dot well-known
В DOTWELLKNOWN предлагается, чтобы службы искались через HTTP-запрос на /.well-known/i2pmail.key. Это требует, чтобы каждая услуга должна была иметь связанный сайт для размещения ключа. Большинство пользователей не запускают веб-сайты.
Одним из обходных путей является предположение, что услуга для адреса b32 фактически работает на этом адресе b32. Так что поиск службы для example.i2p требует HTTP-запроса с http://example.i2p/.well-known/i2pmail.key, но услуга для aaa…aaa.b32.i2p не требует этого поиска, он может просто подключиться напрямую.
Но здесь есть неясность, потому что example.i2p также может быть представлен своим b32.
MX Записи
Записи SRV — это просто универсальная версия MX записей для любой службы. “_smtp._tcp” является записью “MX”. MX записи не нужны, если у нас есть SRV записи, и одни только MX-записи не предоставляют универсальную запись для любой службы.
Дизайн
Записи служб помещаются в секцию опций в LS2 LS2. Секция опций LS2 в настоящее время не используется. Не поддерживается для LS1. Это похоже на предложение по пропускной способности туннеля Prop168, которое определяет опции для записей построения туннеля.
Для поиска адреса услуги для конкретного хоста или b32, роутер получает набор аренды и ищет запись службы в свойствах.
Услуга может быть размещена на том же адресе, что и сам LS, или может ссылаться на другой хостнейм/b32.
Если целевой адрес для службы отличается, целевой LS также должен включать запись службы, указывающую на себя, чтобы указать, что он поддерживает службу.
Дизайн не требует специальной поддержки или кэширования или каких-либо изменений во floodfills. Только издатель набора аренды и клиент, ищущий запись службы, должны поддерживать эти изменения.
Предлагаются незначительные расширения I2CP и SAM, чтобы облегчить получение записей служб клиентами.
Спецификация
Стандарт LS2 Option
Опции LS2 ДОЛЖНЫ быть отсортированы по ключу, чтобы подпись оставалась неизменной.
Определено следующим образом:
- serviceoption := optionkey optionvalue
- optionkey := _service._proto
- service := Символическое имя желаемой службы. Должно быть в нижнем регистре. Пример: “smtp”. Допустимые символы: [a-z0-9-] и не должны начинаться или заканчиваться с ‘-’. Должны быть использованы стандартные идентификаторы из REGISTRY или Linux /etc/services, если они там определены.
- proto := Протокол передачи желаемой услуги. Должен быть в нижнем регистре, либо “tcp”, либо “udp”. “tcp” означает потоковую передачу, а “udp” означает повторяемые дейтаграммы. Индикаторы протокола для сырых дейтаграмм и дейтаграмм2 могут быть определены позже. Допустимые символы: [a-z0-9-] и не должны начинаться или заканчиваться с ‘-’.
- optionvalue := self | srvrecord[,srvrecord]*
- self := “0” ttl port [appoptions]
- srvrecord := “1” ttl priority weight port target [appoptions]
- ttl := время жизни, целое количество секунд. Положительное целое число. Пример: “86400”. Минимум 86400 (один день) рекомендуется, подробнее см. в разделе Рекомендации ниже.
- priority := Приоритет целевого хоста, меньшие значения означают предпочтение. Неотрицательное целое число. Пример: “0” Полезно только если больше одной записи, но требуется, даже если только одна запись.
- weight := Относительный вес для записей с одинаковым приоритетом. Больше значение означает больше шансов быть выбранным. Неотрицательное целое число. Пример: “0” Полезно только если больше одной записи, но требуется, даже если только одна запись.
- port := Порт I2CP, на котором можно найти услугу. Неотрицательное целое число. Пример: “25” Порт 0 поддерживается, но не рекомендуется.
- target := Имя хоста или b32 адрес, предоставляющий услугу. Действительное имя хоста, как в NAMING. Должно быть в нижнем регистре. Пример: “aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p” или “example.i2p”. b32 рекомендуется, если имя хоста не “хорошо известно”, т.е. в официальных или стандартных адресных книгах.
- appoptions := произвольный текст, специфичный для приложения, не должен содержать " " или “,”. Кодировка UTF-8.
Примеры
В LS2 для aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, указывая на один SMTP сервер:
"_smtp._tcp" "1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p"
В LS2 для aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b32.i2p, указывая на два SMTP сервера:
"_smtp._tcp" "1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p,86400 1 0 25 cccccccccccccccccccccccccccccccccccccccccccc.b32.i2p"
В LS2 для bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p, указывая на себя как на SMTP сервер:
"_smtp._tcp" "0 999999 25"
Возможный формат для перенаправления почты (см. ниже):
"_smtp._tcp" "1 86400 0 0 25 smtp.postman.i2p example@mail.i2p"
Ограничения
Формат структуры данных Mapping, используемой для опций LS2, ограничивает ключи и значения до 255 байт (а не символов) максимум. С целью b32, «optionvalue» составляет около 67 байт, так что только 3 записи поместятся. Возможно, только одна или две с длинным полем appoptions, или до четырех или пяти с коротким именем хоста. Это должно быть достаточно; несколько записей должны быть редкостью.
Отличия от RFC2782
- Нет точек в конце
- Нет имени после протокола
- Обязательный нижний регистр
- В текстовом формате с записями, разделенными запятыми, а не в двоичном формате DNS
- Другие индикаторы типа записей
- Дополнительное поле appoptions
Примечания
Не допускаются никакие подстановочные символы, такие как (звездочка), (звездочка)._tcp или _tcp. Каждая поддерживаемая служба должна иметь свою запись.
Реестр имен служб
Нестандартные идентификаторы, не перечисленные в REGISTRY или Linux /etc/services, могут быть запрошены и добавлены в спецификацию общих структур LS2.
Форматы appoptions, специфичных для службы, также могут быть добавлены туда.
Спецификация I2CP
Протокол I2CP должен быть расширен, чтобы поддерживать поиски служб. Потребуются дополнительные коды ошибок MessageStatusMessage и/или HostReplyMessage, относящиеся к поиску служб. Чтобы сделать функцию поиска более широкой, а не только специфичной для записей службы, дизайн поддерживает получение всех опций LS2.
Реализация: Расширить HostLookupMessage для добавления запроса на LS2 опции для хеша, имени хоста и адресата (типы запросов 2-4). Расширить HostReplyMessage, чтобы добавить сопоставление опций, если запрошено. Расширить HostReplyMessage с дополнительными кодами ошибок.
Опции сопоставления могут быть кешированы или отрицательно кэшированы на короткое время как на стороне клиента, так и на стороне роутера, в зависимости от реализации. Рекомендуемое максимальное время — один час, если только время TTL записи службы не короче. Записи службы могут храниться в кэше до времени TTL, указанного приложением, клиентом или роутером.
Расширить спецификацию следующим образом:
Конфигурационные опции
Добавить следующее к [I2CP-OPTIONS]
i2cp.leaseSetOption.nnn
Опции, которые должны быть помещены в набор аренды. Доступны только для LS2. nnn начинается с 0. Значение опции содержит “ключ=значение”. (не включайте кавычки)
Пример:
i2cp.leaseSetOption.0=_smtp._tcp=1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p
Сообщение HostLookup
- Тип поиска 2: Поиск по хешу, запрос сопоставления опций
- Тип поиска 3: Поиск по имени хоста, запрос сопоставления опций
- Тип поиска 4: Поиск по адресату, запрос сопоставления опций
Для типа поиска 4, элемент 5 является Адресатом.
Сообщение HostReply
Для типов поиска 2-4 роутер должен получить набор аренды, даже если ключ поиска находится в адресной книге.
Если успешно, HostReply будет содержать сопоставление опций из набора аренды и включать его как элемент 5 после адресата. Если в Mapping нет опций или набор аренды был версии 1, он все равно будет включен как пустое Mapping (два байта: 0 0). Будут включены все опции из набора аренды, не только опции записи службы. Например, могут присутствовать опции для параметров, определенных в будущем.
При ошибке поиска набора аренды ответ будет содержать новый код ошибки 6 (Ошибка поиска набора аренды) и не будет включать сопоставление. Когда возвращается код ошибки 6, поле Адресат может присутствовать или отсутствовать. Оно будет присутствовать, если поиск по имени хоста в адресной книге был успешным, или если предыдущий поиск был успешным и результат был кэширован, или если Адресат был представлен в сообщении поиска (тип поиска 4).
Если тип поиска не поддерживается, ответ будет содержать новый код ошибки 7 (тип поиска не поддерживается).
Спецификация SAM
Протокол SAMv3 должен быть расширен для поддержки поисков служб.
Расширить NAMING LOOKUP следующим образом:
NAMING LOOKUP NAME=example.i2p OPTIONS=true запрашивает сопоставление опций в ответе.
NAME может быть полным адресом в формате base64, когда OPTIONS=true.
Если поиск адресата прошел успешно и опции присутствовали в наборе аренды, то в ответе, после адресата, будет одна или несколько опций в формате OPTION:key=value. Каждая опция будет иметь отдельный префикс OPTION:. Будут включены все опции из набора аренды, не только опции записи службы. Например, могут присутствовать опции для параметров, определенных в будущем. Пример:
NAMING REPLY RESULT=OK NAME=example.i2p VALUE=base64dest OPTION:_smtp._tcp="1 86400 0 0 25 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.b32.i2p"
Ключи, содержащие ‘=’, и ключи или значения, содержащие новую строку, считаются недопустимыми, и пара ключ/значение будет удалена из ответа.
Если в наборе аренды не найдено никаких опций, или если набор аренды был версии 1, то ответ не будет содержать никаких опций.
Если OPTIONS=true присутствовал в поиске, и набор аренды не найден, будет возвращено новое значение результата LEASESET_NOT_FOUND.
Альтернатива поиска имен
Был рассмотрен альтернативный дизайн, чтобы поддерживать поиски служб в виде полного имени хоста, например _smtp.tcp.example.i2p, обновив NAMING для указания обработки имен хостов, начинающихся с ‘’. Это было отклонено по двум причинам:
- Изменения в I2CP и SAM все равно были бы необходимы, чтобы передать через TTL и информацию о порте клиенту.
- Это не было бы общей функциональностью, которая могла бы использоваться для получения других LS2 опций, которые могут быть определены в будущем.
Рекомендации
Серверы должны указывать TTL не менее 86400, и стандартный порт для приложения.
Дополнительные возможности
Рекурсивные поиски
Может быть желательна поддержка рекурсивных поисков, когда каждый последующий набор аренды проверяется на наличие записи службы, указывающей на другой набор аренды, в стиле DNS. Вероятно, это не нужно, по крайней мере, в первоначальной реализации.
TODO
Специфические для приложения поля
Может быть желательным иметь в записи службы данные, специфичные для приложения. Например, оператор example.i2p может захотеть указать, чтобы электронная почта перенаправлялась на example@mail.i2p. “Пример@” часть должна быть в отдельном поле записи служб, либо удалена из цели.
Даже если оператор запускает свою собственную почтовую службу, он может захотеть указать, что электронная почта должна быть отправлена example@example.i2p. Большинство служб I2P работают одним человеком. Таким образом, здесь может быть полезно иметь отдельное поле.
TODO как это сделать в общем виде
Изменения, необходимые для электронной почты
За пределами сферы действия этого предложения. См. DOTWELLKNOWN для обсуждения.
Примечания по реализации
Кэширование записей служб до TTL может быть выполнено роутером или приложением, зависит от реализации. Кэшировать ли постоянно также зависит от реализации.
Поиски также должны искать целевой набор аренды и проверять, что он содержит “self” запись перед возвратом целевого адреса клиенту.
Анализ безопасности
Так как набор аренды подписан, любая запись служб в нем аутентифицирована ключом подписи адресата.
Записи служб являются общедоступными и видимы для floodfills, если только набор аренды не зашифрован. Любой роутер, запрашивающий набор аренды, сможет видеть записи служб.
Запись SRV, отличная от “self” (т.е. та, которая указывает на другой хостнейм/b32 адрес), не требует согласия цельного хостнейма/b32. Неясно, может ли перенаправление службы на произвольный адрес способствовать какой-либо атаке, и какова была бы цель такой атаки. Тем не менее, это предложение смягчает такую атаку, требуя, чтобы цель также публиковала “self” SRV запись. Реализации должны проверить наличие “self” записи в наборе аренды цели.
Совместимость
LS2: Нет проблем. Все известные реализации в настоящее время игнорируют поле опций в LS2, и правильно пропускают не пустое поле опций. Это было проверено на тестировании как Java I2P, так и i2pd во время разработки LS2. LS2 был реализован в 0.9.38 в 2016 году и хорошо поддерживается всеми реализациями роутеров. Дизайн не требует специальной поддержки или кэширования или каких-либо изменений во floodfills.
Naming: ‘_’ не является допустимым символом в i2p именах хостов.
I2CP: Типы поиска 2-4 не должны отправляться роутерам с API-версией ниже минимальной, в которой он поддерживается (определяется).
SAM: Java SAM сервер игнорирует дополнительные ключи/значения, такие как OPTIONS=true. i2pd должен также, необходимо проверить. SAM клиенты не получат дополнительные значения в ответе, если они не запрошены с OPTIONS=true. Увеличение версии не должно быть необходимо.