uploader-bot/docs/INTER_NODE_COMMUNICATION.md

515 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MY Network v3.0 - Межузловое общение с Ed25519
## Обзор
MY Network v3.0 использует криптографические подписи Ed25519 для безопасного межузлового общения. Каждая нода идентифицируется уникальным ключом Ed25519, что обеспечивает:
- **Аутентификацию**: Каждое сообщение подписано приватным ключом отправителя
- **Целостность**: Подпись гарантирует, что сообщение не было изменено
- **Идентификацию**: Node ID основан на публичном ключе в формате base58
- **Децентрализацию**: Ноды могут менять IP адреса, сохраняя постоянную идентичность
## Архитектура
```
┌─────────────────┐ Ed25519 Signature ┌─────────────────┐
│ Node A │◄──────────────────────────►│ Node B │
│ Private Key │ │ Public Key │
│ Public Key │ Signed Messages │ Verification │
│ Node ID │ │ Node ID │
└─────────────────┘ └─────────────────┘
```
## Настройка Ed25519 ключей
### Автоматическая генерация (рекомендуется)
При запуске через `start.sh` ключи генерируются автоматически:
```bash
curl -sSL https://raw.githubusercontent.com/username/uploader-bot/main/start.sh | bash
```
### Ручная генерация
```bash
# Создание директории для ключей
sudo mkdir -p /opt/my-network/keys
sudo chmod 700 /opt/my-network/keys
# Генерация ключей (выполняется в start.sh)
# Приватный ключ: /opt/my-network/keys/ed25519_private.key
# Публичный ключ: /opt/my-network/keys/ed25519_public.key
# Node ID: /opt/my-network/keys/node_id.txt
```
### Структура ключей
```
/opt/my-network/keys/
├── ed25519_private.key # Приватный ключ (64 символа hex)
├── ed25519_public.key # Публичный ключ (64 символа hex)
└── node_id.txt # Node ID (base58 от публичного ключа)
```
## API Endpoints для межузлового общения
### 1. Handshake - `/api/node/handshake`
Инициализация связи между нодами.
**Запрос:**
```http
POST /api/node/handshake
Content-Type: application/json
X-Node-Communication: true
X-Node-ID: 8x7KJmG5w2d3FhN9QpLmB4c6VzY3Xt2a
X-Node-Public-Key: a1b2c3d4e5f6...
X-Node-Signature: 1a2b3c4d5e6f...
{
"action": "handshake",
"node_info": {
"node_id": "8x7KJmG5w2d3FhN9QpLmB4c6VzY3Xt2a",
"version": "3.0.0",
"capabilities": [
"content_upload",
"content_sync",
"decentralized_filtering",
"ed25519_signatures"
],
"network_info": {
"public_key": "a1b2c3d4e5f6...",
"protocol_version": "1.0"
}
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
```
**Ответ:**
```json
{
"success": true,
"timestamp": "2024-01-15T10:30:01.000Z",
"node_id": "9y8LKnH6x3e4GiO0RqMnC5d7WaZ4Yu3b",
"data": {
"handshake_accepted": true,
"node_info": {
"node_id": "9y8LKnH6x3e4GiO0RqMnC5d7WaZ4Yu3b",
"version": "3.0.0",
"capabilities": [...],
"network_info": {...}
}
}
}
```
### 2. Content Sync - `/api/node/content/sync`
Синхронизация контента между нодами.
**Типы синхронизации:**
- `new_content` - Уведомление о новом контенте
- `content_list` - Запрос списка доступного контента
- `content_request` - Запрос конкретного файла
**Пример - Новый контент:**
```http
POST /api/node/content/sync
{
"action": "content_sync",
"sync_type": "new_content",
"content_info": {
"hash": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"title": "Example Video",
"size": 1048576,
"content_type": "video/mp4",
"timestamp": "2024-01-15T10:30:00.000Z"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
```
### 3. Network Ping - `/api/node/network/ping`
Проверка доступности и измерение задержки.
**Запрос:**
```http
POST /api/node/network/ping
{
"action": "ping",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {"test": true}
}
```
**Ответ:**
```json
{
"success": true,
"data": {
"action": "pong",
"ping_timestamp": "2024-01-15T10:30:00.000Z",
"response_timestamp": "2024-01-15T10:30:01.000Z"
}
}
```
### 4. Node Status - `/api/node/network/status`
Получение статуса ноды (GET запрос, подпись не требуется).
```http
GET /api/node/network/status
```
```json
{
"success": true,
"data": {
"node_id": "8x7KJmG5w2d3FhN9QpLmB4c6VzY3Xt2a",
"public_key": "a1b2c3d4e5f6...",
"version": "3.0.0",
"status": "active",
"capabilities": [...],
"timestamp": "2024-01-15T10:30:00.000Z"
}
}
```
### 5. Node Discovery - `/api/node/network/discover`
Обнаружение других нод в сети.
```http
POST /api/node/network/discover
{
"action": "discover",
"known_nodes": [
{"node_id": "...", "url": "http://node1.example.com:8000"},
{"node_id": "...", "url": "http://node2.example.com:8000"}
],
"timestamp": "2024-01-15T10:30:00.000Z"
}
```
## Использование клиентских функций
### Базовое использование
```python
from app.core.network.node_client import NodeClient, NodeNetworkManager
# Создание клиента
async with NodeClient() as client:
# Получение статуса ноды
status = await client.get_node_status("http://node.example.com:8000")
# Отправка пинга
ping_result = await client.send_ping("http://node.example.com:8000")
# Хэндшейк
our_node_info = {
"node_id": "our_node_id",
"version": "3.0.0",
"capabilities": ["content_upload", "content_sync"]
}
handshake_result = await client.send_handshake(
"http://node.example.com:8000",
our_node_info
)
```
### Менеджер сети
```python
from app.core.network.node_client import get_network_manager
# Получение менеджера
network_manager = await get_network_manager()
# Обнаружение нод
bootstrap_nodes = [
"http://bootstrap1.mynetwork.org:8000",
"http://bootstrap2.mynetwork.org:8000"
]
discovered_nodes = await network_manager.discover_nodes(bootstrap_nodes)
# Проверка здоровья нод
health_results = await network_manager.check_node_health(discovered_nodes)
# Трансляция нового контента
content_info = {
"hash": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"title": "New Video",
"size": 1048576,
"content_type": "video/mp4"
}
broadcast_results = await network_manager.broadcast_content(content_info)
```
## Подпись сообщений
### Формат подписи
1. **Сообщение**: JSON объект сериализуется в строку
2. **Подпись**: Ed25519 подпись от сериализованного JSON
3. **Заголовки**: Подпись и метаданные передаются в HTTP заголовках
### Обязательные заголовки для межузлового общения
```http
X-Node-Communication: true
X-Node-ID: <base58_node_id>
X-Node-Public-Key: <hex_public_key>
X-Node-Signature: <hex_signature>
```
### Пример создания подписи
```python
from app.core.crypto import get_ed25519_manager
crypto_manager = get_ed25519_manager()
# Сообщение
message = {
"action": "ping",
"timestamp": "2024-01-15T10:30:00.000Z",
"data": {"test": True}
}
# Создание подписи
signature = crypto_manager.sign_message(message)
# Заголовки
headers = {
"X-Node-Communication": "true",
"X-Node-ID": crypto_manager.node_id,
"X-Node-Public-Key": crypto_manager.public_key_hex,
"X-Node-Signature": signature
}
```
### Проверка подписи
```python
# Проверка подписи (выполняется автоматически в middleware)
is_valid = crypto_manager.verify_signature(
message, signature, public_key_hex
)
```
## Конфигурация
### Переменные окружения
```bash
# Пути к ключам (по умолчанию /opt/my-network/keys/)
MY_NETWORK_KEYS_DIR=/opt/my-network/keys
# Таймауты для межузлового общения
NODE_CLIENT_TIMEOUT=30
# Bootstrap ноды для обнаружения сети
MY_NETWORK_BOOTSTRAP_NODES=http://bootstrap1.mynetwork.org:8000,http://bootstrap2.mynetwork.org:8000
```
### Настройка в Docker
```yaml
# docker-compose.yml
version: '3.8'
services:
my-network-node:
image: my-network:latest
volumes:
- my_network_keys:/opt/my-network/keys
environment:
- MY_NETWORK_KEYS_DIR=/opt/my-network/keys
- NODE_CLIENT_TIMEOUT=30
ports:
- "8000:8000"
volumes:
my_network_keys:
```
## Безопасность
### Защита приватных ключей
1. **Файловые права**: `chmod 600 /opt/my-network/keys/ed25519_private.key`
2. **Владелец**: Только пользователь приложения имеет доступ
3. **Бэкапы**: Регулярное резервное копирование ключей
4. **Ротация**: Возможность смены ключей с сохранением истории
### Проверка подписей
```python
# Все входящие межузловые сообщения автоматически проверяются
# в CryptographicMiddleware
# Ручная проверка подписи
from app.core.crypto import get_ed25519_manager
crypto_manager = get_ed25519_manager()
is_valid = crypto_manager.verify_signature(message, signature, public_key)
if not is_valid:
raise SecurityError("Invalid message signature")
```
### Защита от replay-атак
1. **Timestamp**: Каждое сообщение содержит timestamp
2. **Nonce**: Опционально можно добавить nonce для дополнительной защиты
3. **TTL**: Сообщения имеют время жизни
## Диагностика и отладка
### Проверка состояния ключей
```bash
# Проверка наличия ключей
ls -la /opt/my-network/keys/
# Проверка Node ID
cat /opt/my-network/keys/node_id.txt
# Проверка прав доступа
stat /opt/my-network/keys/ed25519_private.key
```
### Логирование
```python
# Включение debug логов для криптографии
import logging
logging.getLogger('app.core.crypto').setLevel(logging.DEBUG)
# Включение debug логов для межузлового общения
logging.getLogger('app.core.network').setLevel(logging.DEBUG)
```
### Тестирование соединения
```bash
# Тест статуса ноды
curl http://localhost:8000/api/node/network/status
# Тест здоровья приложения
curl http://localhost:8000/health
```
### Проверка подписи вручную
```python
# Скрипт для тестирования подписей
import asyncio
from app.core.crypto import get_ed25519_manager
async def test_signature():
crypto_manager = get_ed25519_manager()
message = {"test": "message", "timestamp": "2024-01-15T10:30:00.000Z"}
signature = crypto_manager.sign_message(message)
is_valid = crypto_manager.verify_signature(
message, signature, crypto_manager.public_key_hex
)
print(f"Node ID: {crypto_manager.node_id}")
print(f"Signature valid: {is_valid}")
# Запуск теста
asyncio.run(test_signature())
```
## Примеры интеграции
### Добавление в существующие API
```python
# В вашем API endpoint
from app.core.network.node_client import get_network_manager
@app.post("/api/content/upload")
async def upload_content(request):
# ... обработка загрузки ...
# Уведомление других нод о новом контенте
network_manager = await get_network_manager()
content_info = {
"hash": content_hash,
"title": title,
"size": file_size,
"content_type": content_type,
"timestamp": datetime.utcnow().isoformat()
}
# Асинхронно уведомляем другие ноды
asyncio.create_task(
network_manager.broadcast_content(content_info)
)
return {"status": "uploaded", "hash": content_hash}
```
### Периодическая синхронизация
```python
# Фоновая задача для синхронизации
async def sync_with_network():
network_manager = await get_network_manager()
while True:
# Проверяем здоровье известных нод каждые 5 минут
await network_manager.check_node_health(network_manager.known_nodes)
# Попытка обнаружить новые ноды каждые 15 минут
if len(network_manager.active_nodes) < 3:
await network_manager.discover_nodes(bootstrap_nodes)
await asyncio.sleep(300) # 5 минут
# Добавление задачи в приложение
app.add_background_task(sync_with_network())
```
## Миграция и совместимость
### Обновление с предыдущих версий
1. **Backup существующих данных**
2. **Генерация новых ed25519 ключей**
3. **Обновление конфигурации**
4. **Тестирование подключения к сети**
### Совместимость версий
- **v3.0+**: Обязательные ed25519 подписи
- **v2.x**: Опциональные подписи (deprecated)
- **v1.x**: Без криптографической защиты (не поддерживается)
### План миграции
```bash
# 1. Остановка текущей версии
docker-compose down
# 2. Backup данных
tar -czf my-network-backup.tar.gz /opt/my-network/
# 3. Обновление до v3.0
curl -sSL https://raw.githubusercontent.com/username/uploader-bot/main/start.sh | bash
# 4. Проверка работоспособности
curl http://localhost:8000/health
curl http://localhost:8000/api/node/network/status
```
Данная интеграция обеспечивает полную криптографическую защиту межузлового общения в MY Network v3.0, гарантируя безопасность и децентрализованность сети.