montana/Русский/Технологии/003_ТРОЙНОЕ_ЗЕРКАЛО.md

246 lines
7.0 KiB
Markdown
Raw Permalink Normal View History

# 3-Mirror System
**Отказоустойчивая сеть Montana**
**Montana Protocol v1.0**
---
## Abstract
3-Mirror — распределённая система из 5 узлов с автоматическим failover. При падении любых 4 из 5 узлов сеть продолжает работать. Время восстановления < 10 секунд.
**Ключевая формула:**
```
4/5 узлов могут упасть = сеть жива
Восстановление < 10 секунд
```
---
## 1. Архитектура
### 1.1 Цепочка узлов
**Исходный код:** [leader_election.py](../бот/leader_election.py)
```python
BOT_CHAIN = [
("amsterdam", "72.56.102.240"), # PRIMARY
("moscow", "176.124.208.93"), # MIRROR 1
("almaty", "91.200.148.93"), # MIRROR 2
("spb", "188.225.58.98"), # MIRROR 3
("novosibirsk", "147.45.147.247"), # MIRROR 4
]
```
### 1.2 Роли узлов
| Роль | Узел | IP | Функция |
|------|------|----|---------|
| PRIMARY | Amsterdam | 72.56.102.240 | Активный бот |
| MIRROR 1 | Moscow | 176.124.208.93 | Standby |
| MIRROR 2 | Almaty | 91.200.148.93 | Standby |
| MIRROR 3 | SPB | 188.225.58.98 | Standby |
| MIRROR 4 | Novosibirsk | 147.45.147.247 | Standby |
---
## 2. Leader Election
### 2.1 Детерминированный выбор лидера
**Исходный код:** [leader_election.py](../бот/leader_election.py)
```python
def am_i_the_master(self) -> bool:
"""
Я мастер если ВСЕ узлы ДО меня в цепочке мертвы.
"""
for i, (name, ip) in enumerate(self.chain):
if name == self.my_name:
return True # Дошли до себя — я мастер
if check_node_health(ip):
return False # Кто-то выше жив
return False
```
### 2.2 Константы мониторинга
```python
CHECK_INTERVAL = 5 # секунд между проверками
PING_TIMEOUT = 2 # секунд таймаут пинга
STARTUP_DELAY = 3 # секунд перед первой проверкой
```
---
## 3. Failover Protocol
### 3.1 Сценарий падения Amsterdam
```
1. Amsterdam падает
2. Moscow проверяет каждые 5 сек: "Amsterdam жив?"
3. Через 5 сек: Amsterdam мёртв → Moscow становится MASTER
4. Almaty/SPB/Novosibirsk: Moscow жив → остаются STANDBY
```
### 3.2 Сценарий восстановления Amsterdam
```
1. Amsterdam поднимается
2. Moscow проверяет: "Amsterdam жив?"
3. Да → Moscow останавливает polling → STANDBY
4. Amsterdam запускает polling → MASTER
```
---
## 4. Проверка здоровья узла
**Исходный код:** [leader_election.py](../бот/leader_election.py)
```python
def check_node_health(ip: str) -> bool:
"""Комплексная проверка здоровья узла"""
# 1. ICMP ping
if is_node_alive(ip):
return True
# 2. TCP port 22 (SSH)
if is_node_alive_tcp(ip, 22):
return True
# 3. TCP port 443 (HTTPS)
if is_node_alive_tcp(ip, 443):
return True
return False
```
---
## 5. Интеграция с ботом
**Исходный код:** [junomontanaagibot.py](../бот/junomontanaagibot.py)
```python
async def run_with_3mirror():
leader = get_leader_election()
await leader.run_leader_loop(
on_become_master=start_polling,
on_become_standby=stop_polling
)
```
---
## 6. Деплой
### 6.1 Systemd service
```bash
# /etc/systemd/system/junona.service
Environment="MONTANA_NODE_NAME=amsterdam"
```
### 6.2 Скрипт деплоя
**Исходный код:** [deploy_nodes.sh](../бот/deploy_nodes.sh)
```bash
./deploy_nodes.sh
```
---
## 7. Breathing Sync — Git синхронизация
### 7.1 Механизм
**Исходный код:** [breathing_sync.py](../бот/breathing_sync.py)
```python
# Каждые 12 секунд узлы "дышат"
SYNC_INTERVAL_SEC = 12
def breathe():
inhale() # git pull — получаем изменения
exhale() # git push — отправляем свои изменения
```
### 7.2 Метафора дыхания
```
┌─────────────────────────────────────────────────────────────┐
│ BREATHING CYCLE │
├─────────────────────────────────────────────────────────────┤
│ 🫁 Inhale (вдох) │ git pull │ Получаем из сети │
│ 💨 Exhale (выдох) │ git push │ Отдаём в сеть │
│ 🔄 Цикл │ 12 сек │ ~5 "вдохов" в минуту │
└─────────────────────────────────────────────────────────────┘
```
### 7.3 Синхронизируемые файлы
```python
SYNC_PATHS = [
"data/users.json", # Пользователи
"node_crypto/nodes.json" # Узлы
]
```
**Статус:** ✅ Реализовано
---
## 8. TLS Шифрование
### 8.1 Защищённая связь
**Исходный код:** [node_tls.py](../бот/node_tls.py)
```python
# TLS 1.3 шифрование между узлами
SECURE_PORT = 19333
TLS_VERSION = TLSv1_3
```
### 8.2 Сертификаты
Каждый узел имеет self-signed сертификат с привязкой к криптографическому адресу:
```
CN = amsterdam.efir.org
UID = mta46b633d258059b90db46adffc6c5ca08f0e8d6c
```
### 8.3 Защита от атак
| Атака | Защита | Статус |
|-------|--------|--------|
| Man-in-the-middle | TLS 1.3 | ✅ |
| Перехват трафика | Шифрование | ✅ |
| Harvest now, decrypt later | TLS 1.3 + ML-DSA-65 | ✅ |
**Статус:** ✅ Реализовано
---
## 9. Реализация
| Компонент | Файл | Статус |
|-----------|------|--------|
| Leader Election | [leader_election.py](../бот/leader_election.py) | ✅ Работает |
| Проверка здоровья | [leader_election.py](../бот/leader_election.py) | ✅ Работает |
| Breathing Sync | [breathing_sync.py](../бот/breathing_sync.py) | ✅ Работает |
| TLS Шифрование | [node_tls.py](../бот/node_tls.py) | ✅ Работает |
| Интеграция с ботом | [junomontanaagibot.py](../бот/junomontanaagibot.py) | ✅ Работает |
| Деплой скрипт | [deploy_nodes.sh](../бот/deploy_nodes.sh) | ✅ Готов |
---
```
Alejandro Montana
Montana Protocol v1.0
Январь 2026
```