429 lines
15 KiB
Markdown
429 lines
15 KiB
Markdown
# Montana Protocol — Security Specification
|
||
# Техническая спецификация защиты сети
|
||
|
||
**Version:** 2.0
|
||
**Status:** MAINNET
|
||
**Date:** 2026-01-23
|
||
**Authors:** Alejandro Montana
|
||
|
||
---
|
||
|
||
## Abstract
|
||
|
||
Montana Protocol представляет собой распределённую систему консенсуса, основанную на доказательстве присутствия во времени (Atemporal Coordinate Presence, ACP). Настоящая спецификация описывает криптографические, сетевые и программные защитные механизмы протокола.
|
||
|
||
Базовые защитные механизмы:
|
||
- **ML-DSA-65 (FIPS 204)** — постквантовая цифровая подпись
|
||
- **5-Node Leader Election** — распределённое управление без единой точки отказа
|
||
- **Attack Detection + Random Failover** — обнаружение атак и непредсказуемое переключение мастера
|
||
- **Breathing Sync** — git-синхронизация состояния сети
|
||
- **Temporal Coordinates (τ₁, τ₂, τ₃, τ₄)** — иерархические временные единицы
|
||
- **Halving Mechanism** — дефляционная эмиссия
|
||
- **AtlantGuard** — защита узла от ресурсных атак
|
||
|
||
---
|
||
|
||
## 1. Топология сети
|
||
|
||
### 1.1 Узлы сети
|
||
|
||
Montana Protocol функционирует на 5 географически распределённых узлах:
|
||
|
||
| Позиция | Узел | IP | Регион | Роль |
|
||
|---------|------|-----|--------|------|
|
||
| 0 | amsterdam | 72.56.102.240 | EU | PRIMARY |
|
||
| 1 | moscow | 176.124.208.93 | RU-Central | MIRROR 1 |
|
||
| 2 | almaty | 91.200.148.93 | KZ | MIRROR 2 |
|
||
| 3 | spb | 188.225.58.98 | RU-NW | MIRROR 3 |
|
||
| 4 | novosibirsk | 147.45.147.247 | RU-Siberia | MIRROR 4 |
|
||
|
||
**Исходный код:** [leader_election.py:39-46](Бот/leader_election.py#L39-L46)
|
||
|
||
```python
|
||
BOT_CHAIN: List[Tuple[str, str]] = [
|
||
("amsterdam", "72.56.102.240"),
|
||
("moscow", "176.124.208.93"),
|
||
("almaty", "91.200.148.93"),
|
||
("spb", "188.225.58.98"),
|
||
("novosibirsk", "147.45.147.247"),
|
||
]
|
||
```
|
||
|
||
### 1.2 Конфигурация узлов
|
||
|
||
Каждый узел идентифицируется через переменную окружения `MONTANA_NODE_NAME`:
|
||
|
||
```ini
|
||
[Service]
|
||
Environment="MONTANA_NODE_NAME=moscow"
|
||
Environment="PYTHONUNBUFFERED=1"
|
||
WatchdogSec=60
|
||
Restart=always
|
||
RestartSec=15
|
||
TimeoutStopSec=30
|
||
MemoryMax=512M
|
||
MemoryHigh=400M
|
||
```
|
||
|
||
**Исходный код:** [junona.service](Бот/junona.service)
|
||
|
||
---
|
||
|
||
## 2. Криптографическая безопасность
|
||
|
||
### 2.1 ML-DSA-65 (FIPS 204)
|
||
|
||
Montana Protocol использует постквантовый алгоритм подписи ML-DSA-65 (Module Lattice Digital Signature Algorithm), стандартизованный NIST как FIPS 204.
|
||
|
||
| Параметр | Значение |
|
||
|----------|----------|
|
||
| Алгоритм | ML-DSA-65 (Dilithium) |
|
||
| Стандарт | FIPS 204 |
|
||
| Уровень безопасности | NIST Level 3 |
|
||
| Private Key | 4032 байта |
|
||
| Public Key | 1952 байта |
|
||
| Signature | 3309 байт |
|
||
| Адрес | `mt` + SHA256(pubkey)[:20].hex() = 42 символа |
|
||
|
||
**Исходный код:** [node_crypto.py](Бот/node_crypto.py)
|
||
|
||
### 2.2 Формат адреса
|
||
|
||
```python
|
||
def generate_address(public_key: bytes) -> str:
|
||
"""Генерация Montana адреса из публичного ключа ML-DSA-65."""
|
||
hash_bytes = hashlib.sha256(public_key).digest()[:20]
|
||
return "mt" + hash_bytes.hex() # mt + 40 hex chars = 42 total
|
||
```
|
||
|
||
Пример адреса: `mt7a3f2e1d4c5b6a8f9e0d1c2b3a4f5e6d7c8b9a0`
|
||
|
||
---
|
||
|
||
## 3. Leader Election
|
||
|
||
### 3.1 Алгоритм выбора мастера
|
||
|
||
Детерминированный алгоритм определения активного мастера:
|
||
|
||
```python
|
||
def am_i_the_master(self) -> bool:
|
||
"""Проверяет, является ли текущий узел мастером."""
|
||
for name, ip in self.chain:
|
||
if name == self.node_name:
|
||
return True # Дошли до себя — я мастер
|
||
if check_node_health(ip):
|
||
return False # Узел выше жив — он мастер
|
||
return False
|
||
```
|
||
|
||
**Исходный код:** [leader_election.py:326-349](Бот/leader_election.py#L326-L349)
|
||
|
||
### 3.2 Health Check
|
||
|
||
Проверка здоровья узла выполняется через HTTP endpoint на порту 8889:
|
||
|
||
```python
|
||
def check_node_health(ip: str) -> bool:
|
||
"""Проверяет здоровье узла через HTTP health endpoint."""
|
||
try:
|
||
url = f"http://{ip}:8889/health"
|
||
response = requests.get(url, timeout=5)
|
||
return response.status_code == 200
|
||
except:
|
||
return False
|
||
```
|
||
|
||
**Исходный код:** [leader_election.py:102-134](Бот/leader_election.py#L102-L134)
|
||
|
||
### 3.3 Интервалы проверки
|
||
|
||
| Параметр | Значение | Назначение |
|
||
|----------|----------|------------|
|
||
| CHECK_INTERVAL | 5 сек | Интервал проверки здоровья узлов |
|
||
| STARTUP_DELAY | 7-15 сек | Задержка при старте (избежание конфликта polling) |
|
||
| FAILOVER_TIME | < 10 сек | Время переключения на резервный узел |
|
||
|
||
---
|
||
|
||
## 4. Обнаружение атак
|
||
|
||
### 4.1 AttackDetector
|
||
|
||
Класс `AttackDetector` отслеживает метрики, указывающие на атаку:
|
||
|
||
```python
|
||
class AttackDetector:
|
||
def __init__(self):
|
||
self.failure_count = 0
|
||
self.max_failures = 10
|
||
self.response_times = deque(maxlen=10)
|
||
self.cpu_threshold = 80.0
|
||
self.response_time_threshold = 5.0
|
||
self.network_threshold = 100 * 1024 * 1024 # 100 MB/s
|
||
self.under_attack = False
|
||
```
|
||
|
||
**Исходный код:** [leader_election.py:190-232](Бот/leader_election.py#L190-L232)
|
||
|
||
### 4.2 Метрики обнаружения атак
|
||
|
||
| Метрика | Порог | Действие |
|
||
|---------|-------|----------|
|
||
| CPU Usage | > 80% | Флаг атаки |
|
||
| Network Traffic | > 100 MB/s входящего | Флаг атаки |
|
||
| Failure Count | > 10 подряд | Флаг атаки |
|
||
| Response Time (avg) | > 5 секунд | Флаг атаки |
|
||
|
||
### 4.3 Random Failover при атаке
|
||
|
||
При обнаружении атаки цепочка узлов перемешивается случайным образом:
|
||
|
||
```python
|
||
def shuffle_chain_on_attack(self, external_trigger: bool = False):
|
||
"""Перемешивает цепочку при обнаружении атаки."""
|
||
if not self.attack_detector.is_under_attack() and not external_trigger:
|
||
return
|
||
|
||
logger.warning("АТАКА ОБНАРУЖЕНА! Переход на случайный failover")
|
||
|
||
shuffled = list(self.chain)
|
||
random.shuffle(shuffled)
|
||
|
||
healthy_nodes = [
|
||
(name, ip) for (name, ip) in shuffled
|
||
if check_node_health(ip)
|
||
]
|
||
|
||
if healthy_nodes:
|
||
self.chain = healthy_nodes
|
||
self.chain_shuffled = True
|
||
```
|
||
|
||
**Исходный код:** [leader_election.py:395-430](Бот/leader_election.py#L395-L430)
|
||
|
||
---
|
||
|
||
## 5. AtlantGuard — Защита узла
|
||
|
||
### 5.1 Архитектура
|
||
|
||
Класс `AtlantGuard` обеспечивает локальную защиту узла от ресурсных атак:
|
||
|
||
```python
|
||
class AtlantGuard:
|
||
def __init__(self):
|
||
self.start_time = time.time()
|
||
self.request_log = {}
|
||
self.registration_log = []
|
||
self.suspicious_ips = set()
|
||
self.blocked_ips = set()
|
||
self.cpu_history = [] # Буфер последних 5 измерений CPU
|
||
self.degraded_count = 0 # Счётчик высоких значений подряд
|
||
```
|
||
|
||
**Исходный код:** [junomontanaagibot.py:709-754](Бот/junomontanaagibot.py#L709-L754)
|
||
|
||
### 5.2 Health Check с защитой от ложных срабатываний
|
||
|
||
Метод `health_check()` использует скользящее среднее CPU для предотвращения ложных алертов:
|
||
|
||
```python
|
||
def health_check(self) -> Dict[str, Any]:
|
||
# Скользящее среднее CPU (последние 5 измерений)
|
||
cpu_instant = psutil.cpu_percent(interval=None)
|
||
self.cpu_history.append(cpu_instant)
|
||
if len(self.cpu_history) > 5:
|
||
self.cpu_history.pop(0)
|
||
cpu_avg = sum(self.cpu_history) / len(self.cpu_history)
|
||
|
||
# Защита от ложных спайков: требуем 3 подряд высоких значения
|
||
if cpu_avg > 90 or memory.percent > 90:
|
||
self.degraded_count += 1
|
||
if self.degraded_count >= 3:
|
||
status = "degraded"
|
||
else:
|
||
status = "healthy"
|
||
else:
|
||
status = "healthy"
|
||
self.degraded_count = 0
|
||
```
|
||
|
||
**Исходный код:** [junomontanaagibot.py:1001-1051](Бот/junomontanaagibot.py#L1001-L1051)
|
||
|
||
### 5.3 Пороги AtlantGuard
|
||
|
||
| Метрика | Порог | Статус |
|
||
|---------|-------|--------|
|
||
| CPU (среднее за 5 измерений) | > 90% | degraded (после 3 подряд) |
|
||
| Memory | > 90% | degraded (после 3 подряд) |
|
||
| Suspicious IPs | > 5 | degraded |
|
||
| Under attack flag | true | under_attack |
|
||
|
||
### 5.4 Rate Limiting
|
||
|
||
```python
|
||
MAX_REQUESTS_PER_MINUTE = 60 # Запросов/мин с одного источника
|
||
MAX_REGISTRATIONS_PER_HOUR = 20 # Новых регистраций/час
|
||
MAX_NODE_SYNCS_PER_MINUTE = 10 # Синхронизаций узла/мин
|
||
MAX_API_CALLS_PER_MINUTE = 100 # API вызовов/мин на endpoint
|
||
```
|
||
|
||
**Исходный код:** [junomontanaagibot.py:734-738](Бот/junomontanaagibot.py#L734-L738)
|
||
|
||
---
|
||
|
||
## 6. Breathing Sync
|
||
|
||
### 6.1 Механизм синхронизации
|
||
|
||
Git-синхронизация состояния сети каждые 12 секунд:
|
||
|
||
```
|
||
Цикл:
|
||
Вдох (Inhale) — git pull с rebase
|
||
↓
|
||
12 секунд работы
|
||
↓
|
||
Выдох (Exhale) — git add + commit + push
|
||
↓
|
||
Повтор
|
||
```
|
||
|
||
**Исходный код:** [breathing_sync.py](Бот/breathing_sync.py)
|
||
|
||
### 6.2 Интеграция с Leader Election
|
||
|
||
Breathing Sync активируется только для мастер-узла:
|
||
|
||
```python
|
||
only_when_master=True
|
||
is_master_func=lambda: self.is_master
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Временные координаты
|
||
|
||
### 7.1 Иерархия
|
||
|
||
| Единица | Длительность | Назначение |
|
||
|---------|--------------|------------|
|
||
| **τ₁** | 60 секунд | Интервал подписи Presence Proof |
|
||
| **τ₂** | 600 секунд (10 минут) | Слайс эмиссии |
|
||
| **τ₃** | 1,209,600 секунд (14 дней) | Checkpoint |
|
||
| **τ₄** | 126,144,000 секунд (4 года) | Эпоха халвинга |
|
||
|
||
### 7.2 Соотношения
|
||
|
||
```
|
||
1 τ₄ = 104 τ₃ = 209,664 τ₂ = 126,144,000 секунд
|
||
1 τ₃ = 2016 τ₂ = 1,209,600 секунд
|
||
1 τ₂ = 10 τ₁ = 600 секунд
|
||
```
|
||
|
||
**Исходный код:** [time_bank.py:44-80](Бот/time_bank.py#L44-L80)
|
||
|
||
---
|
||
|
||
## 8. TIME_BANK
|
||
|
||
### 8.1 Резерв
|
||
|
||
```python
|
||
BANK_TOTAL_MINUTES = 21_000_000 # 21 млн минут (~40 лет)
|
||
BANK_TOTAL_SECONDS = 1_260_000_000 # 1.26 млрд секунд
|
||
```
|
||
|
||
### 8.2 Halving
|
||
|
||
```python
|
||
def halving_coefficient(tau4_count: int) -> float:
|
||
"""Коэффициент халвинга для текущей эпохи."""
|
||
return 1.0 / (2 ** tau4_count)
|
||
```
|
||
|
||
| Эпоха τ₄ | Годы | Коэффициент | 1 секунда = |
|
||
|----------|------|-------------|-------------|
|
||
| 0 | 0-4 | 1.0 | 1.0 Ɉ |
|
||
| 1 | 4-8 | 0.5 | 0.5 Ɉ |
|
||
| 2 | 8-12 | 0.25 | 0.25 Ɉ |
|
||
| 3 | 12-16 | 0.125 | 0.125 Ɉ |
|
||
|
||
**Исходный код:** [time_bank.py:88-113](Бот/time_bank.py#L88-L113)
|
||
|
||
---
|
||
|
||
## 9. Синхронизация сети
|
||
|
||
### 9.1 Состояние на 2026-01-23
|
||
|
||
| Узел | MD5 Hash | Статус | Python | telegram-bot |
|
||
|------|----------|--------|--------|--------------|
|
||
| amsterdam | 5a0ac1903151eef7a85cd72f3060eb6c | active | 3.12.3 | 22.5 |
|
||
| moscow | 5a0ac1903151eef7a85cd72f3060eb6c | active | 3.12.3 | 22.5 |
|
||
| almaty | 5a0ac1903151eef7a85cd72f3060eb6c | active | 3.12.3 | 22.5 |
|
||
| spb | 5a0ac1903151eef7a85cd72f3060eb6c | active | 3.12.3 | 22.5 |
|
||
| novosibirsk | 5a0ac1903151eef7a85cd72f3060eb6c | active | 3.12.3 | 22.5 |
|
||
|
||
### 9.2 Деплой
|
||
|
||
Rolling deploy выполняется скриптом `deploy_nodes.sh`:
|
||
|
||
```bash
|
||
./deploy_nodes.sh # Rolling deploy (по одному)
|
||
./deploy_nodes.sh --fast # Быстрый deploy (опасно)
|
||
./deploy_nodes.sh --node moscow # Только один узел
|
||
```
|
||
|
||
**Исходный код:** [deploy_nodes.sh](Бот/deploy_nodes.sh)
|
||
|
||
---
|
||
|
||
## 10. Файловая структура
|
||
|
||
```
|
||
Монтана_Montana_蒙大拿/Русский/Бот/
|
||
├── junomontanaagibot.py # Главный бот (229 KB)
|
||
├── leader_election.py # Leader Election + AttackDetector
|
||
├── time_bank.py # TIME_BANK + Presence Proofs
|
||
├── node_crypto.py # ML-DSA-65 криптография
|
||
├── breathing_sync.py # Git синхронизация
|
||
├── montana_db.py # База данных + Event Sourcing
|
||
├── junona_ai.py # AI интеграция (OpenAI/Anthropic)
|
||
├── contracts.py # Смарт-контракты времени
|
||
├── deploy_nodes.sh # Скрипт деплоя
|
||
└── junona.service # Systemd unit
|
||
```
|
||
|
||
---
|
||
|
||
## 11. Известные ограничения
|
||
|
||
| Проблема | Severity | Статус |
|
||
|----------|----------|--------|
|
||
| Split-brain через local lock | HIGH | Требует distributed lock |
|
||
| tau4_count не персистит | MEDIUM | Сбрасывается при рестарте |
|
||
| time.time() может быть изменён root | LOW | Требует time.monotonic() + NTP |
|
||
| Presence Proofs не верифицируются | MEDIUM | Генерируются, но не проверяются |
|
||
|
||
---
|
||
|
||
## Заключение
|
||
|
||
Montana Protocol реализует многоуровневую защиту:
|
||
|
||
1. **Постквантовая криптография (ML-DSA-65)** — защита от квантовых компьютеров
|
||
2. **5-Node Leader Election** — отсутствие единой точки отказа
|
||
3. **AtlantGuard со скользящим средним** — защита от ложных алертов
|
||
4. **Random Failover** — непредсказуемость при атаке
|
||
5. **Breathing Sync** — консистентность состояния сети
|
||
|
||
---
|
||
|
||
```
|
||
Alejandro Montana
|
||
Montana Protocol Security Specification v2.0
|
||
2026-01-23
|
||
```
|