# 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 ```