Два бага в одном месте, оба вскрылись на нагрузочном тесте 31.07.2026. 1. Ключ лимита строился по `request.client.host`. Backend стоит за nginx, поэтому это адрес КОНТЕЙНЕРА NGINX, одинаковый для всех пользователей. Проверено на проде: в Redis лежал единственный ключ `rate_limit:resolve:172.18.0.13`. То есть лимит «10 запросов в минуту» действовал на весь инстанс разом, а не на клиента. 2. Считались все запросы подряд, включая успешные. Одиннадцатый человек, открывший ссылку на конференцию в течение минуты, получал 429 — и видел «Не удалось найти конференцию» для существующей и активной конференции. Люди попадали внутрь с пятой-десятой попытки, попадая в новое окно. Что изменилось: - адрес клиента берётся из `X-Real-IP` (nginx его уже передаёт). Именно `X-Real-IP`, а не первый элемент `X-Forwarded-For`: последний заполняется через `$proxy_add_x_forwarded_for`, то есть дописывается к присланному клиентом, и лимит обходился бы одним заголовком; - жёсткий счётчик (10/мин, как было) теперь считает только ПРОМАХИ: конференция не найдена или пароль неверен. Именно так выглядит перебор номера, от которого лимит и защищает по ADR-001, п.4; - на общий поток с адреса оставлен мягкий потолок 300/мин — против тупого флуда. Офис за общим NAT это один адрес, поэтому потолок заведомо выше правдоподобного числа участников одной конференции. Тесты: успешные резолвы и гостевые входы не упираются в лимит (50 и 30 подряд); перебор номера, несуществующий идентификатор и подбор пароля по-прежнему упираются; лимит одного клиента не задевает другого.
14 KiB
14 KiB