- 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.
9.1 KiB
Удалённые BGP-спикеры (Remnawave-style)
Runbook для реплик bird2 + evobgp-agent на отдельных VPS. Control plane (evobgp-all) инициирует доставку после module_refresh → deploy_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.
Быстрый старт
- CP (microvps-full): зафиксируйте
EVOBGP_BUNDLE_SEED_HEX(32 байта hex) — стабильный ключ подписи бандлов.EVOBGP_NODE_DISPATCH_ENABLED=1. - Cloudflare: A/AAAA
AGENT_DOMAIN→ публичный IP VPS реплики, режим DNS only (серый облачко), как Web UI в quickstart.md. - Web UI → Сеть → Спикеры: создайте спикер
role=replica. Укажите домен агента, IP ноды, BGP source (по умолчанию = IP ноды), email Let's Encrypt, Cloudflare DNS API token (Zone:DNS:Edit), IP панели (CIDR whitelist). - В диалоге «Установка на ноду» скопируйте docker-команды (секреты
agent_secretиnode_tokenпоказываются один раз). Репозиторий EvoBGP на ноде не нужен: команда пишет/opt/evobgp-speaker/docker-compose.yaml(bird2 + agent + Traefik DNS-01) и делаетdocker compose up -d. - Если образы из приватного реестра — на VPS заранее
docker login git.shx.one. - Не делайте
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.
Безопасность (три участка)
- CP → реплика: HTTPS (LE) + Traefik ipallowlist +
agent_secret. - Реплика → CP: HTTPS + роль
node(только bundle/latest/enroll). Ключ создаётся вместе со спикером. - Конфиг: Ed25519
bundle.sig, SHA-256 manifest,bird -p, LKG на ноде.
Prod checklist:
EVOBGP_CONTROL_PLANE_URL=https://...(в команде из UI)EVOBGP_NODE_DISPATCH_ENABLED=1на CPEVOBGP_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_idvslast_applied_revision_id— в UI иevobgp-deploy.- Job
deploy_applymeta: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 на реплике |