Files
Phantom/workspace/phantom-protocol-2025-release/docs/hidden-services-design.md

19 KiB
Raw Permalink Blame History

📝 Проектирование Hidden Services

Версия: 1.0
Дата: 23 ноября 2025
Статус: Завершено
Автор: Manus AI


1. Введение

Этот документ описывает архитектуру и протоколы для реализации Hidden Services (скрытых сервисов) в сети Phantom Protocol. Hidden Services позволяют пользователям публиковать и получать доступ к сервисам (например, веб-сайтам), не раскрывая их реальное местоположение (IP-адрес).

Цели:

  • Обеспечить анонимность как для поставщика сервиса, так и для клиента.
  • Использовать существующую Kademlia DHT для обнаружения сервисов.
  • Минимизировать задержки при установке соединения.
  • Обеспечить устойчивость к атакам на обнаружение и доступность.

2. Архитектура (Задача 1.1.2 )

Архитектура Hidden Services состоит из четырех основных компонентов, которые взаимодействуют для обеспечения анонимности:

  1. Скрытый Сервис (Hidden Service): Это серверное приложение, которое прослушивает трафик только внутри сети Phantom. Оно никогда не раскрывает свой IP-адрес и устанавливает исходящие анонимные туннели к нескольким точкам входа (Introduction Points), чтобы анонсировать свое существование.

  2. Клиент (Client): Это приложение пользователя, которое инициирует соединение со скрытым сервисом. Клиент находит информацию о сервисе в DHT и анонимно договаривается о соединении через точку рандеву (Rendezvous Point).

  3. Точка Рандеву (Rendezvous Point): Это любой узел в сети Phantom, выбранный клиентом для "встречи" со скрытым сервисом. Его основная задача - соединить два анонимных туннеля (от клиента и от сервиса), не зная ничего о конечных участниках.

  4. Дескриптор Сервиса (Service Descriptor): Это небольшая структура данных, подписанная скрытым сервисом и опубликованная в Kademlia DHT. Она содержит публичный ключ сервиса и адреса его точек входа, позволяя клиентам инициировать соединение.

Диаграмма Архитектуры

graph TD
    subgraph "Клиент"
        C[Клиент]
    end

    subgraph "Скрытый Сервис"
        HS[Сервис]
    end

    subgraph "Phantom Сеть"
        DHT[Kademlia DHT]
        RP[Точка Рандеву]
        IP1[Точка входа 1]
        IP2[Точка входа 2]
    end

    C -- "1. Запрос дескриптора по .phantom адресу" --> DHT
    DHT -- "2. Возврат дескриптора" --> C
    HS -- "3. Периодическая публикация дескриптора" --> DHT
    HS -- "4. Создание туннеля к точке входа" --> IP1
    C -- "5. Создание туннеля к точке рандеву" --> RP
    RP -- "6. Сообщение о рандеву (Introduce1)" --> IP1
    IP1 -- "7. Передача сообщения сервису" --> HS
    HS -- "8. Создание туннеля к точке рандеву" --> RP
    C <-. "9. Установлено анонимное соединение" .-> HS

3. Формат .phantom Адреса (Задача 1.1.3 )

.phantom адрес - это человекочитаемый и безопасный идентификатор скрытого сервиса. Он является производным от его постоянного публичного ключа.

Формат: [52-символьный Base32-хэш].phantom

Пример: v4vyh26w7qf5g3z4v3h2g5g3z4v3h2g5v4vyh26w7qf5g3z4v3h2g.phantom

Процесс Генерации Адреса

  1. Генерация ключевой пары: Сервис генерирует долгосрочную ключевую пару для идентификации.

    • (public_key, private_key) = Ed25519_generate()
  2. Хэширование публичного ключа: Для получения уникального идентификатора и сокращения длины используется хэширование.

    • hash = BLAKE2b-256(public_key) (BLAKE2b выбран за скорость и безопасность)
  3. Добавление контрольной суммы: Для предотвращения опечаток добавляется контрольная сумма.

    • checksum = SHA256(SHA256(public_key))[0:2] (первые 2 байта двойного хэша)
    • payload = hash + checksum
  4. Кодирование в Base32: payload кодируется в Base32 (RFC 4648) для удобства использования в DNS и URL.

    • base32_payload = Base32_encode(payload)
  5. Формирование адреса:

    • address = base32_payload + ".phantom"

4. Процессы Регистрации и Подключения

Процесс Регистрации Сервиса (Задача 1.1.5 )

  1. Инициализация: Сервис генерирует свою ключевую пару Ed25519.
  2. Выбор Точек Входа: Сервис выбирает 3-5 надежных и хорошо подключенных узлов в сети в качестве своих точек входа (Introduction Points).
  3. Построение Туннелей: Сервис строит анонимные туннели к каждой из своих точек входа и поддерживает их в активном состоянии.
  4. Создание Дескриптора: Сервис создает дескриптор, содержащий его публичный ключ и список адресов точек входа.
  5. Подпись и Публикация: Сервис подписывает дескриптор своим приватным ключом и публикует его в DHT. Ключом для хранения в DHT является хэш публичного ключа сервиса.
  6. Перепубликация: Сервис периодически (например, каждые 60 минут) перепубликовывает свой дескриптор, чтобы он не истек в DHT.

Процесс Подключения Клиента (Задача 1.1.6 )

  1. Получение Адреса: Клиент получает .phantom адрес сервиса (например, через веб-сайт, мессенджер).
  2. Запрос Дескриптора: Клиент декодирует адрес, извлекает хэш и запрашивает у DHT дескриптор по этому хэшу.
  3. Проверка Дескриптора: Клиент получает дескриптор и проверяет его подпись, используя публичный ключ из самого дескриптора.
  4. Выбор Точки Рандеву: Клиент выбирает случайный узел в сети в качестве точки рандеву (Rendezvous Point).
  5. Туннель к Рандеву: Клиент строит анонимный туннель к точке рандеву и отправляет ей одноразовый секрет (cookie), сгенерированный случайным образом.
  6. Отправка Сообщения: Клиент выбирает одну из точек входа из дескриптора и анонимно отправляет ей сообщение о рандеву (introduce message). Это сообщение зашифровано для публичного ключа сервиса и содержит адрес точки рандеву и тот же cookie.
  7. Пересылка Сервису: Точка входа пересылает сообщение сервису по ранее установленному туннелю.
  8. Туннель от Сервиса: Сервис расшифровывает сообщение, строит свой анонимный туннель к указанной точке рандеву и отправляет ей тот же cookie.
  9. Соединение: Точка рандеву, получив одинаковые cookie от клиента и сервиса, "соединяет" их туннели. Теперь трафик может течь между клиентом и сервисом анонимно в обе стороны.

5. Протокол Рандеву (Задача 1.1.4 )

Протокол рандеву - это ядро установки соединения. Он состоит из двух ключевых сообщений.

Сообщение о Рандеву (Introduce1)

Отправляется от клиента к точке входа, зашифровано для публичного ключа сервиса.

Содержимое (Protobuf):

// Файл: protos/hidden_service.proto

message Introduce1 {
    // Адрес точки рандеву (фантомный адрес)
    bytes rendezvous_address = 1;

    // Одноразовый секрет (cookie, 32 байта), сгенерированный клиентом
    bytes rendezvous_cookie = 2;

    // Публичный ключ клиента для DH-обмена (X25519)
    bytes client_dh_public_key = 3;
}

Сообщение о Рандеву (Rendezvous1)

Отправляется от скрытого сервиса к точке рандеву.

Содержимое (Protobuf):

// Файл: protos/hidden_service.proto

message Rendezvous1 {
    // Тот же одноразовый секрет, что и в Introduce1
    bytes rendezvous_cookie = 1;

    // Публичный ключ сервиса для DH-обмена (X25519)
    bytes service_dh_public_key = 2;
}

6. Структуры Данных (Задача 1.1.7 )

Дескриптор Сервиса (Protobuf)

// Файл: protos/hidden_service.proto

syntax = "proto3";

package phantom;

message ServiceDescriptor {
    // Публичный ключ сервиса (Ed25519, 32 байта)
    bytes public_key = 1;

    // Список точек входа
    repeated IntroductionPoint introduction_points = 2;

    // Версия протокола (например, 1)
    uint32 protocol_version = 3;

    // Временная метка создания (Unix timestamp)
    uint64 timestamp = 4;

    // Подпись (public_key, introduction_points, protocol_version, timestamp)
    bytes signature = 5;
}

message IntroductionPoint {
    // Адрес узла (фантомный адрес)
    bytes address = 1;

    // Публичный ключ для шифрования сообщений от клиента (X25519)
    bytes encryption_key = 2;
}

phantom_hidden_service.h

#ifndef PHANTOM_HIDDEN_SERVICE_H
#define PHANTOM_HIDDEN_SERVICE_H

#include <openssl/evp.h>
#include <stdint.h>
#include "kademlia.h"

#define PHANTOM_HS_ADDRESS_LEN 52
#define PHANTOM_HS_COOKIE_LEN 32
#define PHANTOM_HS_MAX_INTRO_POINTS 5

// Структура для хранения информации о точке входа
typedef struct {
    phantom_address_t address;      // Фантомный адрес точки входа
    EVP_PKEY *encryption_key;       // Ключ шифрования X25519
    // ... информация о туннеле
} phantom_intro_point_t;

// Структура для хранения информации о скрытом сервисе
typedef struct {
    // Постоянные ключи сервиса
    EVP_PKEY *identity_key; // Ed25519

    // .phantom адрес
    char address[PHANTOM_HS_ADDRESS_LEN + 9]; // + .phantom + null

    // Список точек входа
    phantom_intro_point_t intro_points[PHANTOM_HS_MAX_INTRO_POINTS];
    int num_intro_points;

    // ... информация о потоках, состоянии и т.д.

} phantom_hidden_service_t;

// Функции

/**
 * @brief Создает и инициализирует новый скрытый сервис
 * @return Указатель на структуру сервиса или NULL при ошибке
 */
phantom_hidden_service_t* phantom_hs_create();

/**
 * @brief Публикует дескриптор сервиса в DHT
 * @param service Указатель на структуру сервиса
 * @param dht Указатель на экземпляр Kademlia DHT
 * @return 0 при успехе, -1 при ошибке
 */
int phantom_hs_publish(phantom_hidden_service_t *service, kademlia_dht_t *dht);

/**
 * @brief Запускает прослушивание входящих соединений от точек входа
 * @param service Указатель на структуру сервиса
 * @return 0 при успехе, -1 при ошибке
 */
int phantom_hs_listen(phantom_hidden_service_t *service);

#endif // PHANTOM_HIDDEN_SERVICE_H

7. Диаграммы Последовательности (Задача 1.1.8 )

Публикация Сервиса

sequenceDiagram
    participant HS as Скрытый Сервис
    participant IP as Точка Входа
    participant DHT as Kademlia DHT

    HS->>HS: 1. Генерация identity_key (Ed25519)
    HS->>IP: 2. Установка анонимного туннеля
    HS->>HS: 3. Создание дескриптора (с адресом IP)
    HS->>HS: 4. Подпись дескриптора своим identity_key
    HS->>DHT: 5. Публикация дескриптора (PUT)
    Note right of DHT: Хранится 1 час
    loop Каждые 60 минут
        HS->>DHT: Перепубликация дескриптора
    end

Подключение Клиента

sequenceDiagram
    participant C as Клиент
    participant DHT as Kademlia DHT
    participant IP as Точка Входа
    participant RP as Точка Рандеву
    participant HS as Скрытый Сервис

    C->>DHT: 1. Запрос дескриптора (GET)
    DHT-->>C: 2. Возврат дескриптора
    C->>C: 3. Проверка подписи дескриптора
    C->>RP: 4. Установка туннеля и отправка cookie
    C->>IP: 5. Отправка Introduce1 (зашифровано для HS)
    IP->>HS: 6. Пересылка зашифрованного сообщения
    HS->>HS: 7. Расшифровка, проверка cookie
    HS->>RP: 8. Установка туннеля и отправка того же cookie
    RP->>RP: 9. Сравнение cookie от C и HS
    Note over RP: Cookie совпали, соединяем туннели
    C-->>HS: 10. Обмен данными по анонимному туннелю

8. План Реализации

Задача 1.1: Проектирование (2 недели)

  • Создать этот документ
  • Описать архитектуру
  • Определить формат адреса
  • Спроектировать протокол рандеву
  • Описать процесс регистрации сервиса
  • Описать процесс подключения клиента
  • Определить структуры данных
  • Создать диаграммы последовательности

Задача 1.2: Реализация phantom_hidden_service.c (6-8 недель)

  • Реализовать phantom_hs_create()
  • Реализовать генерацию адреса
  • Реализовать создание дескриптора
  • Реализовать phantom_hs_publish()
  • Реализовать phantom_hs_listen()

Задача 1.3: Реализация клиентской части (4-6 недель)

  • Реализовать phantom_client_connect_hs()
  • Реализовать запрос дескриптора
  • Реализовать протокол рандеву

Задача 1.4: Тестирование (2 недели)

  • Написать unit-тесты
  • Написать интеграционные тесты
  • Протестировать реальный сценарий (веб-сервер)

9. Открытые Вопросы

  1. Защита от DoS-атак на точки входа: Как предотвратить флуд сообщениями о рандеву?

    • Решение: Требовать небольшой proof-of-work (например, Hashcash) от клиента при отправке сообщения Introduce1. Это будет реализовано в версии 2 протокола.
  2. Ротация точек входа: Как часто сервис должен менять свои точки входа для повышения анонимности?

    • Решение: Сервис должен выбирать новые точки входа каждые 24 часа и публиковать обновленный дескриптор.
  3. Хранение дескрипторов в DHT: Как обеспечить постоянное наличие дескрипторов в DHT?

    • Решение: Сервис должен перепубликовывать свой дескриптор каждые 60 минут. Если сервис отключается, дескриптор автоматически истечет.
  4. Балансировка нагрузки: Как распределить нагрузку между несколькими точками входа?

    • Решение: Клиент должен выбирать точку входа из дескриптора случайным образом. Это обеспечивает простую и эффективную балансировку.

Конец документа