246 lines
7.0 KiB
Markdown
246 lines
7.0 KiB
Markdown
# 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
|
||
```
|