Что нового

Как исправить Let’s Encrypt, Dovecot и SMTP в Thunderbird на старом почтовом сервере

Как я восстановил Let's Encrypt для mail.examle.com и исправил подключение Thunderbird к старому Dovecot/Postfix​

2bb49cde806a3719660d7f0b2767774e.webp

В этой статье я разберу реальный случай с почтовым сервером mail.examle.com.

Сервер достаточно старый:

  • Dovecot 2.0.9;
  • OpenSSL 1.0.1e-fips;
  • старый Postfix;
  • nginx;
  • Let's Encrypt через устаревший letsencrypt-auto.

Проблема началась с того, что перестало нормально проходить обновление сертификата Let's Encrypt, а после его получения Thunderbird всё равно не хотел подключаться к почтовому серверу.

В итоге оказалось, что здесь наложились сразу несколько независимых проблем:

  1. nginx перенаправлял запрос проверки Let's Encrypt с HTTP на HTTPS;
  2. certbot-auto уже официально не поддерживается;
  3. Dovecot использовал устаревшие 1024-битные DH-параметры;
  4. SMTP на порту 465 согласовывал древний TLS 1.0;
  5. Thunderbird нормально заработал после перехода SMTP на порт 587 с STARTTLS.

Ниже покажу всю диагностику по порядку.

Исходная ошибка Let's Encrypt​


Я запускал получение сертификата следующим образом:

Bash:
./letsencrypt-auto certonly \
    -a webroot \
    --agree-tos \
    --renew-by-default \
    --webroot-path=/usr/www/mail \
    -d mail.examle.com

Certbot сразу предупреждал:

Код:
Your system is not supported by certbot-auto anymore.
certbot-auto and its Certbot installation will no longer receive updates.

Это отдельная проблема: certbot-auto давно устарел и больше не получает обновлений.

Но непосредственно выпуск сертификата ломался по другой причине:

Код:
Challenge failed for domain mail.examle.com

Domain: mail.examle.com
Type: connection

Detail: 192.145.97.65: Fetching
https://mail.examle.com/.well-known/acme-challenge/...
Error getting validation data

Особенно важной здесь была строка:

Код:
Fetching https://mail.examle.com/.well-known/acme-challenge/...

Для HTTP-01 challenge проверка первоначально приходит по HTTP, то есть на порт 80.

Почему nginx ломал ACME challenge​


В конфигурации mail.examle.com у меня был такой редирект:

NGINX:
if ($scheme = http) {
    return 301 https://$server_name$request_uri;
}

Одновременно был location для Let's Encrypt:

NGINX:
location ~ /.well-known {
    root /usr/www/mail;
    allow all;
}

На первый взгляд всё выглядело правильно.

Но серверный return 301 отправлял в HTTPS в том числе запросы:

Код:
http://mail.examle.com/.well-known/acme-challenge/...

В результате получалась цепочка:

Код:
HTTP :80
   ↓
301 Redirect
   ↓
HTTPS :443
   ↓
ошибка проверки ACME

Правильная конфигурация nginx для ACME​


Я разделил HTTP и HTTPS.

Для HTTP оставил отдельный server:

NGINX:
server {
    listen 192.145.97.65:80;
    server_name mail.examle.com;

    location ^~ /.well-known/acme-challenge/ {
        root /usr/www/mail;
        default_type text/plain;
        try_files $uri =404;
        allow all;
    }

    location / {
        return 301 https://mail.examle.com$request_uri;
    }
}

Таким образом:

  • обычные HTTP-запросы перенаправляются на HTTPS;
  • /.well-known/acme-challenge/ остаётся доступным непосредственно по HTTP.

А HTTPS работает отдельно:

NGINX:
server {
    listen 192.145.97.65:443 ssl;
    server_name mail.examle.com;

    ssl_certificate /etc/letsencrypt/live/mail.examle.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mail.examle.com/privkey.pem;

    # Остальная конфигурация сайта
}

Проверка webroot вручную​


Перед новым запуском Let's Encrypt я решил проверить, действительно ли nginx отдаёт файлы из нужного каталога.

Создал тестовый файл:

Bash:
mkdir -p /usr/www/mail/.well-known/acme-challenge

echo "acme-test-ok" \
> /usr/www/mail/.well-known/acme-challenge/test.txt

Проверил nginx:

Bash:
nginx -t

После чего перезагрузил конфигурацию:

Bash:
service nginx reload

И проверил с помощью curl:

Bash:
curl -i http://mail.examle.com/.well-known/acme-challenge/test.txt

Правильный результат:

Код:
HTTP/1.1 200 OK

acme-test-ok

При этом не должно происходить:

Код:
301 Moved Permanently
Location: https://mail.examle.com/...

Также можно проверить непосредственно backend:

Bash:
curl -i \
    -H 'Host: mail.examle.com' \
    http://192.145.97.65/.well-known/acme-challenge/test.txt

После этого сертификат Let's Encrypt успешно выпустился.

Проверяю новый сертификат​


Проверил симлинки:

Bash:
ls -la /etc/letsencrypt/live/mail.examle.com/

В моём случае они уже указывали на свежие файлы сертификата:

Код:
cert.pem
chain.pem
fullchain.pem
privkey.pem

Затем:

Bash:
openssl x509 \
    -in /etc/letsencrypt/live/mail.examle.com/fullchain.pem \
    -noout \
    -subject \
    -issuer \
    -dates

Сертификат был корректный:

Код:
subject=/CN=mail.examle.com
issuer=/C=US/O=Let's Encrypt/...

То есть проблема непосредственно с Let's Encrypt была решена.

Thunderbird всё равно ругается​


После обновления сертификата Thunderbird поначалу продолжал показывать окно добавления исключения безопасности для:

Код:
mail.examle.com:993

Я решил не добавлять исключение, а проверить сервер.

И это правильный подход: если сервер должен использовать нормальный сертификат Let's Encrypt, создавать постоянное исключение в почтовом клиенте не нужно.

Проверяю IMAPS на порту 993​


Сначала проверил, слушает ли порт Dovecot:

Bash:
netstat -lntp | grep ':993'

Результат:

Код:
tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN dovecot

Затем проверил TLS локально:

Bash:
openssl s_client \
    -connect 127.0.0.1:993 \
    -servername mail.examle.com \
    -showcerts </dev/null

И по DNS-имени:

Bash:
openssl s_client \
    -connect mail.examle.com:993 \
    -servername mail.examle.com \
    -showcerts </dev/null

В обоих случаях сертификат был правильным:

Код:
subject=/CN=mail.examle.com
issuer=/C=US/O=Let's Encrypt/...
Verify return code: 0 (ok)

То есть:

  • порт 993 доступен;
  • Dovecot работает;
  • сертификат правильный;
  • цепочка сертификатов валидна.

Проверяю конфигурацию Dovecot​


Проверил:

Bash:
dovecot -n 2>&1 | grep -Ei 'ssl|cert|key|listen|protocol'

Получил:

Код:
listen = *
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.examle.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.examle.com/privkey.pem
protocol imap {

То есть Dovecot уже использовал именно новый Let's Encrypt.

Версия оказалась очень старой:

Bash:
dovecot --version

Результат:

Код:
2.0.9

Обнаруживаю ещё одну проблему: DH 1024​


При TLS-подключении OpenSSL показывал:

Код:
Server Temp Key: DH, 1024 bits

Проверил настройки:

Bash:
doveconf -a | grep -i dh

Получил:

Код:
ssl_dh_parameters_length = 1024

Полные SSL-настройки выглядели примерно так:

Код:
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.examle.com/fullchain.pem
ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL
ssl_dh_parameters_length = 1024
ssl_key = </etc/letsencrypt/live/mail.examle.com/privkey.pem
ssl_parameters_file = ssl-parameters.dat
ssl_parameters_regenerate = 0
ssl_protocols = !SSLv2 !SSLv3

В /etc/dovecot/conf.d/10-ssl.conf при этом находилась строка:

Код:
#ssl_dh_parameters_length = 1024

То есть использовалось значение по умолчанию.

Для такого старого сервера разумно увеличить DH хотя бы до 2048:

Код:
ssl_dh_parameters_length = 2048

После изменения:

Bash:
service dovecot restart

Проверить результат можно так:

Bash:
openssl s_client \
    -connect mail.examle.com:993 \
    -servername mail.examle.com \
    </dev/null 2>&1 |
egrep 'Server Temp Key|Protocol|Cipher|Verify return'

В идеале:

Код:
Server Temp Key: DH, 2048 bits
Protocol  : TLSv1.2
Verify return code: 0 (ok)

ECDHE старый Dovecot не использовал​


Сам OpenSSL на сервере поддерживал ECDHE:

Bash:
openssl ciphers -v | grep ECDHE

Например:

Код:
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-SHA

Но при принудительном подключении:

Bash:
openssl s_client \
    -connect mail.examle.com:993 \
    -servername mail.examle.com \
    -cipher 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA' \
    </dev/null

Dovecot отвечал:

Код:
sslv3 alert handshake failure
no peer certificate available
Cipher is (NONE)

То есть наличие ECDHE в OpenSSL ещё не означает, что конкретная старая версия Dovecot будет его нормально использовать.

Проблема оказалась ещё и в SMTP​


После исправления сертификата Thunderbird всё равно не мог завершить автоматическую проверку учётной записи.

Настройки были такими:

Код:
IMAP:
mail.examle.com
993
SSL/TLS

SMTP:
mail.examle.com
465
SSL/TLS

Я проверил открытые порты:

Bash:
netstat -lntp | egrep ':(465|587|993)\s'

Все необходимые службы слушали:

Код:
0.0.0.0:993
0.0.0.0:587
0.0.0.0:465

Следовательно, дело было не в закрытом порте.

Проверяю SMTP 465​


Запустил:

Bash:
openssl s_client \
    -connect mail.examle.com:465 \
    -servername mail.examle.com \
    -showcerts </dev/null

Сертификат снова был правильный:

Код:
subject=/CN=mail.examle.com
issuer=/C=US/O=Let's Encrypt/...
Verify return code: 0 (ok)

Но в конце обнаружилось главное:

Код:
Server Temp Key: DH, 1024 bits

Protocol  : TLSv1
Cipher    : DHE-RSA-AES256-SHA

То есть SMTP на 465 порту договаривался всего лишь о:

Код:
TLS 1.0

Для современного Thunderbird это уже слишком старый TLS.

Почему порт 465 не работал в Thunderbird​


Сам порт был открыт.

Сертификат был валиден.

DNS был правильным.

Но сервер предлагал старый TLS:

Код:
TLSv1
DHE
DH 1024 bit

Современный Thunderbird такие настройки по умолчанию уже не принимает.

Поэтому я не стал ослаблять настройки безопасности Thunderbird.

Вместо этого проверил второй стандартный SMTP submission порт — 587.

Окончательное решение: SMTP 587 + STARTTLS​


В Thunderbird я изменил только настройки сервера исходящей почты.

Было:

Код:
Сервер: mail.examle.com
Порт: 465
Защита соединения: SSL/TLS

Стало:

Код:
Сервер: mail.examle.com
Порт: 587
Защита соединения: STARTTLS

После этого Thunderbird сразу успешно проверил настройки, и почтовый ящик заработал.

Моя итоговая конфигурация Thunderbird​


Входящая почта — IMAP

Код:
Протокол: IMAP
Сервер: mail.examle.com
Порт: 993
Защита соединения: SSL/TLS
Метод аутентификации: Обычный пароль
Имя пользователя: полный адрес электронной почты

Например:

Код:
admin@examle.com

Исходящая почта — SMTP

Код:
Сервер: mail.examle.com
Порт: 587
Защита соединения: STARTTLS
Метод аутентификации: Обычный пароль
Имя пользователя: полный адрес электронной почты

То есть в моём случае итоговая схема получилась такой:

Код:
IMAP
mail.examle.com:993
SSL/TLS

SMTP
mail.examle.com:587
STARTTLS

Набор команд для быстрой диагностики​


Если столкнусь с подобной проблемой снова, сначала проверю именно эти вещи.

1. Какие почтовые порты слушаются:

Bash:
netstat -lntp | egrep ':(465|587|993)\s'

2. IMAPS:

Bash:
openssl s_client \
    -connect mail.examle.com:993 \
    -servername mail.examle.com \
    </dev/null

3. SMTPS 465:

Bash:
openssl s_client \
    -connect mail.examle.com:465 \
    -servername mail.examle.com \
    </dev/null

4. SMTP Submission 587:

Bash:
openssl s_client \
    -starttls smtp \
    -connect mail.examle.com:587 \
    -servername mail.examle.com \
    </dev/null

5. Сертификат Let's Encrypt:

Bash:
openssl x509 \
    -in /etc/letsencrypt/live/mail.examle.com/fullchain.pem \
    -noout \
    -subject \
    -issuer \
    -dates

6. SSL-настройки Dovecot:

Bash:
doveconf -a | grep -E '^ssl_|^ssl '

7. Версия Dovecot:

Bash:
dovecot --version

8. Версия OpenSSL:

Bash:
openssl version -a

На что смотреть в openssl s_client​


Меня интересуют прежде всего строки:

Код:
subject=
issuer=
Protocol  :
Cipher    :
Server Temp Key:
Verify return code:

Хороший результат проверки сертификата:

Код:
subject=/CN=mail.examle.com
Verify return code: 0 (ok)

Если вижу:

Код:
Protocol : TLSv1

это уже тревожный сигнал для современного почтового клиента.

Если вижу:

Код:
Server Temp Key: DH, 1024 bits

сервер также использует устаревшие DH-параметры.

Не стоит сразу добавлять исключение безопасности​


Если Thunderbird предлагает:

Код:
Добавить исключение безопасности

я теперь сначала проверяю сервер через OpenSSL.

Если сервер должен использовать публичный сертификат Let's Encrypt, лучше устранить причину на сервере, а не создавать постоянное исключение в Thunderbird.

Особенно проверяю:

  • правильное ли имя хоста;
  • правильный ли сертификат отдаётся;
  • полная ли цепочка сертификатов;
  • действителен ли сертификат;
  • какая версия TLS используется;
  • какой cipher согласован;
  • какой размер DH используется;
  • на каком SMTP-порту работает современный TLS.

Что ещё нужно модернизировать​


После восстановления почты сама инфраструктура всё равно остаётся устаревшей.

В моём случае это:

Код:
Dovecot 2.0.9
OpenSSL 1.0.1e-fips
старый Postfix
certbot-auto

Поэтому решение с портом 587 позволило быстро вернуть работоспособность Thunderbird, но в перспективе такой почтовый сервер стоит обновить.

Особенно желательно избавиться от:

  • TLS 1.0;
  • 1024-битного DHE;
  • старого OpenSSL;
  • Dovecot 2.0.x;
  • certbot-auto.

Итог​


В этой ситуации у меня было сразу несколько проблем, поэтому диагностика только сертификата не давала полной картины.

Сначала Let's Encrypt не мог пройти HTTP-01 из-за nginx:

Код:
HTTP → 301 → HTTPS

После исправления nginx новый сертификат успешно выпустился.

Dovecot на 993 уже корректно отдавал сертификат Let's Encrypt:

Код:
Verify return code: 0 (ok)

Но Thunderbird всё равно не завершал настройку.

Причина обнаружилась на SMTP 465:

Код:
Protocol : TLSv1
Server Temp Key: DH, 1024 bits

В итоге мне даже не пришлось серьёзно переделывать Postfix.

Я просто перевёл Thunderbird с:

Код:
SMTP 465 + SSL/TLS

на:

Код:
SMTP 587 + STARTTLS

И после этого всё заработало.

Итоговая рабочая схема:

Код:
IMAP:
mail.examle.com:993
SSL/TLS

SMTP:
mail.examle.com:587
STARTTLS

Для старого почтового сервера это оказалось самым простым способом восстановить работу современного Thunderbird без искусственного снижения требований безопасности на стороне клиента.
Об авторе
Guru
Василий, cистемный админ /gnu/linux/windows/macos/mikrotik/troubleshooter, создатель сайта
Интересуюсь всем что делает инфраструктуру быстрой и надёжной
Открыт к общению и проектам, написать мне можно через форму или в личном сообщении

❗ Если есть пожелания по обзору какого-либо вопроса не представленного на сайте - пиши в комментариях

Комментарии

Нет комментариев для отображения.

Информация о статье

Автор
Guru
Время чтения статьи
8 мин чтения
Просмотры
11
Посл. обновление

Ещё в Работа над ошибками

Ещё от Guru

Поделиться этой статьёй

Назад
Верх