- deploy/test/stress/: multi-IP masked handshake flood (flood.py), legit client during attack (legit.py), full orchestration (run-stress.sh), edge Dockerfile with socat stub backend and high/defense configs - docs/research/load-test-report.md: v3 VDS loopback results (2026-08-04) - README.md: performance table update (4k conn/s raw, 99.6% blocked in defense, legit clients RTT 2-6ms during attack) - docs/testing.md: multi-IP masked stress-test procedure
6.5 KiB
6.5 KiB
Testing - Rampart
Как тестировать: unit, integration, нагрузочное, DDoS simulation.
1. Unit тесты (Rust)
# Все тесты
cargo test
# Конкретный модуль
cargo test handshake
cargo test hmac
cargo test rate_limiter
# С выводом
cargo test -- --nocapture
# С профилированием
cargo test --release
Что тестировать
| Модуль | 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 |
Пример: VarInt
#[test]
fn test_varint_normal() {
let buf = vec![0x00];
assert_eq!(read_varint(&buf, 0).unwrap(), (0, 1));
}
#[test]
fn test_varint_max() {
let buf = vec![0xFF, 0xFF, 0xFF, 0xFF, 0x07];
assert_eq!(read_varint(&buf, 0).unwrap(), (i32::MAX, 5));
}
#[test]
fn test_varint_overflow() {
let buf = vec![0xFF, 0xFF, 0xFF, 0xFF, 0x0F]; // > 5 байт
assert!(matches!(read_varint(&buf, 0), Err(VarIntError::TooBig)));
}
#[test]
fn test_varint_incomplete() {
let buf = vec![0x80]; // ждём ещё байты
assert!(matches!(read_varint(&buf, 0), Err(VarIntError::Incomplete)));
}
2. Интеграционные тесты
# Требуют: docker compose up (redis, clickhouse)
cargo test --test integration
Что тестируем
#[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
// tests/fuzz/handshake.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
// Должен крашиться на любой вход
let _ = McHandshake::parse(data);
});
cargo install cargo-fuzz
cargo fuzz run handshake_parser
4. Нагрузочное тестирование
Базовый тест (tcpkali)
# Установка
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)
# Только на свои серверы!
hping3 -S --flood -p 25565 EDGE_IP
# С рандомным src IP
hping3 -S --flood -p 25565 --rand-source EDGE_IP
Реальные Minecraft боты (SoulFire)
java -jar SoulFire.jar \
--target play.example.com:25565 \
--amount 200 \
--join-delay 50 \
--protocol-version 765
5. DDoS simulation
# Сценарий 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.
# На 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
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.
6. CI Pipeline
# .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. Метрики качества
# Покрытие кода
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/: тесты в изолированной среде
Версия: 1.0 | Июль 2026