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