Защита от перебора паролей перед выходом почты в интернет (mail.jambocheck.com, 75.6). Один счётчик LoginGuard на все проверки пароля: SMTP AUTH (25/587/465), IMAP LOGIN/AUTHENTICATE, вход в веб, смена пароля.
По IP: 10 неверных за 15 мин → блок 15 мин; каждый следующий блок того же IP вдвое дольше, до 24 ч.
По ящику: 20 неверных на один ящик с любых IP → ящик закрыт на 15 мин, кроме IP, с которых в него уже успешно входили (30 дней): владельца перебором не запереть.
Во время блока пароль не проверяется: SMTP 421 4.7.0 + обрыв, IMAP * BYE + NO [UNAVAILABLE], веб 429 + Retry-After.
Неверный пароль отвечается через 1 с; 3 неверных в одном соединении → обрыв (SMTP, IMAP).
«Нет ящика» и «неверный пароль» снаружи неразличимы (веб: и для отключённого ящика), оба считаются.
X-Forwarded-For принимается только от прокси в частной сети (своя замена forwardedHeaderTransformer); с публичного адреса — отбрасывается. Важно для docker-compose.public.yml: порт 8080 там опубликован и на публичном адресе ВМ.
Настройки LOGIN_GUARD_* (README), счётчики в памяти.
Попутно исправил IMAP: после * BYE терялся тегированный ответ (LOGOUT, обрыв после неудачных входов).
Проверка
./gradlew :backend:test: 68 тестов, 0 упало (новые: LoginGuardTest, LoginGuardConfigTest, AuthenticationControllerTest, по одному в SmtpServerTest/ImapServerTest).
Живой запуск jar на временной Postgres: 4 неверных → 429 даже с верным паролем, ответ ~1,2 с на неверный; через прокси (X-Forwarded-For с localhost) — другой IP, 200; блок виден в логе.
Не сделано: лимит на регистрацию (на публичной почте она закрыта).
## Что
Защита от перебора паролей перед выходом почты в интернет (`mail.jambocheck.com`, 75.6). Один счётчик `LoginGuard` на все проверки пароля: SMTP `AUTH` (25/587/465), IMAP `LOGIN`/`AUTHENTICATE`, вход в веб, смена пароля.
- **По IP:** 10 неверных за 15 мин → блок 15 мин; каждый следующий блок того же IP вдвое дольше, до 24 ч.
- **По ящику:** 20 неверных на один ящик с любых IP → ящик закрыт на 15 мин, **кроме IP, с которых в него уже успешно входили** (30 дней): владельца перебором не запереть.
- Во время блока пароль не проверяется: SMTP `421 4.7.0` + обрыв, IMAP `* BYE` + `NO [UNAVAILABLE]`, веб `429` + `Retry-After`.
- Неверный пароль отвечается через 1 с; 3 неверных в одном соединении → обрыв (SMTP, IMAP).
- «Нет ящика» и «неверный пароль» снаружи неразличимы (веб: и для отключённого ящика), оба считаются.
- `X-Forwarded-For` принимается только от прокси в частной сети (своя замена `forwardedHeaderTransformer`); с публичного адреса — отбрасывается. Важно для `docker-compose.public.yml`: порт 8080 там опубликован и на публичном адресе ВМ.
- Настройки `LOGIN_GUARD_*` (README), счётчики в памяти.
Попутно исправил IMAP: после `* BYE` терялся тегированный ответ (LOGOUT, обрыв после неудачных входов).
## Проверка
- `./gradlew :backend:test`: 68 тестов, 0 упало (новые: `LoginGuardTest`, `LoginGuardConfigTest`, `AuthenticationControllerTest`, по одному в `SmtpServerTest`/`ImapServerTest`).
- Живой запуск jar на временной Postgres: 4 неверных → `429` даже с верным паролем, ответ ~1,2 с на неверный; через прокси (`X-Forwarded-For` с localhost) — другой IP, `200`; блок виден в логе.
Не сделано: лимит на регистрацию (на публичной почте она закрыта).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Один LoginGuard на все проверки пароля (SMTP AUTH, IMAP LOGIN/AUTHENTICATE,
вход в веб, смена пароля): 10 неверных с IP за 15 мин → блок 15 мин, дальше
вдвое дольше до суток; 20 неверных на ящик с разных IP → ящик закрыт, кроме
IP, с которых в него уже входили. Во время блока пароль не проверяется
(SMTP 421, IMAP BYE + NO [UNAVAILABLE], веб 429 + Retry-After); неверный
пароль — ответ через 1 с; 3 неверных в соединении — обрыв.
X-Forwarded-For веб-входа — только от прокси в частной сети, иначе
заголовок отбрасывается (подменой IP лимит не обойти).
Попутно: IMAP терял тегированный ответ после "* BYE" (LOGOUT, обрыв после
неудачных входов) — takeUntil теперь после тегированной строки.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Что
Защита от перебора паролей перед выходом почты в интернет (
mail.jambocheck.com, 75.6). Один счётчикLoginGuardна все проверки пароля: SMTPAUTH(25/587/465), IMAPLOGIN/AUTHENTICATE, вход в веб, смена пароля.421 4.7.0+ обрыв, IMAP* BYE+NO [UNAVAILABLE], веб429+Retry-After.X-Forwarded-Forпринимается только от прокси в частной сети (своя заменаforwardedHeaderTransformer); с публичного адреса — отбрасывается. Важно дляdocker-compose.public.yml: порт 8080 там опубликован и на публичном адресе ВМ.LOGIN_GUARD_*(README), счётчики в памяти.Попутно исправил IMAP: после
* BYEтерялся тегированный ответ (LOGOUT, обрыв после неудачных входов).Проверка
./gradlew :backend:test: 68 тестов, 0 упало (новые:LoginGuardTest,LoginGuardConfigTest,AuthenticationControllerTest, по одному вSmtpServerTest/ImapServerTest).429даже с верным паролем, ответ ~1,2 с на неверный; через прокси (X-Forwarded-Forс localhost) — другой IP,200; блок виден в логе.Не сделано: лимит на регистрацию (на публичной почте она закрыта).
🤖 Generated with Claude Code