Задачи 025-030: ёмкость префиксов, политика входа, дерево префиксов
Повторный анализ кодовой базы (docs/reviews/2026-09-26-codebase-review-2.md) и доработки:
025 Ёмкость префикса — размер его подсети (а не сумма листьев); «Обзор» считает ёмкость
по корневым активным IPv4-префиксам и адреса внутри них.
026 Политика блокировки входа: 5 неудач на логин+IP, 20 на IP, 50 на логин со всех IP,
кроме известных IP (known_logins, миграция 0009) — владельца нельзя заблокировать анонимно.
027 Сериализация попыток входа по IP (advisory-lock после блокировки логина).
028 UI «Префиксы»: загрузка всех страниц (до 20 000), счётчики по total, предупреждение об усечении.
029 Advisory-lock по VRF для операций, меняющих дерево префиксов и раскладку адресов.
030 Исправление замечаний ревью 025-029: _lock_prefix (VRF блокируется до чтения префикса,
409 при одновременном переносе), константы политики входа перенесены в app/services.py.
Тесты: 14 passed (проверка ёмкости родителя приведена к семантике 025); сквозные сценарии
и гонки — docs/reviews/2026-09-26-changes-025-029-review.md, 2026-09-27-changes-030-review.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
13e17fbb47
commit
03d727e496
25 files changed
+877
-78
No files matched your search
@@ -0,0 +1,21 @@
|
||||
# Сериализация попыток входа по IP (изменение 027)
|
||||
|
||||
Находка № 7 из `docs/reviews/2026-09-26-codebase-review-2.md`, серьёзность — низкая. Выполняется вместе с 026 (тот же файл).
|
||||
|
||||
## Context
|
||||
Изменение 024 сериализует попытки одного логина (`pg_advisory_xact_lock(hashtext(логин))`). Параллельные попытки **разных** логинов с одного IP проходят проверку лимита по IP
|
||||
одновременно, и порог 20 можно превысить на степень параллелизма.
|
||||
|
||||
## Решение (`app/api/v1/auth.py`, `login`)
|
||||
1. После блокировки по логину и до `_retry_after` — вторая блокировка `pg_advisory_xact_lock(hashtext('ip:' || ip))`, если `ip` известен.
|
||||
Порядок всегда «логин, затем IP»: IP-блокировка берётся последней, поэтому цикл ожидания невозможен.
|
||||
2. Использовать двухаргументную форму advisory-lock с отдельными пространствами ключей, чтобы исключить коллизии между логинами и IP:
|
||||
`pg_advisory_xact_lock(<LOGIN_NS>, hashtext(name))` и `pg_advisory_xact_lock(<IP_NS>, hashtext(ip))`; константы пространств — в `auth.py` (например, 7031 и 7032).
|
||||
3. Комментарий в коде: цена — попытки с одного IP (в том числе за NAT) обрабатываются по одной, время ответа при массовом входе растёт на время argon2.
|
||||
|
||||
## Файлы
|
||||
`app/api/v1/auth.py`, `README.md` (одна фраза в абзаце «Вход»).
|
||||
|
||||
## Проверка
|
||||
16 параллельных неверных входов на 16 разных несуществующих логинов с одного IP при заранее вставленных 15 неудачах этого IP → проверено не больше 5 паролей
|
||||
(в `login_attempts` добавилось ≤ 5 записей), остальные — 429.
|
||||
Reference in new issue
Block a user