uploader-bot/docs/INTER_NODE_COMMUNICATION.md

15 KiB
Raw Permalink Blame History

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 ключи генерируются автоматически:

curl -sSL https://raw.githubusercontent.com/username/uploader-bot/main/start.sh | 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

Инициализация связи между нодами.

Запрос:

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"
}

Ответ:

{
  "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 - Запрос конкретного файла

Пример - Новый контент:

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

Проверка доступности и измерение задержки.

Запрос:

POST /api/node/network/ping
{
  "action": "ping",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "data": {"test": true}
}

Ответ:

{
  "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 запрос, подпись не требуется).

GET /api/node/network/status
{
  "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

Обнаружение других нод в сети.

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"
}

Использование клиентских функций

Базовое использование

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
    )

Менеджер сети

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 заголовках

Обязательные заголовки для межузлового общения

X-Node-Communication: true
X-Node-ID: <base58_node_id>
X-Node-Public-Key: <hex_public_key>
X-Node-Signature: <hex_signature>

Пример создания подписи

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
}

Проверка подписи

# Проверка подписи (выполняется автоматически в middleware)
is_valid = crypto_manager.verify_signature(
    message, signature, public_key_hex
)

Конфигурация

Переменные окружения

# Пути к ключам (по умолчанию /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

# 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. Ротация: Возможность смены ключей с сохранением истории

Проверка подписей

# Все входящие межузловые сообщения автоматически проверяются
# в 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: Сообщения имеют время жизни

Диагностика и отладка

Проверка состояния ключей

# Проверка наличия ключей
ls -la /opt/my-network/keys/

# Проверка Node ID
cat /opt/my-network/keys/node_id.txt

# Проверка прав доступа
stat /opt/my-network/keys/ed25519_private.key

Логирование

# Включение debug логов для криптографии
import logging
logging.getLogger('app.core.crypto').setLevel(logging.DEBUG)

# Включение debug логов для межузлового общения  
logging.getLogger('app.core.network').setLevel(logging.DEBUG)

Тестирование соединения

# Тест статуса ноды
curl http://localhost:8000/api/node/network/status

# Тест здоровья приложения
curl http://localhost:8000/health

Проверка подписи вручную

# Скрипт для тестирования подписей
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

# В вашем 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}

Периодическая синхронизация

# Фоновая задача для синхронизации
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: Без криптографической защиты (не поддерживается)

План миграции

# 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, гарантируя безопасность и децентрализованность сети.