Два резервирующих друг друга сервера и одно имя для клиентов: общий SAN-сертификат через DNS-проверку и его раздача на обе машины

Что было. Два почтовых сервера (основной и резервный) обслуживают несколько доменов. При переключении DNS на резервный клиенты получают ошибку сертификата: сертификат резервного сервера выдан на его имена, а клиенты ходят по имени, которое было на основном.

Что предложили (подтверждено). Один сертификат со всеми именами (SAN) для обоих серверов, получаемый через проверку DNS-01, потому что HTTP-проверка требует, чтобы запрос попал именно на тот сервер, который запрашивает. Для DNS-01 нужен способ автоматически ставить TXT-записи: либо API DNS-провайдера (плагины certbot), либо делегирование _acme-challenge на отдельный маленький DNS-сервер для ACME (acme-dns), что участник счёл проще, чем динамические обновления основного DNS. Сертификат получает одна машина и раздаёт второй по хуку.

Схема.

  1. На сервере A: certbot certonly --dns-<провайдер> --dns-<провайдер>-credentials /root/.secrets/dns.ini -d mail.example.net -d mx1.example.net -d mx2.example.net -d imap.example.org … (либо --manual --preferred-challenges dns с acme-dns через хук-скрипт).
  2. Хук развёртывания /etc/letsencrypt/renewal-hooks/deploy/sync-to-b.sh:
    #!/bin/sh
    rsync -aL --chmod=D700,F600 /etc/letsencrypt/live/mail.example.net/ certsync@mx2.example.net:/etc/ssl/mail/
    ssh certsync@mx2.example.net 'sudo systemctl reload postfix dovecot'
    systemctl reload postfix dovecot
    
    Отдельный ключ и пользователь certsync на B с sudo только на перезагрузку служб.
  3. На B службы читают сертификат из /etc/ssl/mail/; certbot на B не нужен.
  4. Раз в квартал проверять: openssl s_client -connect mx2.example.net:993 -servername mail.example.net </dev/null | openssl x509 -noout -dates -ext subjectAltName.

Про TTL и переключение. Клиенты кэшируют DNS на время TTL; при переключении на резервный сервер часть клиентов минуты или часы будет ходить на старый адрес. Короткий TTL (300 с) для записей, которые участвуют в переключении, и одинаковый сертификат на обоих серверах делают переключение незаметным.

Альтернативы. Wildcard-сертификат (*.example.net) тоже только через DNS-01 и покрывает все поддомены одного домена, но не разные домены; для нескольких доменов нужен SAN. Отдельные сертификаты на каждом сервере на все имена (каждый получает свой через DNS-01) избавляют от раздачи, но удваивают запросы к центру сертификации и требуют DNS-доступа с обоих серверов.

Замечание про почту. Почтовые клиенты проверяют имя сервера из своих настроек (mail.example.net) против SAN сертификата того сервера, к которому подключились; MX-имена (mx1, mx2) в сертификате нужны для входящего SMTP с проверкой TLS (DANE/MTA-STS). Поэтому в SAN включать и клиентские, и MX-имена.

Плагины DNS описаны в документации certbot.