CI / changes (push) Successful in 8s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 25s
CI / web (push) Failing after 34s
CI / go (push) Failing after 19s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped
- Added support for remote speaker configuration in the README and documentation. - Implemented a new endpoint for retrieving the bundle signing public key. - Updated the `evobgp-agent` to include a `serve` command for Panel→Node sync API. - Enhanced CI workflow to validate remote speaker compose files. - Introduced new fields in the API and UI for managing speaker metadata, including dispatch status and sync status. - Improved error handling and response formatting in speaker-related API endpoints. - Updated documentation to reflect changes in remote speaker functionality and usage guidelines.
105 lines
5.0 KiB
Markdown
105 lines
5.0 KiB
Markdown
# Удалённые 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 → карточка спикера |
|
||
| Push Xray JSON | Wake-up → pull signed bundle → verify Ed25519 → apply |
|
||
|
||
Подробнее: [architecture.md](architecture.md).
|
||
|
||
## Быстрый старт
|
||
|
||
1. **CP (microvps-full):** зафиксируйте `EVOBGP_BUNDLE_SEED_HEX` (32 байта hex) — стабильный ключ подписи бандлов.
|
||
2. **Web UI → Сеть → Спикеры:** создайте спикер `role=replica`, укажите **Agent domain**, **IP ноды**, **BGP source** (по умолчанию = IP ноды).
|
||
3. Сохраните **`agent_secret`** (показывается один раз) и скопируйте **docker-compose** из UI.
|
||
4. Выдайте **node API-ключ** ([access.md](access.md)) для `EVOBGP_NODE_TOKEN`.
|
||
5. `GET /v1/bundle/signing-public-key` → `EVOBGP_BUNDLE_PUBKEY_BASE64` на реплике.
|
||
6. На VPS реплики:
|
||
```bash
|
||
cd deploy/compose
|
||
cp .env.remote-speaker.example .env.remote-speaker
|
||
cp .env.remote-speaker-tls.example .env.remote-speaker-tls
|
||
# заполните переменные из UI
|
||
docker compose -f docker-compose.remote-speaker.yaml \
|
||
--env-file .env.remote-speaker --env-file .env.remote-speaker-tls \
|
||
--profile production up -d
|
||
```
|
||
7. **CP:** `EVOBGP_NODE_DISPATCH_ENABLED=1` — Panel шлёт wake-up после publish.
|
||
8. Cloudflare: `AGENT_DOMAIN` → IP VPS, **DNS only** (как Web UI в [quickstart.md](quickstart.md)).
|
||
|
||
## Compose-профили
|
||
|
||
| Profile | Состав |
|
||
|---------|--------|
|
||
| `production` | bird2 (host) + agent + Traefik LE |
|
||
| `plain` | bird2 + agent на хосте без Traefik (только lab) |
|
||
| `fallback` | + `sync-bundle` polling (`scripts/sync-bundle.sh`) |
|
||
|
||
Файлы: [docker-compose.remote-speaker.yaml](../deploy/compose/docker-compose.remote-speaker.yaml).
|
||
|
||
## Firewall
|
||
|
||
| Порт | Кто | Зачем |
|
||
|------|-----|-------|
|
||
| **443** | IP CP (`PANEL_IP_WHITELIST`) | HTTPS dispatch + health |
|
||
| **179** | BGP peers | Data plane |
|
||
| **80** | ACME | Traefik → 443 |
|
||
|
||
## Безопасность (три участка)
|
||
|
||
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://...`
|
||
- [ ] `EVOBGP_NODE_DISPATCH_ENABLED=1` на CP
|
||
- [ ] `EVOBGP_BUNDLE_SEED_HEX` на CP (не менять после выдачи pubkey репликам)
|
||
- [ ] Уникальные `agent_secret` и node token на спикер
|
||
- [ ] Не использовать profile `plain` в prod
|
||
- [ ] Не отключать verify-bundle в agent
|
||
|
||
## 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
|
||
|
||
| Симптом | Проверка |
|
||
|---------|----------|
|
||
| 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 не поднимается | bird2 `network_mode: host`; peers; MD5 BGP отдельно от HTTP sync |
|
||
|
||
## Ограничения (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` | реплика |
|
||
| `EVOBGP_NODE_TOKEN` | реплика |
|
||
| `EVOBGP_BUNDLE_PUBKEY_BASE64` | реплика |
|
||
| `PANEL_IP_WHITELIST` | Traefik на реплике |
|