99a9eee908
Маскировка: - ChangeCipherSpec middlebox-compat запись после ClientHello/ServerHello — без неё последовательность типов TLS-записей отличала нас от настоящего браузера даже при идеальном JA3/JA4-отпечатке. - SNI-aware stealth fallback: невалидный клиент проксируется на запрошенный им хост, а не всегда на один и тот же decoy — иначе активное зондирование с разными SNI на одном IP получало одинаковый ответ. Резолв только в публичные IP (защита от SSRF на внутреннюю сеть ноды через подставной SNI). - Профиль браузера привязан к session_id, а не к номеру попытки реконнекта: раньше при нескольких быстрых ретраях с одного IP летели ClientHello Chrome→Edge→Firefox подряд — сама по себе аномалия для DPI. - Бакетный паддинг Data/UdpData кадров вместо полного отсутствия паддинга; джиттер перед ServerHello вместо мгновенного детерминированного ответа. Версионирование: - PROTOCOL_VERSION в session_id ClientHello — сервер узнаёт версию клиента до отправки чего-либо и может включать версионно-зависимое поведение (сейчас — CCS) только для тех, кто его понимает. Позволяет катить будущие несовместимые изменения протокола без синхронного flag-day релиза. Тесты (core, было 0): - Round-trip тесты TLS-записей/hello-сообщений/кадров/кодека. - Полный цикл хендшейка с реальным выводом ключей на обеих сторонах. - Вся SSRF-защита (hostname/IP валидация, v4/v6). - Интеграционные тесты по настоящему TCP: легитимный хендшейк и stealth-fallback на мусорный ClientHello. tools/loadtest — нагрузочный тест поверх настоящего скомпилированного netrunner-server (реальный процесс, метрики RSS/CPU из /proc) и настоящего публичного клиентского API. Попутно найден и обойдён гоночный баг: Connect-кадр в ClientHandler::connect() уходит через try_send ещё до того, как поднимется хоть одна нога тунеля, и молча теряется при синтетической нагрузке. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
18 lines
371 B
TOML
18 lines
371 B
TOML
[package]
|
|
name = "netrunner-loadtest"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
|
|
[[bin]]
|
|
name = "loadtest"
|
|
path = "src/main.rs"
|
|
|
|
[dependencies]
|
|
netrunner-core = { path = "../../core" }
|
|
tokio = { version = "1.49.0", features = ["full"] }
|
|
clap = { version = "4", features = ["derive"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
bytes = "1.5"
|
|
libc = "0.2"
|