# 📝 Проектирование 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. Она содержит публичный ключ сервиса и адреса его точек входа, позволяя клиентам инициировать соединение. ### Диаграмма Архитектуры ```mermaid 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):** ```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):** ```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) ```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` ```c #ifndef PHANTOM_HIDDEN_SERVICE_H #define PHANTOM_HIDDEN_SERVICE_H #include #include #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 ✅) ### Публикация Сервиса ```mermaid 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 ``` ### Подключение Клиента ```mermaid 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 недели)** - [x] Создать этот документ - [x] Описать архитектуру - [x] Определить формат адреса - [x] Спроектировать протокол рандеву - [x] Описать процесс регистрации сервиса - [x] Описать процесс подключения клиента - [x] Определить структуры данных - [x] Создать диаграммы последовательности **Задача 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. **Балансировка нагрузки:** Как распределить нагрузку между несколькими точками входа? - *Решение:* Клиент должен выбирать точку входа из дескриптора случайным образом. Это обеспечивает простую и эффективную балансировку. --- **Конец документа**