Linux x86_64 ELF, 9138360 bytes. Любой может скачать через wget/curl и поднять p2p-узел Montana. |
||
|---|---|---|
| .. | ||
| bin | ||
| genesis-manifest.json | ||
| join.sh | ||
| montana-node.service | ||
| README.md | ||
Montana Node — установка валидаторского узла
Полная инструкция запуска нового p2p-узла сети Montana с присоединением к существующей сети без перегенерации genesis.
Требования к серверу
- Ubuntu 22.04 / 24.04 (или совместимый Linux x86_64)
- Минимум 2 CPU / 2 GB RAM / 20 GB диск
- Публичный IP, открытый порт
:8444(TCP) — M8 cross-machine - Открытый порт
:443(TCP) — опционально, для xray VLESS+Reality VPN-фронта/бэкенда
Шаги установки
1. Подготовка сервера
apt-get update
apt-get install -y curl ca-certificates ufw
useradd -r -m -d /var/lib/montana -s /usr/sbin/nologin montana
mkdir -p /var/lib/montana && chown montana:montana /var/lib/montana && chmod 700 /var/lib/montana
mkdir -p /etc/montana
2. Скопировать montana-node бинарь
С любого существующего узла Montana (montana-moscow, montana-frankfurt, montana-finland, montana-us):
# на macOS:
scp montana-moscow:/usr/local/bin/montana-node /tmp/
scp /tmp/montana-node <new-server>:/usr/local/bin/montana-node
ssh <new-server> "chmod +x /usr/local/bin/montana-node"
3. Скопировать genesis-manifest.json
genesis-manifest.json определяет bootstrap-peers (с кем новый узел синхронизируется при первом запуске). Manifest одинаков на всех узлах сети — берём с любого существующего.
scp montana-moscow:/etc/montana/genesis-manifest.json /tmp/
scp /tmp/genesis-manifest.json <new-server>:/etc/montana/genesis-manifest.json
4. Сгенерировать identity нового узла
ssh <new-server> "sudo -u montana /usr/local/bin/montana-node init --data-dir /var/lib/montana"
Команда выведет 24 слова мнемоники — сохрани их в надёжном месте (это единственный способ восстановить ключи узла). Также покажет:
account_id(hex 64 символа)node_id(hex 64 символа)master_seed_fp(8-байтный отпечаток)
5. Открыть порты
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp comment 'SSH'
ufw allow 8444/tcp comment 'Montana M8 p2p'
ufw allow 443/tcp comment 'optional xray VPN' # если узел работает как VPN
echo 'y' | ufw enable
6. systemd unit
Скопировать montana-node.service из этой папки:
scp Montana/Node/montana-node.service <new-server>:/etc/systemd/system/
ssh <new-server> "systemctl daemon-reload && systemctl enable --now montana-node"
7. Проверка
ssh <new-server> "systemctl status montana-node; journalctl -u montana-node --no-pager -n 30"
В логах должно появиться:
[network] CONNECTION ESTABLISHED peer=12D3Koo... label=moscow
[network] CONNECTION ESTABLISHED peer=12D3Koo... label=frankfurt
[network] CONNECTION ESTABLISHED peer=12D3Koo... label=helsinki
[network] heartbeat OK peer=...
8. Lifecycle нового узла
После запуска узел проходит фазы автоматически:
- Bootstrap (несколько секунд) — подключение к peer-ам manifest, дискавери.
- CandidateVdf — тикает VDF (Verifiable Delay Function), накапливая
vdf_chain_lengthдоτ₂ = 20160окон (≈10 часов wall-clock на M-class CPU). - Registered — формирует NodeRegistration через
apply_noderegistrations_batch, попадает вCandidatePool. - Active — на ближайшем selection-окне (
window % 336 == 0) проходитapply_selection_eventи появляется вNodeTable. С этого момента — полноправный валидатор: per-window VdfReveal + BundledConfirmation + ProposalHeader + эмиссия13 Ɉ.
9. Регистрация на карте (опционально)
Чтобы новый узел отображался на /net/ карте montana.quest:
9.1. Добавить DNS A-запись через Cloudflare
# например: <alias>.montana.quest → <new-ip>, DNS-only (не proxied, Reality не работает за CF)
9.2. Добавить алиас на Moscow (orchestrator)
# /root/.ssh/config на Moscow:
Host montana-<alias>-stats
HostName <alias>.montana.quest
User root
IdentityFile /root/.ssh/montana_stats
IdentitiesOnly yes
StrictHostKeyChecking accept-new
ConnectTimeout 6
BatchMode yes
9.3. Добавить в montana-net-pull arrays + montana-cities-build CITIES dict
Файлы:
/usr/local/bin/montana-net-pull— добавить[<id>]="..."в SRC/LABEL/REGION/COUNTRY/HOSTING +for NODE in msk fra fin us <id>;/usr/local/bin/montana-cities-build— добавить<id>: {label, country, hosting, coords, role, peers}в CITIES
9.4. Добавить в peer-health.py на каждом узле
PEERS = [
...
{"name": "<id>", "ip": "<alias>.montana.quest", "country": "<CC>"},
]
Распространить через scp на все узлы и перезапустить montana-net-aggregator.timer.
Архитектурные принципы
- Никакого rebuild genesis при добавлении узла.
genesis-manifest.jsonопределяет bootstrap-peers, state узла живёт в/var/lib/montana/. - Manifest одинаков на всех узлах — peer_id хэши участвуют в M8 handshake.
- Identity рандомная — каждый новый узел генерирует свою (мнемоника + ML-DSA-65 ключи + ML-KEM-768 для PQ-шифрования).
- IP в публичных файлах запрещены — везде использовать
<alias>.montana.questчерез CF DNS-only (см.feedback_no_ip_in_public.md).
Удаление узла
ssh <server> "systemctl stop montana-node && systemctl disable montana-node && rm -rf /var/lib/montana /etc/montana /etc/systemd/system/montana-node.service && systemctl daemon-reload"
После остановки узел перестанет получать NodeRegistration heartbeat, существующие peer-ы через τ₂ окон уберут его из активного NodeTable (cooldown logic).
Текущая сеть (на момент написания)
| ID | Город | Страна | Хостинг | Роль |
|---|---|---|---|---|
| msk | Москва | RU | Timeweb | genesis, vpn origin |
| fra | Frankfurt | DE | Timeweb | genesis, vpn backend |
| fin | Helsinki | FI | THE.Hosting | genesis, vpn frontend |
| us | New York | US | WorkTitans | non-genesis joined 2026-05-14, vpn backend |
Альтернатива: одной командой через join.sh
Не хочешь читать 9 шагов — запусти автоматический скрипт:
# на новом сервере (под root):
scp <existing-server>:/usr/local/bin/montana-node /usr/local/bin/
scp <existing-server>:/etc/montana/genesis-manifest.json /etc/montana/
ALIAS=amsterdam \
LABEL=Amsterdam \
COUNTRY=NL \
HOSTING=DigitalOcean \
COORDS="52.37,4.89" \
TOKEN=<orchestrator_token> \
bash <(curl -sk https://hub.montana.quest/efir369999/montana/raw/branch/main/Node/join.sh)
Скрипт автоматически:
- Поставит xray + ufw
- Сгенерирует Reality keypair, UUID, shortId
- Создаст systemd unit для montana-node и xray
- Откроет порты :443 и :8444
- Сделает identity через
montana-node init - Зарегистрирует узел в Moscow orchestrator (
POST /vpn/node/register) - Orchestrator автоматически обновит на всех узлах:
peer-health.py(PEERS)montana-net-pull(SRC/LABEL/HOSTING/COUNTRY)montana-cities-build(CITIES dict)- Helsinki
xray/config.json(добавит outbound + расширит cascade balancer selector)
- Через ~30 секунд новый узел появится на
montana.quest/net/и/vpn/
TOKEN — секрет orchestrator, лежит на Moscow в /etc/montana-orchestrator.token. Запроси у admin Montana.
Orchestrator API
GET https://montana.quest/vpn/node/health→{"ok":true,"nodes":<count>}GET https://montana.quest/vpn/node/nodes→ список всех известных узлов сетиPOST https://montana.quest/vpn/node/register→ регистрация нового узла (требуетsecretв body)