feat!: universal redesign — drop Minecraft stack, single-crate architecture
- remove Java plugins (velocity/paper), dashboard, all MC-specific code
(handshake, death_code, varint, hostname-HMAC); available in history pre-v0.2
- merge crates/* into one package with src/bin/{rampart,rampart-manager,rampart-cli}
- ProtocolHandler trait + registry (no implementations yet), universal PoW kept
- XDP: universal L3/L4 filter (xdp/core/) + pluggable hook API (xdp/hooks/),
fix IPv6 saddr bug; clang build verified
- docs: bilingual knowledge base (docs/kb/: attacks x4, defense-levels,
practice x3), rewrite README/architecture for universal concept
- TODO.md v4.0: <=300-line module limit, competitor benchmark section (ref/)
- deploy/CI/docs cleanup: no MC references, new binary names
cargo build/clippy(-D warnings)/test green (55 tests)
This commit is contained in:
parent
0b53ed720b
commit
15f474486a
179 changed files with 5044 additions and 11519 deletions
|
|
@ -1,30 +1,9 @@
|
|||
# Configuration - Rampart
|
||||
|
||||
> Примеры конфигурационных файлов для всех компонентов.
|
||||
> Единый конфиг edge-ноды (`config.toml`) и переменные окружения Manager.
|
||||
> Схема конфига: `src/config/sections.rs` — единственный источник правды.
|
||||
|
||||
## Как конфиги связывают компоненты
|
||||
|
||||
```
|
||||
Edge config.toml Manager (env)
|
||||
bind.address JWT_SECRET
|
||||
bind.port API_PASSWORD
|
||||
backend.address ───→ REDIS_URL
|
||||
hmac.secret ←──────┐ CLICKHOUSE_URL
|
||||
store.redis_url ────┤
|
||||
│
|
||||
Velocity (env) │ Paper (env)
|
||||
RAMPART_HMAC_SECRET┤ RAMPART_HMAC_SECRET
|
||||
RAMPART_ALLOWED_ │ RAMPART_REDIS_URL
|
||||
DOMAINS │ RAMPART_SERVER_NAME
|
||||
RAMPART_REDIS_URL ─┘ RAMPART_SERVER_IP
|
||||
```
|
||||
|
||||
HMAC secret должен быть ОДИНАКОВЫМ на Edge, Velocity и Paper.
|
||||
Redis URL - одинаковым на всех компонентах.
|
||||
|
||||
---
|
||||
|
||||
## 1. Edge Node (`config.toml`)
|
||||
## 1. Edge (`config.toml`, путь задаётся `RAMPART_CONFIG`)
|
||||
|
||||
```toml
|
||||
[bind]
|
||||
|
|
@ -32,249 +11,80 @@ address = "0.0.0.0"
|
|||
port = 25565
|
||||
|
||||
[backend]
|
||||
# Velocity нода или HAProxy
|
||||
address = "10.0.0.2"
|
||||
port = 25565
|
||||
|
||||
[hmac]
|
||||
# Минимум 32 байта. Сгенерировать: openssl rand -hex 32
|
||||
secret = "CHANGE_ME_32_BYTES_LONG_HERE_ABCDEF123456"
|
||||
# Список TCP-бэкендов (addr:port). Обязателен непустой, адреса валидируются.
|
||||
upstreams = ["127.0.0.1:25566"]
|
||||
|
||||
[workers]
|
||||
# Количество воркеров = количество vCPU
|
||||
count = 4
|
||||
|
||||
[xdp]
|
||||
# Опционально, требует kernel 5.10+
|
||||
enabled = false
|
||||
interface = "eth0"
|
||||
|
||||
[pow]
|
||||
# PoW Challenge (Layer 2). ВЫКЛЮЧЕН по умолчанию (P0-4):
|
||||
# текстовый challenge отправляется до handshake и несовместим с ванильными
|
||||
# MC-клиентами — они не умеют его решать, и при enabled=true никто не сможет
|
||||
# зайти на сервер. Включать только после появления клиентского мода или PoW,
|
||||
# совместимого с протоколом Minecraft.
|
||||
enabled = false
|
||||
difficulty = 4
|
||||
|
||||
[limits]
|
||||
# Максимум времени на получение handshake (Slowloris защита)
|
||||
handshake_timeout_secs = 5
|
||||
# Максимум одновременных соединений с одного IP
|
||||
max_connections_per_ip = 10
|
||||
# Лимит коннектов в секунду с одного IP (Status ping)
|
||||
rate_limit_status_pps = 2
|
||||
# Лимит коннектов в секунду с одного IP (Login)
|
||||
rate_limit_login_pps = 5
|
||||
# Лимит burst
|
||||
rate_limit_burst = 10
|
||||
handshake_timeout_secs = 5 # таймаут чтения (slowloris-защита)
|
||||
max_connections_per_ip = 10 # одновременные соединения с одного IP
|
||||
rate_limit_pps = 5.0 # лимит коннектов/сек с одного IP
|
||||
rate_limit_burst = 10.0 # burst
|
||||
|
||||
[ban]
|
||||
ban_duration_secs = 3600
|
||||
|
||||
[store]
|
||||
# v0.2+: Redis для синхронизации блэклиста
|
||||
redis_url = "redis://:password@10.0.0.1:6379/0"
|
||||
# TTL кэша блэклиста (локально)
|
||||
redis_url = "" # пусто = синхронизация блэклиста выключена
|
||||
blacklist_cache_ttl_secs = 300
|
||||
clickhouse_url = "" # пусто = запись событий выключена
|
||||
|
||||
[xdp]
|
||||
enabled = false # требует сборки --features xdp, kernel 5.10+
|
||||
interface = "eth0"
|
||||
|
||||
[logging]
|
||||
level = "info" # trace, debug, info, warn, error
|
||||
format = "json" # json или text
|
||||
level = "info" # trace, debug, info, warn, error
|
||||
format = "text" # text или json
|
||||
|
||||
[metrics]
|
||||
enabled = true
|
||||
port = 9090
|
||||
|
||||
[quic]
|
||||
# v0.4+: QUIC канал к Manager (опционально)
|
||||
enabled = false
|
||||
connect = "10.0.0.1:7777"
|
||||
[pow]
|
||||
enabled = false # PoW challenge, OFF по умолчанию
|
||||
difficulty = 4
|
||||
|
||||
whitelist = ["127.0.0.1", "::1"] # только IP-адреса, валидируются при парсинге
|
||||
```
|
||||
|
||||
---
|
||||
Все секции опциональны — при отсутствии используются дефолты из таблицы выше.
|
||||
|
||||
## 2. Velocity Plugin
|
||||
## 2. Manager (переменные окружения)
|
||||
|
||||
Плагин конфигурируется через переменные окружения (совпадают с edge node).
|
||||
| Переменная | Обязательна | По умолчанию | Описание |
|
||||
|------------|-------------|--------------|----------|
|
||||
| `REDIS_URL` | нет | `redis://127.0.0.1:6379/0` | Хранилище состояния |
|
||||
| `JWT_SECRET` | да | — | Минимум 32 байта |
|
||||
| `JWT_AUDIENCE` | нет | `rampart` | Audience JWT |
|
||||
| `JWT_EXPIRATION_SECS` | нет | `86400` | Время жизни токена |
|
||||
| `API_PASSWORD` | да | — | Пароль для `/api/v1/auth/login`; значение `changeme` запрещено |
|
||||
| `CORS_ORIGIN` | нет | `http://localhost:5173` | CORS; `*` или пусто — разрешить все |
|
||||
|
||||
Manager всегда слушает `0.0.0.0:8080`.
|
||||
|
||||
## 3. Feature flags сборки (Cargo.toml)
|
||||
|
||||
| Feature | По умолчанию | Что включает |
|
||||
|---------|--------------|--------------|
|
||||
| `store-redis` | ✅ | Redis-клиент и синхронизация блэклиста |
|
||||
| `geoip` | ❌ | GeoIP lookup (maxminddb) |
|
||||
| `xdp` | ❌ | Загрузка XDP-программы через libbpf-rs |
|
||||
| `io-uring` | ❌ | splice/io_uring I/O |
|
||||
| `protocol-http` | ❌ | Резерв под HTTP-плагин (пока пустой) |
|
||||
|
||||
Пример: `cargo build --release --features xdp --bin rampart`.
|
||||
|
||||
## 4. BPF/XDP программа
|
||||
|
||||
Исходник: `xdp/core/universal_filter.c`. Smoke-check компиляции:
|
||||
|
||||
```bash
|
||||
# Обязательно: HMAC секрет (должен совпадать с edge нодой)
|
||||
RAMPART_HMAC_SECRET="CHANGE_ME_32_BYTES_LONG_HERE_ABCDEF123456"
|
||||
|
||||
# Опционально: список разрешённых доменов (через запятую)
|
||||
RAMPART_ALLOWED_DOMAINS="play.example.com,mc.example.com,example.com"
|
||||
```
|
||||
|
||||
Установка:
|
||||
```
|
||||
# Сборка
|
||||
cd plugins && ./gradlew :velocity:build
|
||||
|
||||
# Копирование в Velocity
|
||||
cp velocity/build/libs/rampart-velocity-*.jar /opt/velocity/plugins/
|
||||
|
||||
# Рестарт
|
||||
systemctl restart velocity
|
||||
```
|
||||
|
||||
Плагин делает:
|
||||
- **DomainCheck**: блокирует direct IP-коннекты, пропускает только домены из whitelist
|
||||
- **HmacCheck**: верифицирует HMAC-SHA256 подпись в hostname (`\0shield\0<sig>`)
|
||||
|
||||
---
|
||||
|
||||
## 3. Paper Plugin
|
||||
|
||||
Конфигурация - через переменные окружения:
|
||||
|
||||
```bash
|
||||
# Обязательно: HMAC секрет (должен совпадать с edge нодой)
|
||||
RAMPART_HMAC_SECRET="CHANGE_ME_32_BYTES_LONG_HERE_ABCDEF123456"
|
||||
```
|
||||
|
||||
Установка:
|
||||
```
|
||||
cd plugins && ./gradlew :paper:build
|
||||
cp paper/build/libs/rampart-paper-*.jar /opt/paper/plugins/
|
||||
```
|
||||
|
||||
Плагин делает:
|
||||
- **HmacCheck**: резервная верификация HMAC-подписи на случай прямого коннекта (в обход Velocity)
|
||||
|
||||
---
|
||||
|
||||
## 4. Manager (`manager.toml`)
|
||||
|
||||
```toml
|
||||
[bind]
|
||||
address = "0.0.0.0"
|
||||
port = 8080
|
||||
|
||||
[tls]
|
||||
cert = "/etc/rampart/tls/manager.crt"
|
||||
key = "/etc/rampart/tls/manager.key"
|
||||
ca = "/etc/rampart/tls/ca.crt"
|
||||
|
||||
[auth]
|
||||
jwt_secret = "CHANGE_ME_JWT_SECRET_HERE"
|
||||
jwt_expiry_hours = 24
|
||||
|
||||
[redis]
|
||||
url = "redis://:password@127.0.0.1:6379/0"
|
||||
pool_size = 10
|
||||
|
||||
[nats]
|
||||
# v0.4+: NATS для критических событий
|
||||
urls = ["nats://127.0.0.1:4222"]
|
||||
|
||||
[clickhouse]
|
||||
url = "http://127.0.0.1:8123"
|
||||
db = "rampart"
|
||||
batch_size = 1000
|
||||
flush_interval_secs = 1
|
||||
|
||||
[quic]
|
||||
# v0.4+: QUIC сервер для edge нод
|
||||
bind = "0.0.0.0:7777"
|
||||
|
||||
[limits]
|
||||
api_rate_per_minute = 60
|
||||
clang -O2 -g -target bpf -c xdp/core/universal_filter.c -o /tmp/universal_filter.o
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. HAProxy (`haproxy.cfg`)
|
||||
|
||||
```haproxy
|
||||
global
|
||||
maxconn 100000
|
||||
log /dev/log local0
|
||||
|
||||
defaults
|
||||
mode tcp
|
||||
timeout connect 3s
|
||||
timeout client 30s
|
||||
timeout server 30s
|
||||
option tcplog
|
||||
|
||||
frontend minecraft_in
|
||||
bind *:25565
|
||||
mode tcp
|
||||
|
||||
# Только от edge нод
|
||||
acl is_edge src 10.0.100.0/24
|
||||
tcp-request connection reject if !is_edge
|
||||
|
||||
default_backend velocity_pool
|
||||
|
||||
backend velocity_pool
|
||||
mode tcp
|
||||
balance leastconn
|
||||
option tcp-check
|
||||
|
||||
server vel1 10.0.0.2:25565 check inter 3s rise 2 fall 3
|
||||
server vel2 10.0.0.3:25565 check inter 3s rise 2 fall 3
|
||||
server vel3 10.0.0.4:25565 check inter 3s rise 2 fall 3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Prometheus (`prometheus.yml`)
|
||||
|
||||
```yaml
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: 'rampart-edge'
|
||||
static_configs:
|
||||
- targets:
|
||||
- '10.0.100.1:9090'
|
||||
- '10.0.100.2:9090'
|
||||
|
||||
- job_name: 'rampart-manager'
|
||||
static_configs:
|
||||
- targets: ['10.0.0.1:9090']
|
||||
|
||||
- job_name: 'rampart-velocity'
|
||||
static_configs:
|
||||
- targets:
|
||||
- '10.0.0.2:9091'
|
||||
- '10.0.0.3:9091'
|
||||
|
||||
- job_name: 'paper-servers'
|
||||
file_sd_configs:
|
||||
- files: ['/etc/prometheus/game_servers.json']
|
||||
refresh_interval: 30s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. WireGuard (`wg0.conf`)
|
||||
|
||||
```ini
|
||||
[Interface]
|
||||
Address = 10.0.0.1/16
|
||||
PrivateKey = <MANAGER_PRIVATE_KEY>
|
||||
ListenPort = 51820
|
||||
MTU = 1420
|
||||
|
||||
[Peer]
|
||||
# Edge EU
|
||||
PublicKey = <EDGE_EU_PUBLIC_KEY>
|
||||
AllowedIPs = 10.0.100.1/32
|
||||
|
||||
[Peer]
|
||||
# Edge US
|
||||
PublicKey = <EDGE_US_PUBLIC_KEY>
|
||||
AllowedIPs = 10.0.100.2/32
|
||||
|
||||
[Peer]
|
||||
# Velocity 1
|
||||
PublicKey = <VEL1_PUBLIC_KEY>
|
||||
AllowedIPs = 10.0.0.2/32
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Версия: 1.0 | Июль 2026*
|
||||
*Версия: 2.0 | Август 2026*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue