Files
EvoBGP/docs/remote-speakers.md
Denozordec 927e27640a
quality / commitlint (push) Skipped
quality / changes (push) Successful in 8s
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 26s
quality / web (push) Successful in 1m27s
quality / go (push) Successful in 1m18s
quality / bird2 (push) Successful in 16s
CD / quality (push) Successful in 3m43s
CD / publish (push) Successful in 3m11s
feat(docs): update speaker installation instructions and logging details
- Enhanced the speaker installation documentation to clarify the use of TCP port 179 and the logging commands for monitoring BIRD and evobgp-agent.
- Updated the speaker form dialog to include additional information about MikroTik connections and logging commands.
- Modified the BIRD configuration to include logging to stderr for better visibility during operations.
- Adjusted the Docker Compose configuration to ensure proper network settings and sysctl configurations for BGP functionality.
2026-08-21 16:11:28 +07:00

9.1 KiB
Raw Permalink Blame History

Удалённые BGP-спикеры (Remnawave-style)

Runbook для реплик bird2 + evobgp-agent на отдельных VPS. Control plane (evobgp-all) инициирует доставку после module_refreshdeploy_apply; реплика не собирает префиксы сама.

Модель

Remnawave EvoBGP
Panel → Node:PORT CP POST https://AGENT_DOMAIN/v1/agent/sync
SECRET_KEY agent_secret (Bearer)
Copy compose Web UI → после создания реплики: docker-команды (bird2 + agent + Traefik)
Push Xray JSON Wake-up → pull signed bundle → verify Ed25519 → apply

Подробнее: architecture.md.

Быстрый старт

  1. CP (microvps-full): зафиксируйте EVOBGP_BUNDLE_SEED_HEX (32 байта hex) — стабильный ключ подписи бандлов. EVOBGP_NODE_DISPATCH_ENABLED=1.
  2. Cloudflare: A/AAAA AGENT_DOMAIN → публичный IP VPS реплики, режим DNS only (серый облачко), как Web UI в quickstart.md.
  3. Web UI → Сеть → Спикеры: создайте спикер role=replica. Укажите домен агента, IP ноды, BGP source (по умолчанию = IP ноды), email Let's Encrypt, Cloudflare DNS API token (Zone:DNS:Edit), IP панели (CIDR whitelist).
  4. В диалоге «Установка на ноду» скопируйте docker-команды (секреты agent_secret и node_token показываются один раз). Репозиторий EvoBGP на ноде не нужен: команда пишет /opt/evobgp-speaker/docker-compose.yaml (bird2 + agent + Traefik DNS-01) и делает docker compose up -d.
  5. Если образы из приватного реестра — на VPS заранее docker login git.shx.one.
  6. Не делайте docker compose down -v на реплике без бэкапа тома evobgp_speaker_traefik_letsencrypt (acme.json).

Эталонный compose в репозитории (lab / ручной запуск): docker-compose.remote-speaker.yaml. Prod-установка с панели — paste из UI.

HTTPS на ноде (DNS-01)

Сертификат не выписывает Control Plane и не Cloudflare Origin CA. Его выпускает Traefik на самой реплике (evobgp-edge), resolver letsencrypt, ACME DNS-01 через Cloudflare.

Кто Что делает
Оператор DNS only: AGENT_DOMAIN → IP VPS
Traefik на ноде dnschallenge=true, provider=cloudflare
CF_DNS_API_TOKEN В env реплики (вшит в команду из UI). Traefik создаёт TXT _acme-challenge.<AGENT_DOMAIN>
Let's Encrypt Проверяет TXT, отдаёт сертификат
Том evobgp_speaker_traefik_letsencrypt/letsencrypt/acme.json
CP → нода https://AGENT_DOMAIN/v1/agent/* + Authorization: Bearer <agent_secret> + Traefik ipallowlist (PANEL_IP_WHITELIST)

Порты:

Порт Кто Зачем
443 IP CP (PANEL_IP_WHITELIST) HTTPS dispatch, health, GET /v1/agent/bird/protocols
179 BGP peers Data plane — Docker ports: 179:179/tcp, как на панели
80 любой редирект HTTP → HTTPS (не HTTP-01 ACME)

В панели хостера / security group откройте TCP 179 (скрипт compose это не делает). Overlay (bird_bgp_source_ipv4 / node_ipv4) задаёт router id; host-сеть bird2 не используется.

DNS-01 ходит исходящим к Cloudflare API и Let's Encrypt; inbound 80 для выпуска сертификата не нужен. Agent слушает :8443 только во внутренней docker-сети; снаружи — Traefik 443.

Токен Cloudflare для панели (evobgp-edge на CP) в процесс API не проброшен — для реплики его задают в форме создания.

Profile plain в файле репозитория — только lab без Traefik.

Compose-профили (файл в репозитории)

Profile Состав
production bird2 (speaker-net, 179:179) + agent + Traefik LE
plain bird2 + agent без Traefik (lab; agent на хосте)
fallback + sync-bundle polling (scripts/sync-bundle.sh)

Команда из UI — самодостаточный yaml без profiles (эквивалент production).

Подготовка VPS

bird2 в docker-сети с ports: 179:179/tcp и sysctls ip_forward (как панель). Команда из UI дополнительно включает sysctl на хосте:

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1
echo 'net.ipv4.ip_forward=1' | tee /etc/sysctl.d/99-evobgp-bird.conf
echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.d/99-evobgp-bird.conf
sysctl --system

Логи на реплике

BIRD пишет в stderr (log stderr all), agent — в stdout. На VPS:

cd /opt/evobgp-speaker
docker compose logs -f bird2
docker compose logs -f evobgp-agent

До первого apply бандла с protocol bgp порт 179 может быть CLOSED (нет listener). После sync в логах agent: sync start / sync ok / sync failed.

Безопасность (три участка)

  1. CP → реплика: HTTPS (LE) + Traefik ipallowlist + agent_secret.
  2. Реплика → CP: HTTPS + роль node (только bundle/latest/enroll). Ключ создаётся вместе со спикером.
  3. Конфиг: Ed25519 bundle.sig, SHA-256 manifest, bird -p, LKG на ноде.

Prod checklist:

  • EVOBGP_CONTROL_PLANE_URL=https://... (в команде из UI)
  • EVOBGP_NODE_DISPATCH_ENABLED=1 на CP
  • EVOBGP_BUNDLE_SEED_HEX на CP (не менять после выдачи pubkey репликам)
  • Уникальные agent_secret и node token на спикер
  • Не использовать profile plain в prod
  • Не отключать verify-bundle в agent
  • Не docker compose down -v без бэкапа acme.json

Per-speaker BGP source

В UI: IP ноды (meta_json.node_ipv4) и BGP source IPv4 (bird_bgp_source_ipv4, default = IP ноды). Pipeline накладывает overlay при GET .../bundle/{revision_id} — меняются router id и peer local.

Tenant /v1/settings (bird_bgp_source_ipv4) — fallback для master / если у спикера не задано.

Drift и dispatch

  • published_revision_id vs last_applied_revision_id — в UI и evobgp-deploy.
  • Job deploy_apply meta: node_dispatch.results[] — статус wake-up per speaker.
  • Canary: POST /v1/speakers/{id}/apply с revision_id.

Troubleshooting

Симптом Проверка
CHANGE_ME_* в yaml В форме не заполнены email LE / CF token / IP панели / домен
Traefik отдаёт дефолтный сертификат DNS only; token Zone:DNS:Edit; логи evobgp-edge; том acme.json
Offline в UI GET https://AGENT_DOMAIN/v1/agent/health с CP; LE cert; whitelist
dispatch error CP logs job meta; firewall 443; agent_secret
verify-bundle fail pubkey совпадает с CP seed; пересоберите pubkey после смены seed
BGP не поднимается / сканер CLOSED 179:179 в compose; SG хостера; docker compose logs bird2; пир MikroTik на IP ноды; бандл применён (sync ok)

Ограничения (scale-review)

  • Peers не фильтруются по speaker_id — один tenant-wide peers fragment на все реплики.
  • Разные peer-наборы per site — отдельная итерация pipeline.
  • Если Panel не достучится до agent — включите profile fallback (polling) в файле репозитория.

Связанные env

Переменная Где
EVOBGP_NODE_DISPATCH_ENABLED=1 CP
EVOBGP_AGENT_SECRET реплика (из UI, один раз)
EVOBGP_NODE_TOKEN реплика (API-ключ role=node, из UI)
EVOBGP_FIREWALL_FAILOVER_ENABLED=1 реплика (опционально: отдавать /v1/firewall/blocklist при недоступности CP)
EVOBGP_FIREWALL_STATE_FILE реплика (default /var/lib/evobgp-agent/firewall-state.json)
EVOBGP_BUNDLE_PUBKEY_BASE64 реплика (в команде из UI)
PANEL_IP_WHITELIST Traefik на реплике
CF_DNS_API_TOKEN Traefik на реплике
LETSENCRYPT_EMAIL Traefik на реплике