guard/docs/research/ddos.md
loki5512344 cf9608ce5d
Initial commit: Rampart v0.2.0
Multi-layer DDoS protection for Minecraft servers.

- rampart-core: Edge node with XDP/eBPF + Rust L7 filtering
- rampart-manager: REST API with JWT auth, Redis sync
- rampart-cli: CLI tool for operators
- velocity-plugin: Domain check, HMAC verify, server registry, load balancer
- paper-plugin: Auto-registration, heartbeat, HMAC verify
- dashboard: React + Vite web UI for management
2026-07-20 20:53:32 +02:00

292 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DDoS - Векторы атак и защита
> Актуально: v0.1+
> Это лучший раздел документации - глубокий разбор всех известных векторов.
---
## Как трафик проходит через защиту
```
Атакующий (ботнет)
|
v
┌──────────────────┐
│ 1. NIC / XDP │ L3/L4: SYN flood, UDP drop, IP blacklist
│ (kernel, C) │ CPU < 30%, дроп до 10M pps
└────────┬─────────┘
v (чистый TCP)
┌──────────────────┐
│ 2. Rust Core │ L7: парсинг handshake, HMAC, rate limit
│ (userspace) │ death code auto-ban, blacklist check
└────────┬─────────┘
v (валидный MC клиент)
┌──────────────────┐
│ 3. Load │ Round-robin, circuit breaker
│ Balancer/Proxy │ TPS < 12 = server out
└────────┬─────────┘
v
┌──────────────────┐
│ 4. Game Server │ Чистый трафик, без DDoS нагрузки
│ (Velocity/Hub) │
└──────────────────┘
```
Каждый слой отрабатывает и дропает до перехода к следующему.
XDP отсекает L3/L4 флуд, Rust - L7 атаки на протокол MC.
---
## L3/L4 атаки (объёмные)
| Атака | Механизм | Защита | Слой |
|---|---|---|---|
| **UDP Flood** | Миллионы UDP пакетов | MC = TCP, UDP дропается на уровне NIC | XDP |
| **SYN Flood** | Миллионы TCP SYN без ACK | SYN cookies в ядре Linux | XDP + sysctl |
| **ACK Flood** | Пакеты с ACK без SYN | Stateful connection tracking | XDP |
| **ICMP Flood** | Ping flood | Отключить ICMP ответы | sysctl |
| **Amplification** | DNS/NTP усиление | Фильтрация у провайдера (UDP) | Upstream |
| **Invalid flags** | TCP с мусорными флагами | XDP дроп по флагам | XDP |
| **IP Spoof** | Поддельный src IP | BPF map проверка + uRPF | XDP |
### sysctl для L3/L4 защиты
```bash
# SYN flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
# ICMP
net.ipv4.icmp_echo_ignore_all = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Общие буферы
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
```
---
## L7 атаки (Minecraft-специфичные)
### Handshake Flood
Боты коннектятся тысячами, шлют валидный handshake, дропают.
```
Детект: connections/sec с одного IP > threshold
Защита: rate limit (token bucket) в Rust
Параметры: max 5 conn/IP/сек, burst 10
```
### Bot Join Flood
Тысячи фейковых логинов с разных IP.
```
Детект: LoginStart без предшествующего challenge
Защита: Sonar antibot (физика на limbo) + custom challenge
Параметры: очередь 100 одновременных верификаций
```
### Ping Flood (Status Request)
Тысячи пакетов с next_state=1 (не логин, просто пинг).
```
Детект: status requests/сек > threshold с IP
Защита: отдельный rate limit для status (next_state=1)
Параметры: max 2 status/IP/10сек
```
### Slow Loris (MC вариант)
Открывают TCP, шлют handshake по 1 байту каждые несколько секунд - занимают слоты.
```
Детект: время на handshake > 5 сек
Защита: connection timeout (5 сек на получение полного handshake)
Rust: tokio::time::timeout(Duration::from_secs(5), read_handshake())
```
### Fragmented Handshake
Handshake пакет разбит на несколько TCP сегментов - ломает парсеры.
```
Детект: невозможно, это нормальный TCP
Защита: robust парсер с reassembly буфером
читаем до N байт пока не получим полный пакет
timeout если слишком долго
```
### Fake Forge Flood
Бесконечный поток Forge handshake с мусорными mod list - ломает парсер.
```
Детект: mod list длиннее разумного (> 500 модов)
Защита: max_hostname_length = 4096, дроп при превышении
парсер с явными bounds check на каждый VarInt
```
### VarInt Overflow
Специально сформированные VarInt которые вызывают integer overflow.
```
Детект: VarInt > 5 байт (по MC протоколу)
Защита: строгий bounds check, паника = DROP не crash
// Правильный парсер с защитой
fn read_varint(buf: &[u8]) -> Result<(i32, usize), Error> {
let mut value: i32 = 0;
let mut position = 0;
for (i, &byte) in buf.iter().enumerate() {
if i >= 5 { return Err(Error::VarIntTooBig); } // MAX 5 байт
value |= ((byte & 0x7F) as i32) << position;
if (byte & 0x80) == 0 { return Ok((value, i + 1)); }
position += 7;
}
Err(Error::Incomplete)
}
```
---
## AI-боты (2026)
### Проблема
Современные attack frameworks используют AI и базы CAPTCHA решений:
- Боты проходят физику Sonar (реализован настоящий MC движок)
- Боты решают математические задачи в чате
- Боты кликают на блоки по описанию
- LimboFilter полностью обходится
### Что всё ещё работает
```
✓ HMAC верификация - только через наш edge (криптография)
✓ Rate limit на edge - физически ограничивает скорость
✓ ASN блокировка - датацентры не могут быть "жилыми" IP
✓ Репутационная система - долго строить репутацию
✓ Кастомный challenge - нет готового обхода
✓ Timing analysis - боты отвечают слишком быстро или паттернами
```
### Кастомный challenge - идеи которые сложно автоматизировать
```
1. Timing-based: игрок должен ответить МЕЖДУ 2 и 8 секундами
(слишком быстро = бот, слишком медленно = AFK скрипт)
2. Контекстный вопрос: вопрос зависит от случайного события
на сервере в последние 5 минут (бот не знает контекст)
3. Изменяющаяся механика: challenge меняется каждые 6 часов
(атакующий должен постоянно обновлять обход)
4. Map-based CAPTCHA: картинка рендерится на карте в инвентаре
случайным шрифтом из пула 50+ шрифтов
5. Поведенческий анализ: первые 30 сек на хабе - смотрим
на паттерны движения, мыши, взаимодействий
```
### Timing Analysis
```rust
// Боты часто отвечают с константной задержкой
// Реальные игроки - с нормальным распределением
pub struct TimingAnalyzer {
response_times: Vec<Duration>,
}
impl TimingAnalyzer {
pub fn is_bot_timing(&self, response_time: Duration) -> f64 {
let ms = response_time.as_millis() as f64;
// Слишком быстро - скрипт
if ms < 200.0 { return 0.9; }
// Слишком ровно - паттерн (variance < 10ms за 5 измерений)
if self.response_times.len() >= 5 {
let variance = self.calculate_variance();
if variance < 10.0 { return 0.85; }
}
// Нормальное распределение - человек
0.1
}
}
```
---
## Circuit Breaker для перегруженных серверов
```
CLOSED (нормально)
↓ TPS < 12 или timeout > 3 сек → OPEN
OPEN (сервер выведен)
↓ через 30 сек → HALF_OPEN (пробный трафик)
HALF_OPEN
↓ успешно → CLOSED
↓ снова плохо → OPEN
```
```rust
pub enum CircuitState { Closed, Open(Instant), HalfOpen }
impl CircuitBreaker {
pub fn should_route(&mut self, server: &ServerEntry) -> bool {
match &self.state {
CircuitState::Closed => {
if server.tps < 12.0 { self.trip(); false }
else { true }
}
CircuitState::Open(tripped_at) => {
if tripped_at.elapsed() > Duration::from_secs(30) {
self.state = CircuitState::HalfOpen;
true // пробуем
} else { false }
}
CircuitState::HalfOpen => true,
}
}
}
```
---
## ASN Reputation
Разные лимиты для разных типов сетей:
```rust
pub enum AsnReputation {
Residential, // обычный провайдер → стандартные лимиты
Datacenter, // AWS/OVH/Hetzner → строгие лимиты
Mobile, // мобильные сети → средние лимиты (NAT!)
Tor, // Tor exit node → максимальная строгость
Vpn, // известный VPN → настраивается
Unknown,
}
// rate limit множитель по типу ASN
fn rate_limit_multiplier(rep: &AsnReputation) -> f64 {
match rep {
AsnReputation::Residential => 1.0,
AsnReputation::Mobile => 0.5, // NAT - много игроков с 1 IP
AsnReputation::Datacenter => 0.2,
AsnReputation::Vpn => 0.3,
AsnReputation::Tor => 0.05,
AsnReputation::Unknown => 0.5,
}
}
```
> ⚠️ Мобильные сети используют NAT - один IP = много реальных игроков.
> Не блокируй мобильные ASN полностью, только снижай лимит.