75.1 TLS для SMTP: STARTTLS и неявный TLS (465) #9

Merged
Liosha84 merged 1 commits from feat/75-1-smtp-starttls into master 2026-11-05 19:42:53 +01:00
Owner

Чек-лист Jambotron v0.2.3, 75.1 — шифрование SMTP.

Что сделано

  • STARTTLS на порту SMTP (RFC 3207). Обработчик TLS ставится только после того, как ответ 220 Ready to start TLS ушёл открытым текстом (ответы пишутся по одному). После рукопожатия сессия начинается заново: нужен новый EHLO, прежний MAIL FROM и вход забыты.
  • Защита от подмешивания команд (CVE-2011-0411): каждая строка помечена, пришла ли она через TLS. Строки, присланные открытым текстом вместе со STARTTLS, не выполняются, соединение закрывается. Декодер строк заменяется свежим, чтобы остатки открытого текста не смешались с расшифрованными данными.
  • Неявный TLS на SMTPS_PORT (RFC 8314, обычно 465), по умолчанию выключен.
  • AUTH предлагается только внутри TLS (или без него при SMTP_AUTH_WITHOUT_TLS=true, как сейчас на стенде Jambotron). В Received: пишется ESMTPS/ESMTPSA.
  • Сертификат: свой (MAIL_TLS_CERT + MAIL_TLS_KEY, PEM) или самоподписанный: создаётся один раз в MAIL_TLS_DIR, в образе это /app/data/tls (том data). TLS 1.2/1.3. MAIL_TLS=false выключает TLS.

Проверка

  • :backend:test 38/38. Новые тесты: STARTTLS + AUTH и новая сессия; подмешанный открытый текст; JavaMail со starttls.required; порт 465; переиспользование сертификата.
  • Вживую на временном Postgres: openssl s_client -starttls smtp даёт TLSv1.3, сертификат CN=mail.test. Вход и письмо через TLS прошли. Порт 465 отвечает.

На стенде staging ничего не ломается: Jambotron шлёт письма без TLS и без входа, а STARTTLS клиенту не обязателен. После деплоя сертификат создастся сам.

Не сделано: TLS для IMAP (вместе с переписыванием IMAP, 75.2); Let's Encrypt для настоящей почты (75.6).

— α

🤖 Generated with Claude Code

Чек-лист Jambotron v0.2.3, **75.1 — шифрование SMTP**. **Что сделано** - **STARTTLS** на порту SMTP (RFC 3207). Обработчик TLS ставится только после того, как ответ `220 Ready to start TLS` ушёл открытым текстом (ответы пишутся по одному). После рукопожатия сессия начинается заново: нужен новый `EHLO`, прежний `MAIL FROM` и вход забыты. - **Защита от подмешивания команд (CVE-2011-0411):** каждая строка помечена, пришла ли она через TLS. Строки, присланные открытым текстом вместе со `STARTTLS`, не выполняются, соединение закрывается. Декодер строк заменяется свежим, чтобы остатки открытого текста не смешались с расшифрованными данными. - **Неявный TLS** на `SMTPS_PORT` (RFC 8314, обычно 465), по умолчанию выключен. - `AUTH` предлагается только внутри TLS (или без него при `SMTP_AUTH_WITHOUT_TLS=true`, как сейчас на стенде Jambotron). В `Received:` пишется `ESMTPS`/`ESMTPSA`. - **Сертификат:** свой (`MAIL_TLS_CERT` + `MAIL_TLS_KEY`, PEM) или самоподписанный: создаётся один раз в `MAIL_TLS_DIR`, в образе это `/app/data/tls` (том `data`). TLS 1.2/1.3. `MAIL_TLS=false` выключает TLS. **Проверка** - `:backend:test` 38/38. Новые тесты: STARTTLS + AUTH и новая сессия; подмешанный открытый текст; JavaMail со `starttls.required`; порт 465; переиспользование сертификата. - Вживую на временном Postgres: `openssl s_client -starttls smtp` даёт TLSv1.3, сертификат `CN=mail.test`. Вход и письмо через TLS прошли. Порт 465 отвечает. **На стенде staging ничего не ломается:** Jambotron шлёт письма без TLS и без входа, а `STARTTLS` клиенту не обязателен. После деплоя сертификат создастся сам. **Не сделано:** TLS для IMAP (вместе с переписыванием IMAP, 75.2); Let's Encrypt для настоящей почты (75.6). — α 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Liosha84 added 1 commit 2026-11-05 19:42:12 +01:00
- SmtpServer: STARTTLS (RFC 3207) — SslHandler ставится сразу после того,
  как ответ 220 ушёл открытым текстом; сессия начинается заново; строки,
  присланные открытым текстом вместе со STARTTLS, не выполняются, соединение
  закрывается (CVE-2011-0411); свежий декодер строк без остатков открытого текста
- неявный TLS на SMTPS_PORT (RFC 8314); AUTH — только внутри TLS
  (или SMTP_AUTH_WITHOUT_TLS); Received: ESMTPS/ESMTPSA
- SmtpTls: свой сертификат (MAIL_TLS_CERT/KEY) или самоподписанный,
  создаётся один раз в MAIL_TLS_DIR (в образе /app/data/tls); TLS 1.2/1.3
- тесты: STARTTLS + AUTH, подмешанный открытый текст, JavaMail со
  starttls.required, порт 465, переиспользование сертификата (38 всего)
- проверено вживую: openssl s_client -starttls smtp и порт 465, TLSv1.3

α
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Liosha84 merged commit 73c03b1d6d into master 2026-11-05 19:42:53 +01:00
Sign in to join this conversation.