19 KiB
📝 Проектирование Hidden Services
Версия: 1.0
Дата: 23 ноября 2025
Статус: ✅ Завершено
Автор: Manus AI
1. Введение
Этот документ описывает архитектуру и протоколы для реализации Hidden Services (скрытых сервисов) в сети Phantom Protocol. Hidden Services позволяют пользователям публиковать и получать доступ к сервисам (например, веб-сайтам), не раскрывая их реальное местоположение (IP-адрес).
Цели:
- Обеспечить анонимность как для поставщика сервиса, так и для клиента.
- Использовать существующую Kademlia DHT для обнаружения сервисов.
- Минимизировать задержки при установке соединения.
- Обеспечить устойчивость к атакам на обнаружение и доступность.
2. Архитектура (Задача 1.1.2 ✅)
Архитектура Hidden Services состоит из четырех основных компонентов, которые взаимодействуют для обеспечения анонимности:
-
Скрытый Сервис (Hidden Service): Это серверное приложение, которое прослушивает трафик только внутри сети Phantom. Оно никогда не раскрывает свой IP-адрес и устанавливает исходящие анонимные туннели к нескольким точкам входа (Introduction Points), чтобы анонсировать свое существование.
-
Клиент (Client): Это приложение пользователя, которое инициирует соединение со скрытым сервисом. Клиент находит информацию о сервисе в DHT и анонимно договаривается о соединении через точку рандеву (Rendezvous Point).
-
Точка Рандеву (Rendezvous Point): Это любой узел в сети Phantom, выбранный клиентом для "встречи" со скрытым сервисом. Его основная задача - соединить два анонимных туннеля (от клиента и от сервиса), не зная ничего о конечных участниках.
-
Дескриптор Сервиса (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
Процесс Генерации Адреса
-
Генерация ключевой пары: Сервис генерирует долгосрочную ключевую пару для идентификации.
(public_key, private_key) = Ed25519_generate()
-
Хэширование публичного ключа: Для получения уникального идентификатора и сокращения длины используется хэширование.
hash = BLAKE2b-256(public_key)(BLAKE2b выбран за скорость и безопасность)
-
Добавление контрольной суммы: Для предотвращения опечаток добавляется контрольная сумма.
checksum = SHA256(SHA256(public_key))[0:2](первые 2 байта двойного хэша)payload = hash + checksum
-
Кодирование в Base32:
payloadкодируется в Base32 (RFC 4648) для удобства использования в DNS и URL.base32_payload = Base32_encode(payload)
-
Формирование адреса:
address = base32_payload + ".phantom"
4. Процессы Регистрации и Подключения
Процесс Регистрации Сервиса (Задача 1.1.5 ✅)
- Инициализация: Сервис генерирует свою ключевую пару Ed25519.
- Выбор Точек Входа: Сервис выбирает 3-5 надежных и хорошо подключенных узлов в сети в качестве своих точек входа (Introduction Points).
- Построение Туннелей: Сервис строит анонимные туннели к каждой из своих точек входа и поддерживает их в активном состоянии.
- Создание Дескриптора: Сервис создает дескриптор, содержащий его публичный ключ и список адресов точек входа.
- Подпись и Публикация: Сервис подписывает дескриптор своим приватным ключом и публикует его в DHT. Ключом для хранения в DHT является хэш публичного ключа сервиса.
- Перепубликация: Сервис периодически (например, каждые 60 минут) перепубликовывает свой дескриптор, чтобы он не истек в DHT.
Процесс Подключения Клиента (Задача 1.1.6 ✅)
- Получение Адреса: Клиент получает
.phantomадрес сервиса (например, через веб-сайт, мессенджер). - Запрос Дескриптора: Клиент декодирует адрес, извлекает хэш и запрашивает у DHT дескриптор по этому хэшу.
- Проверка Дескриптора: Клиент получает дескриптор и проверяет его подпись, используя публичный ключ из самого дескриптора.
- Выбор Точки Рандеву: Клиент выбирает случайный узел в сети в качестве точки рандеву (Rendezvous Point).
- Туннель к Рандеву: Клиент строит анонимный туннель к точке рандеву и отправляет ей одноразовый секрет (cookie), сгенерированный случайным образом.
- Отправка Сообщения: Клиент выбирает одну из точек входа из дескриптора и анонимно отправляет ей сообщение о рандеву (introduce message). Это сообщение зашифровано для публичного ключа сервиса и содержит адрес точки рандеву и тот же cookie.
- Пересылка Сервису: Точка входа пересылает сообщение сервису по ранее установленному туннелю.
- Туннель от Сервиса: Сервис расшифровывает сообщение, строит свой анонимный туннель к указанной точке рандеву и отправляет ей тот же cookie.
- Соединение: Точка рандеву, получив одинаковые 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. Открытые Вопросы
-
Защита от DoS-атак на точки входа: Как предотвратить флуд сообщениями о рандеву?
- Решение: Требовать небольшой proof-of-work (например, Hashcash) от клиента при отправке сообщения
Introduce1. Это будет реализовано в версии 2 протокола.
- Решение: Требовать небольшой proof-of-work (например, Hashcash) от клиента при отправке сообщения
-
Ротация точек входа: Как часто сервис должен менять свои точки входа для повышения анонимности?
- Решение: Сервис должен выбирать новые точки входа каждые 24 часа и публиковать обновленный дескриптор.
-
Хранение дескрипторов в DHT: Как обеспечить постоянное наличие дескрипторов в DHT?
- Решение: Сервис должен перепубликовывать свой дескриптор каждые 60 минут. Если сервис отключается, дескриптор автоматически истечет.
-
Балансировка нагрузки: Как распределить нагрузку между несколькими точками входа?
- Решение: Клиент должен выбирать точку входа из дескриптора случайным образом. Это обеспечивает простую и эффективную балансировку.
Конец документа