Repository navigation
feat(server): рейт-лимит на игровой вход — кап соединений и скорости per-IP (итер. 33) - #45
Merged
Merged
Conversation
…per-IP (итер. 33)
Защищает /ws и /rtc от флуда соединений и удержания горутин/комнат/сокетов
одним IP. joinGate (cmd/server) — middleware до апгрейда: пер-IP кап живых
соединений (слот занят на время сессии) + токен-бакет скорости новых; оба
лимитера ОБЩИЕ для обоих транспортов, при исчерпании — 429.
Токен-бакет вынесен из auth-лимита (итер. 21) в новый чистый пакет
internal/ratelimit (Limiter + ConnLimiter + ClientKey; без HTTP/game/сети);
internal/api рефакторнут в тонкий адаптер над ним, алгоритм-тесты переехали.
Метрика arena_join_rejected_total{reason}. Env ARENA_JOIN_MAX_PER_IP(16) /
_RATE_BURST(30) / _RATE_WINDOW(1m) / _RATE_IP_HEADER. Игра/провод/симуляция
не тронуты; security-review — findings нет.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Что
Рейт-лимит на игровой вход (
/wsи/rtc) — итерация 33 (лейн Инфра/прод).Пер-IP шлюз
joinGateдо апгрейда: кап живых соединений (ARENA_JOIN_MAX_PER_IP,деф. 16) — слот занят ровно пока жива сессия (обработчик блокируется весь её срок; защита
от удержания горутин/комнат/сокетов), и токен-бакет скорости новых соединений
(
ARENA_JOIN_RATE_BURST/_WINDOW, деф. 30/1m; защита от лавины). Исчерпал —429(у рейта — с
Retry-After), не доходя до рукопожатия и комнаты. Оба лимитера общиедля
/wsи/rtc. Метрикаarena_join_rejected_total{reason}(rate/concurrent).Токен-бакет вынесен из auth-лимита (итер. 21) в новый чистый пакет
internal/ratelimit(
Limiter+ConnLimiter+ClientKey; без HTTP/game/сети);internal/apiрефакторнут втонкий HTTP-адаптер над ним (дубля алгоритма больше нет), алгоритм-тесты переехали в
ratelimit.Зачем
Auth-эндпоинты рейт-лимитятся с итер. 21, но игровой вход — нет: один IP мог лавиной
открывать WS-соединения или держать тысячи долгоживущих сессий (апгрейд + горутина + join +
вход в комнату), исчерпывая ресурсы. Кап живых соединений — главная защита именно игрового
сервера (соединения долгоживущие, в отличие от быстрых auth-POST'ов).
Как
internal/ratelimit/—Limiter(токен-бакет, ленивый свип, инъектируемые часы),ConnLimiter(кап конкурентных слотов,Acquire/Release, карта не растёт),ClientKey(ключ из
RemoteAddr/ первого элемента доверенного заголовка). Оба конструктора привыключении дают
nil, методы nil-безопасны. Конкурентно под мьютексом, без фоновых горутин.internal/api/ratelimit.go— тонкий адаптер:clientKey(r)→ratelimit.ClientKey,middleware→Limiter.Allow. Поведение auth-эндпоинтов идентично прежнему.cmd/server/joingate.go— middleware вокругgateway/rtcGateway:Allow(rate) →Acquire/defer Release(conns) →next. За прокси —ARENA_JOIN_RATE_IP_HEADER.main.go(общие лимитеры на оба хэндлера), env вconfig.go, метрика вinternal/metrics.Тестирование
internal/ratelimit:Limiter(burst/дозаправка/кап/изоляция/свип/конкурентность-race,ClientKey),ConnLimiter(кап/изоляция/очистка карты/конкурентность-race— пик слотовне превышает max).
cmd/server:joingate_test.go(кап держит слот и отдаёт 429 «concurrent» до обработчика,освобождение слота, рейт+
Retry-After«rate», сквозной путь при выключении, ключ иззаголовка),
TestJoinRateConfig(env), integrationTestE2EJoinConcurrencyCap(реальный WS:второе одновременное соединение отклонено, после ухода первого — снова проходит).
make check(lint 0 issues +-raceвсе пакеты) иmake integration— зелёные.Checksumне тронуты — прецедентитер. 21); вместо этого security-review — findings нет.