Шифрование сейчас все актуальнее и актуальнее. Проникает во все сферы. Почта и postfix также не остаются в стороне. Поэтому обсудим что такое Postfix TLS/STARTTLS и что как настраивать и почему.
На SMTP/25 обычно включают opportunistic STARTTLS. Это значит, что если отправители умеют — шифруемся, если нет — всё равно принимаем, иначе потеряете часть писем. А вот на submission/587 для своих клиентов (почтовики, сайты, приложения) шифрование можно и нужно сделать обязательным.
Будем думать, что уже есть:
- FQDN для почтового сервера, например mail.example.com, который резольвится на ваш IP.
- Открыты порты: 25 (SMTP), 587 (submission), опционально 465 (smtps), плюс 80/443 или DNS‑доступ для выпуска сертификата.
- Postfix установлен и работает.
Выпускаем сертификат Let’s Encrypt (certbot)
Устанавливаем certbot (на Ubuntu 22.04 обычно через snap или apt — выберите ваш стандарт), затем получаем сертификат для имени mail‑хоста. В итоге должны появиться файлы:
- /etc/letsencrypt/live/mail.example.com/fullchain.pem
- /etc/letsencrypt/live/mail.example.com/privkey.pem
Включаем STARTTLS на входящем SMTP/25
Откройте /etc/postfix/main.cf и добавьте параметры:
# Входящие SMTP-соединения: предлагаем STARTTLS, но не требуем
smtpd_tls_security_level = may
# Сертификат Let's Encrypt
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
# Кеш TLS-сессий (меньше CPU на рукопожатиях)
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
# Умеренная детализация TLS в логах для диагностики
smtpd_tls_loglevel = 1
Почему may? Порт 25 используется для передачи почты между почтовыми серверами (MTA-MTA), а не от пользователя к серверу. Заставлять весь интернет шифроваться на 25 нельзя «безболезненно» — часть серверов просто не доставит вам письма.
Делаем обязательный TLS на submission/587
Порт 587 (submission) используется для отправки почты почтовыми клиентами (Outlook, Thunderbird) на почтовый сервер, выступая как современный и безопасный канал, который требует аутентификации и обеспечивает шифрование.
В /etc/postfix/master.cf включите (или добавьте) сервис submission и переопределите настройки только для него:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
Ключевые строки:
smtpd_tls_security_level=encrypt— TLS обязателен на 587 (без STARTTLS клиент не сможет отправлять).smtpd_tls_auth_only=yes— запрещает аутентификацию без шифрования
Исходящая доставка
Включаем режим TLS «по возможности». Чтобы Postfix шифровался при доставке на внешние домены (где TLS поддерживается):
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
Если поставить encrypt глобально, начнутся потери отправки (недоставки) на домены без TLS (или с кривым TLS). Но и выключать шифрование отправки нельзя, так как это снижает доверие к вашей почте (будете попадать в СПАМ). Поэтому для «интернета целиком» лучше использовать may.
Применяем:
sudo postfix check
sudo systemctl reload postfix
Автообновление сертификата
Let’s Encrypt сертификаты обновляются автоматически, но Postfix должен «подхватить» новые файлы. Вариант — использовать post-hook/deploy-hook механику, чтобы после renew выполнялся systemctl reload postfix.
Какие отличия между post-hook и deploy-hook? При ключе post-hook скрипты запустятся всегда, независимо от успеха обновления сертификата (success или failure), а во втором случае, только после удачного обновления.
Варианты настройки, первый простой. Добавить опцию --post-hook или --deploy-hook в crontab строку:
0 1 * * 7 certbot renew --post-hook "systemctl restart postfix; systemctl restart dovecot"
Второй вариант – создать шелл-скрипт в директории /etc/letsencrypt/renewal-hooks/post/, либо /etc/letsencrypt/renewal-hooks/deploy/ например, restart-services.sh
#!/bin/sh
systemctl restart postfix
systemctl restart dovecot
И установить права на выполнение:
chmod +x /etc/letsencrypt/renewal-hooks/deploy/restart-services.sh
Быстрая проверка STARTTLS
Как проверить, что все настроили правильно и что всё работает? Проверка 25 порта:
penssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com
Проверка 587 порта
openssl s_client -starttls smtp -connect mail.example.com:587 -servername mail.example.com
Что важно увидеть:
- сертификат выдан на нужное имя (SAN/CN), цепочка без ошибок, рукопожатие проходит.
- на 587 без STARTTLS соединение должно «ругаться» и не давать логиниться, если включён обязательный TLS.
Типовые ошибки в логах Postfix и лечение
Логи на Ubuntu чаще всего смотрят через:
sudo tail -f /var/log/mail.log
или journalctl -u postfix -f
Postfix не может прочитать privkey (permission denied)
Это ошибки загрузки ключа/сертификата, TLS не поднимается. Частая причина — права доступа к /etc/letsencrypt/… и privkey.pem, которые Postfix (и Dovecot) не читают по умолчанию.
Что делать? Корректно разрешить доступ (группа/ACL/разрешения) так, чтобы Postfix мог читать ключ, но ключ не стал «общем достоянием» для всех.
Клиент на 587-й подключается, но не видит STARTTLS и не может отправить
Причина: вы включили TLS только в main.cf, но не активировали submission (что-то не так настроили) в master.cf или не переопределили там smtpd_tls_security_level=encrypt
Проверьте блок submission и сделайте systemctl reload postfix
«TLS library problem», «SSL_accept error», «handshake failure»
Обычно связано с несовместимостью по протоколам/шифрам или с неправильной цепочкой сертификатов. Начните с проверки через openssl s_client и проверьте, что используете fullchain.pem, а не «обрезанный» сертификат.