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
277
docs/testing.md
277
docs/testing.md
|
|
@ -4,265 +4,90 @@
|
|||
|
||||
---
|
||||
|
||||
## 1. Unit тесты (Rust)
|
||||
## 1. Unit и integration тесты (Rust)
|
||||
|
||||
```bash
|
||||
# Все тесты
|
||||
cargo test
|
||||
|
||||
# Конкретный модуль
|
||||
cargo test handshake
|
||||
cargo test hmac
|
||||
cargo test rate_limiter
|
||||
|
||||
# С выводом
|
||||
cargo test -- --nocapture
|
||||
|
||||
# С профилированием
|
||||
cargo test --release
|
||||
cargo test # все тесты
|
||||
cargo test --test config_parse
|
||||
cargo test -- --nocapture # с выводом
|
||||
```
|
||||
|
||||
### Что тестировать
|
||||
Существующие наборы (tests/):
|
||||
|
||||
| Модуль | Happy path | Error cases |
|
||||
|--------|-----------|-------------|
|
||||
| VarInt parser | обычный, короткий | overflow, incomplete, >5 байт |
|
||||
| MC Handshake | vanilla, forge, hmac | truncated, invalid utf8, wrong packet id |
|
||||
| HMAC sign/verify | правильный secret | wrong secret, empty hostname, timing |
|
||||
| Rate limiter | under limit, reset | over limit, burst, concurrent |
|
||||
| Blacklist | add/check/remove | expired entry, duplicate add |
|
||||
| Тест | Что покрывает |
|
||||
|------|---------------|
|
||||
| `config_parse` | Парсинг и валидация единого конфига (src/config) |
|
||||
| `filter_logic` | Blacklist, rate limit, geo-фильтры |
|
||||
| `pow_roundtrip` | Выдача/решение/проверка PoW challenge |
|
||||
| `protocol_registry` | Реестр протокольных плагинов |
|
||||
|
||||
### Пример: VarInt
|
||||
---
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn test_varint_normal() {
|
||||
let buf = vec![0x00];
|
||||
assert_eq!(read_varint(&buf, 0).unwrap(), (0, 1));
|
||||
}
|
||||
## 2. Статический анализ
|
||||
|
||||
#[test]
|
||||
fn test_varint_max() {
|
||||
let buf = vec![0xFF, 0xFF, 0xFF, 0xFF, 0x07];
|
||||
assert_eq!(read_varint(&buf, 0).unwrap(), (i32::MAX, 5));
|
||||
}
|
||||
```bash
|
||||
cargo fmt --all --check
|
||||
cargo clippy --all-targets --all-features -- -D warnings
|
||||
cargo deny check
|
||||
```
|
||||
|
||||
#[test]
|
||||
fn test_varint_overflow() {
|
||||
let buf = vec![0xFF, 0xFF, 0xFF, 0xFF, 0x0F]; // > 5 байт
|
||||
assert!(matches!(read_varint(&buf, 0), Err(VarIntError::TooBig)));
|
||||
}
|
||||
XDP: smoke-check компиляции BPF-программы:
|
||||
|
||||
#[test]
|
||||
fn test_varint_incomplete() {
|
||||
let buf = vec![0x80]; // ждём ещё байты
|
||||
assert!(matches!(read_varint(&buf, 0), Err(VarIntError::Incomplete)));
|
||||
}
|
||||
```bash
|
||||
clang -O2 -g -target bpf -c xdp/core/universal_filter.c -o /tmp/universal_filter.o
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Интеграционные тесты
|
||||
## 3. Локальный integration-стенд (Docker)
|
||||
|
||||
```bash
|
||||
# Требуют: docker compose up (redis, clickhouse)
|
||||
cargo test --test integration
|
||||
bash deploy/test/run_test.sh
|
||||
```
|
||||
|
||||
### Что тестируем
|
||||
|
||||
```rust
|
||||
#[tokio::test]
|
||||
async fn test_full_flow() {
|
||||
// 1. Запускаем edge ноду (test config)
|
||||
// 2. Подключаемся Minecraft клиентом (через tokio::net::TcpStream)
|
||||
// 3. Шлём валидный handshake
|
||||
// 4. Проверяем что HMAC добавлен
|
||||
// 5. Проверяем что трафик проксирован до backend
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_blacklist_sync() {
|
||||
// 1. Добавляем IP в блэклист через Redis
|
||||
// 2. Проверяем что edge нода его подхватила
|
||||
// 3. Пытаемся подключиться с забаненного IP
|
||||
// 4. Проверяем что соединение отклонено
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Fuzzing
|
||||
|
||||
```rust
|
||||
// tests/fuzz/handshake.rs
|
||||
#![no_main]
|
||||
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
// Должен крашиться на любой вход
|
||||
let _ = McHandshake::parse(data);
|
||||
});
|
||||
```
|
||||
|
||||
```bash
|
||||
cargo install cargo-fuzz
|
||||
cargo fuzz run handshake_parser
|
||||
```
|
||||
Поднимает backend-stub (TCP echo), edge (`rampart` с config.test.toml) и
|
||||
attacker-контейнер. Сценарии — в [deploy/test/README.md](../deploy/test/README.md).
|
||||
|
||||
---
|
||||
|
||||
## 4. Нагрузочное тестирование
|
||||
|
||||
### Базовый тест (tcpkali)
|
||||
### Много-IP TCP flood на VDS (edge-only)
|
||||
|
||||
`deploy/test/stress/` — полный цикл без Redis/ClickHouse: edge-контейнер с
|
||||
stub-бэкендом (socat echo) + attacker-контейнер со 100 source IP.
|
||||
`flood.py` шлёт чистые TCP-соединения (connect / slowloris / keepalive),
|
||||
во время флуда параллельно подключаются generic TCP-клиенты (`legit.py`),
|
||||
замеряющие RTT.
|
||||
|
||||
```bash
|
||||
# Установка
|
||||
cargo install tcpkali
|
||||
|
||||
# 50k новых соединений
|
||||
tcpkali \
|
||||
--connections 1000 \
|
||||
--connect-rate 5000 \
|
||||
--duration 60s \
|
||||
EDGE_IP:25565
|
||||
|
||||
# 500 активных соединений с трафиком
|
||||
tcpkali \
|
||||
--connections 500 \
|
||||
--connect-rate 100 \
|
||||
--duration 120s \
|
||||
--message-rate 1 \
|
||||
--message "$(xxd mc_handshake.bin)" \
|
||||
EDGE_IP:25565
|
||||
```
|
||||
|
||||
### SYN flood (hping3)
|
||||
|
||||
```bash
|
||||
# Только на свои серверы!
|
||||
hping3 -S --flood -p 25565 EDGE_IP
|
||||
|
||||
# С рандомным src IP
|
||||
hping3 -S --flood -p 25565 --rand-source EDGE_IP
|
||||
```
|
||||
|
||||
### Реальные Minecraft боты (SoulFire)
|
||||
|
||||
```bash
|
||||
java -jar SoulFire.jar \
|
||||
--target play.example.com:25565 \
|
||||
--amount 200 \
|
||||
--join-delay 50 \
|
||||
--protocol-version 765
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. DDoS simulation
|
||||
|
||||
```bash
|
||||
# Сценарий 1: SYN flood
|
||||
# Ожидание: XDP дропает, CPU < 30%
|
||||
hping3 -S --flood -p 25565 EDGE_IP
|
||||
|
||||
# Сценарий 2: Handshake flood
|
||||
# Ожидание: rate limit блокирует, CPU < 60%
|
||||
for i in $(seq 1 1000); do
|
||||
(echo -n "$MC_HANDSHAKE" | nc -w1 EDGE_IP 25565) &
|
||||
done
|
||||
|
||||
# Сценарий 3: Slowloris
|
||||
# Ожидание: timeout 5 сек, соединение закрывается
|
||||
while true; do
|
||||
echo -n -e '\x01' | nc -w 10 EDGE_IP 25565
|
||||
done
|
||||
|
||||
# Сценарий 4: Fragmented handshake
|
||||
# Ожидание: буферизация, успешный парсинг
|
||||
# (отправляем handshake по 1 байту с задержкой 100ms)
|
||||
```
|
||||
|
||||
### Готовый много-IP стресс-тест на VDS (edge-only)
|
||||
|
||||
`deploy/test/stress/` — полный цикл без Redis/Velocity/Paper: edge-контейнер с stub-бэкендом
|
||||
(socat echo) + attacker-контейнер со 100 source IP. Атака **маскируется под обычный трафик**
|
||||
(валидные handshake со случайными hostname), во время флуда параллельно заходят легитимные
|
||||
клиенты (`legit.py`), замеряющие RTT.
|
||||
|
||||
```bash
|
||||
# На VDS
|
||||
git clone https://github.com/loki5512344/rampart.git && cd rampart
|
||||
cargo build --release --bin rampart-core
|
||||
cp target/release/rampart-core deploy/test/stress/edge-ctx/rampart-core
|
||||
cargo build --release --bin rampart
|
||||
cd deploy/test/stress && bash run-stress.sh
|
||||
```
|
||||
|
||||
Фазы: A — сырая пропускная способность (лимиты 100k), B — защита (дефолт 5 pps/IP),
|
||||
C — SYN flood, D — активные соединения. Результаты прогона 2026-08-04 —
|
||||
в [load-test-report.md](research/load-test-report.md).
|
||||
Фазы: A — сырая пропускная способность (лимиты сняты), B — защита (per-IP rate
|
||||
limit + reputation bans), C — SYN flood hping3, D — активные соединения.
|
||||
|
||||
---
|
||||
|
||||
## 6. CI Pipeline
|
||||
|
||||
```yaml
|
||||
# .github/workflows/test.yml
|
||||
name: Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
unit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: cargo test
|
||||
- run: cargo clippy -- -D warnings
|
||||
- run: cargo fmt --check
|
||||
|
||||
integration:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- 6379:6379
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: cargo test --test integration
|
||||
|
||||
fuzz:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: cargo fuzz run handshake_parser -- -runs=100000
|
||||
|
||||
bench:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: cargo bench
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Метрики качества
|
||||
### tcpkali / hping3
|
||||
|
||||
```bash
|
||||
# Покрытие кода
|
||||
cargo install cargo-tarpaulin
|
||||
cargo tarpaulin --out Html
|
||||
open tarpaulin-report.html
|
||||
|
||||
# Цели:
|
||||
# core/handshake.rs: > 95%
|
||||
# core/hmac.rs: > 90%
|
||||
# core/rate_limit: > 85%
|
||||
# xdp/: тесты в изолированной среде
|
||||
tcpkali --connections 1000 --connect-rate 5000 --duration 60s EDGE_IP:25565
|
||||
hping3 -S --flood -p 25565 --rand-source EDGE_IP # только на свои серверы!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Версия: 1.0 | Июль 2026*
|
||||
## 5. Метрики для проверки во время теста
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:9090/metrics | grep rampart_
|
||||
# rampart_connections_total{result="allowed|blocked"}
|
||||
# rampart_rate_limit_hits
|
||||
# rampart_pow_challenges_total{result=...}
|
||||
# rampart_attack_status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Версия: 2.0 | Август 2026*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue