Обзор
Данная спецификация расширяет ленту подписки на адреса командами, чтобы позволить серверам имен транслировать обновления записей от владельцев имен хостов. Реализовано в версии 0.9.26, первоначально предложено в предложении 112.
Мотивация
Ранее серверы подписок hosts.txt просто отправляли данные в формате hosts.txt, который выглядит следующим образом:
example.i2p=b64destination
С этим есть несколько проблем:
- Владельцы имён хостов не могут обновить Destination, связанный с их именами хостов (например, для обновления ключа подписи на более стойкий тип).
- Владельцы имён хостов не могут произвольно отказаться от своих имён хостов; они должны передать соответствующие приватные ключи Destination напрямую новому владельцу.
- Не существует способа аутентифицировать, что поддомен контролируется соответствующим базовым именем хоста; в настоящее время это обеспечивается только индивидуально некоторыми серверами имён.
Дизайн
Данная спецификация добавляет ряд командных строк к формату hosts.txt. С помощью этих команд серверы имен могут расширить свои услуги для предоставления дополнительных функций. Клиенты, которые реализуют эту спецификацию, смогут получать эти функции через обычный процесс подписки.
Все командные строки должны быть подписаны соответствующим Destination. Это гарантирует, что изменения вносятся только по запросу владельца имени хоста.
Последствия для безопасности
Данная спецификация не влияет на анонимность.
Существует повышенный риск, связанный с потерей контроля над ключом Destination, поскольку тот, кто его получит, может использовать эти команды для внесения изменений в любые связанные имена хостов. Но это не больше проблема, чем текущее положение дел, когда тот, кто получает Destination, может выдать себя за имя хоста и (частично) перехватить его трафик. Повышенный риск также компенсируется предоставлением владельцам имён хостов возможности изменить Destination, связанный с именем хоста, в случае если они полагают, что Destination был скомпрометирован; это невозможно в текущей системе.
Спецификация
Новые типы строк
Есть два новых типа строк:
Команды добавления и изменения:
example.i2p=b64destination#!key1=val1#key2=val2 ...Команды удаления:
#!key1=val1#key2=val2 ...
Упорядочивание
Лента не обязательно упорядочена или полна. Например, команда изменения может находиться на строке перед командой добавления или без команды добавления.
Ключи могут быть в любом порядке. Дублирующиеся ключи не допускаются. Все ключи и значения чувствительны к регистру.
Общие ключи
Обязательно во всех командах:
sig : B64 подпись, использующая ключ подписи из назначения
Ссылки на второе имя хоста и/или назначение:
oldname : Второе имя хоста (новое или измененное)
olddest : Второй b64 destination (новый или изменённый)
oldsig : Вторая b64 подпись, использующая ключ подписи из olddest
Другие распространенные ключи:
action : Команда
name : Имя хоста, присутствует только если не предшествует example.i2p=b64dest
dest : B64 назначение, присутствует только если не предшествует example.i2p=b64dest
date : В секундах с начала эпохи
expires : В секундах с начала эпохи
Команды
Все команды, кроме команды “Add”, должны содержать ключ/значение action=command.
Для совместимости со старыми клиентами большинство команд предваряются example.i2p=b64dest, как отмечено ниже. Для изменений это всегда новые значения. Любые старые значения включены в секцию ключ/значение.
Перечисленные ключи являются обязательными. Все команды могут содержать дополнительные пары ключ/значение, не определенные здесь.
Добавить имя хоста
Перед example.i2p=b64dest : ДА, это новое имя хоста и destination.
action : НЕ включается, подразумевается.
sig : подпись
Пример:
example.i2p=b64dest#!sig=b64sig
Изменить имя хоста
Предшествует example.i2p=b64dest : ДА, это новое имя хоста и старое назначение.
action : changename
oldname : старое имя хоста, которое будет заменено
sig : подпись
Пример:
example.i2p=b64dest#!action=changename#oldname=oldhostname#sig=b64sig
Изменить назначение
Предшествует example.i2p=b64dest : ДА, это старое имя хоста и новое назначение.
action : changedest
olddest : старый dest, который будет заменен
oldsig : подпись с использованием olddest
sig : подпись
Пример:
example.i2p=b64dest#!action=changedest#olddest=oldb64dest#oldsig=b64sig#sig=b64sig
Добавить псевдоним имени хоста
Предшествует example.i2p=b64dest : ДА, это новое (псевдоним) имя хоста и старое назначение.
action : addname
oldname : старое имя хоста
sig : подпись
Пример:
example.i2p=b64dest#!action=addname#oldname=oldhostname#sig=b64sig
Добавить псевдоним назначения
(Используется для обновления криптографии)
Предшествует example.i2p=b64dest : ДА, это старое имя хоста и новое (альтернативное) назначение.
action : adddest
olddest : старый dest
oldsig : подпись с использованием olddest
sig : подпись с использованием dest
Пример:
example.i2p=b64dest#!action=adddest#olddest=oldb64dest#oldsig=b64sig#sig=b64sig
Добавить поддомен
Предшествует subdomain.example.i2p=b64dest : ДА, это новое имя поддомена хоста и назначение.
action : addsubdomain
oldname : имя хоста верхнего уровня (example.i2p)
olddest : назначение более высокого уровня (например, example.i2p)
oldsig : подпись с использованием olddest
sig : подпись, использующая dest
Пример:
subdomain.example.i2p=b64dest#!action=addsubdomain#oldname=example.i2p#olddest=oldb64dest#oldsig=b64sig#sig=b64sig
Обновить метаданные
Предшествует example.i2p=b64dest : ДА, это старое имя хоста и назначение.
action : update
sig : подпись
(добавьте сюда любые обновленные ключи)
Пример:
example.i2p=b64dest#!action=update#k1=v1#k2=v2#sig=b64sig
Удалить имя хоста
Предваряется example.i2p=b64dest : НЕТ, они указываются в опциях
action : remove
name : имя хоста
dest : место назначения
sig : подпись
Пример:
#!action=remove#name=example.i2p#dest=b64dest#sig=b64sig
Удалить все с этим назначением
Предшествует example.i2p=b64dest : НЕТ, они указываются в опциях
action : removeall
name : старое имя хоста, только для справки
dest : старый dest, все записи с этим dest удаляются
sig : подпись
Пример:
#!action=removeall#name=example.i2p#dest=b64dest#sig=b64sig
Подписи
Все команды должны содержать ключ/значение подписи sig=b64signature, где подпись предназначена для других данных, используя ключ подписи назначения.
Для команд, включающих старое и новое назначение, также должна быть oldsig=b64signature и либо oldname, либо olddest, либо и то, и другое.
В команде Add или Change открытый ключ для верификации находится в Destination, который нужно добавить или изменить.
В некоторых командах добавления или редактирования может быть указано дополнительное destination, например при добавлении псевдонима или изменении destination или имени хоста. В таком случае должна быть включена вторая подпись, и обе должны быть проверены. Вторая подпись является “внутренней” подписью и подписывается и проверяется первой (исключая “внешнюю” подпись). Клиент должен предпринять любые дополнительные действия, необходимые для проверки и принятия изменений.
oldsig всегда является “внутренней” подписью. Подписывайте и проверяйте без присутствия ключей ‘oldsig’ или ‘sig’. sig всегда является “внешней” подписью. Подписывайте и проверяйте с присутствующим ключом ‘oldsig’, но без ключа ‘sig’.
Входные данные для подписей
Для генерации байтового потока для создания или проверки подписи выполните сериализацию следующим образом:
- Удалите ключ “sig”
- Если проверяете с oldsig, также удалите ключ “oldsig”
- Только для команд Add или Change выведите
example.i2p=b64dest - Если остаются какие-либо ключи, выведите
#! - Отсортируйте опции по ключу UTF-8, завершите с ошибкой при дублирующихся ключах
- Для каждой пары ключ/значение выведите
key=value, за которой следует (если это не последняя пара ключ/значение) символ#
Примечания:
- Не выводить символ новой строки
- Кодировка вывода UTF-8
- Вся кодировка destination и подписей в Base 64 с использованием алфавита I2P
- Ключи и значения чувствительны к регистру
- Имена хостов должны быть в нижнем регистре
Совместимость
Все новые строки в формате hosts.txt реализованы с использованием ведущих символов комментариев, поэтому все старые версии I2P будут интерпретировать новые команды как комментарии.
Когда I2P router обновляются до новой спецификации, они не будут повторно интерпретировать старые комментарии, но начнут прослушивать новые команды при последующих загрузках своих лент подписок. Поэтому важно, чтобы серверы имён каким-либо образом сохраняли записи команд или включали поддержку etag, чтобы router могли получать все прошлые команды.