Перейти к содержанию

Расширенная настройка SSL

Let's Encrypt (из коробки)

Контейнер «acme-animails» попытается получить сертификат LE для ${MAILCOW_HOSTNAME}, autodiscover.ADDED_MAIL_DOMAIN и autoconfig.ADDED_MAIL_DOMAIN.

Нужны Wildcard-сертификаты или есть ограничения брандмауэра?

Если вам нужны wildcard-сертификаты (*.example.com) или ваш сервер animails недоступен по порту 80, рассмотрите возможность использования DNS-01 challenge вместо метода HTTP-01, описанного на этой странице. DNS-01 работает без необходимости открывать порт 80 и поддерживает полноценные wildcard-сертификаты.

Важно

animails должен быть доступен по порту 80 для работы ACME-клиента. Наши примеры конфигураций обратного прокси (reverse proxy) предусматривают это. Вы также можете использовать любой внешний ACME-клиент (например, certbot) для получения сертификатов, но вам нужно будет убедиться, что они скопированы в правильное место, а post-hook скрипт перезапускает затронутые контейнеры. Подробнее см. в документации по Reverse Proxy.

По умолчанию (когда в animails добавлено 0 доменов) система попытается получить сертификат для ${MAILCOW_HOSTNAME}.

Для каждого добавляемого домена система будет пытаться разрешить autodiscover.ADDED_MAIL_DOMAIN и autoconfig.ADDED_MAIL_DOMAIN в его IPv6-адрес или — если IPv6 не настроен — в IPv4-адрес. В случае успеха имя будет добавлено как SAN (Subject Alternative Name) в запрос сертификата.

В SAN будут добавлены только те имена, которые прошли проверку.

При удалении домена сертификат будет перемещен и будет запрошен новый сертификат. Невозможно сохранить домены в сертификате, если мы не можем пройти проверку для них.

Если вы хотите перезапустить ACME-клиент, используйте следующую команду:

docker compose restart acme-animails
docker-compose restart acme-animails

Мониторинг логов:

docker compose logs --tail=200 -f acme-animails
docker-compose logs --tail=200 -f acme-animails

Дополнительные доменные имена

Отредактируйте "animails.conf" и добавьте параметр ADDITIONAL_SAN следующим образом:

Не используйте кавычки (") и пробелы между именами!

ADDITIONAL_SAN=smtp.*,cert1.example.com,cert2.example.org,whatever.*

Каждое имя будет проверено на соответствие его IPv6-адресу или — если IPv6 не настроен — IPv4-адресу.

Имя с маской, например smtp.*, попытается получить SAN вида smtp.DOMAIN_NAME для каждого домена, добавленного в animails.

Поведение Wildcard зависит от типа проверки (Challenge)

Имена с маской в ADDITIONAL_SAN работают по-разному в зависимости от метода проверки:

  • HTTP-01 (эта страница): smtp.* создает smtp.DOMAIN для каждого домена в animails (например, smtp.example.com, smtp.another.org).
  • DNS-01: Поддерживает настоящие wildcard-имена, такие как *.example.com, охватывающие все поддомены.

Для получения настоящих wildcard-сертификатов см. SSL с DNS-01 Challenge.

Выполните следующую команду для автоматического пересоздания затронутых контейнеров:

docker compose up -d
docker-compose up -d

Информация

Использование имен, отличных от MAILCOW_HOSTNAME, для доступа к интерфейсу animails может потребовать дополнительной настройки.

Если вы планируете использовать имя сервера, отличное от MAILCOW_HOSTNAME, для доступа к UI animails (например, добавив mail.* в ADDITIONAL_SAN), обязательно укажите это имя в animails.conf через ADDITIONAL_SERVER_NAMES. Имена должны быть разделены запятыми и не должны содержать пробелы. Если пропустить этот шаг, animails может отобразить некорректный сайт.

ADDITIONAL_SERVER_NAMES=webmail.domain.tld,other.example.tld

Для применения изменений выполните:

docker compose up -d
docker-compose up -d

Принудительное обновление

Чтобы форсировать обновление сертификата, необходимо создать файл с именем force_renew и перезапустить контейнер acme-animails:

cd /opt/animails
touch data/assets/ssl/force_renew
docker compose restart acme-animails
# Проверьте логи на наличие процесса обновления
docker compose logs --tail=200 -f acme-animails
cd /opt/animails
touch data/assets/ssl/force_renew
docker-compose restart acme-animails
# Проверьте логи на наличие процесса обновления
docker-compose logs --tail=200 -f acme-animails

Файл будет удален автоматически.

Ошибки валидации и как их пропустить

Вы можете пропустить проверку IP, установив SKIP_IP_CHECK=y в animails.conf (без кавычек). Имейте в виду, что из-за неправильной конфигурации вы можете попасть под ограничение частоты запросов (ratelimit) от Let's Encrypt! Это полезно в основном для систем с несколькими IP, где проверка IP может вернуть неверный исходящий адрес. Из-за использования динамических IP для acme-animails, исходящий NAT может меняться после перезагрузки.

Если у вас возникли проблемы с «HTTP-валидацией», но подтверждение IP-адреса проходит успешно, скорее всего, вы используете firewalld, ufw или другой брандмауэр, который запрещает соединения от br-animails к вашему внешнему интерфейсу. И firewalld, и ufw запрещают это по умолчанию. Часто недостаточно просто остановить эти службы. Вам потребуется остановить animails, остановить службу брандмауэра, очистить цепочки (flush chains) и перезапустить Docker.

Вы также можете пропустить этот метод проверки, установив SKIP_HTTP_VERIFICATION=y в "animails.conf". Предупреждаем, что это не рекомендуется. В большинстве случаев HTTP-проверка пропускается для обхода проблем с NAT reflection, которые не решаются игнорированием этой сетевой ошибки. Если у вас возникли проблемы с генерацией записей TLSA в обзоре DNS внутри animails, скорее всего, у вас есть проблемы с NAT reflection, которые следует исправить.

Если вы изменили параметр SKIP_*, выполните команду ниже для применения изменений:

docker compose up -d
docker-compose up -d

Отключение Let's Encrypt

Полное отключение Let's Encrypt

Установите SKIP_LETS_ENCRYPT=y в "animails.conf" и пересоздайте "acme-animails":

docker compose up -d
docker-compose up -d

Пропуск всех имен, кроме ${MAILCOW_HOSTNAME}

Добавьте ONLY_MAILCOW_HOSTNAME=y в "animails.conf" и пересоздайте "acme-animails":

docker compose up -d
docker-compose up -d

Лимит Let's Encrypt subjectAltName в 100 доменов

В настоящее время у Let's Encrypt действует лимит в 100 доменных имен на один сертификат.

По умолчанию «acme-animails» создает один SAN-сертификат для всех проверенных доменов (см. первый раздел и Дополнительные имена доменов). Это обеспечивает наилучшую совместимость, но означает, что лимит Let's Encrypt будет превышен, если вы добавите слишком много доменов в одну установку animails.

Чтобы решить эту проблему, вы можете настроить ENABLE_SSL_SNI для генерации:

  • Основного сертификата сервера с MAILCOW_HOSTNAME и всеми полными доменными именами (FQDN) из конфига ADDITIONAL_SAN.
  • Одного дополнительного сертификата для каждого домена, найденного в базе данных, с autodiscover., autoconfig. и любыми другими ADDITIONAL_SAN, настроенными в этом формате (subdomain.*).
  • Ограничения: Имя сертификата в формате ADDITIONAL_SAN=test.example.com будет добавлено как SAN в основной сертификат. Отдельная пара сертификат/ключ для такого формата генерироваться не будет.

Postfix, Dovecot и Nginx будут отдавать эти сертификаты с использованием SNI.

Установите ENABLE_SSL_SNI=y в "animails.conf" и пересоздайте "acme-animails":

docker compose up -d
docker-compose up -d

Внимание

Не все клиенты поддерживают SNI, см. документацию Dovecot или Википедию. Если вы включите эту функцию, убедитесь, что такие клиенты используют MAILCOW_HOSTNAME для защищенных соединений.

Пример:

  • MAILCOW_HOSTNAME=server.email.tld
  • ADDITIONAL_SAN=webmail.email.tld,mail.*
  • Почтовые домены animails: "domain1.tld" и "domain2.tld"

Будут созданы следующие сертификаты:

  • server.email.tld, webmail.email.tld -> это сертификат по умолчанию, все клиенты могут подключаться через эти домены.
  • mail.domain1.tld, autoconfig.domain1.tld, autodiscover.domain1.tld -> индивидуальный сертификат для domain1.tld, не может использоваться клиентами без поддержки SNI.
  • mail.domain2.tld, autoconfig.domain2.tld, autodiscover.domain2.tld -> индивидуальный сертификат для domain2.tld, не может использоваться клиентами без поддержки SNI.

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

Убедитесь, что вы отключили внутренний LE-клиент animails (см. выше).

Чтобы использовать собственные сертификаты, просто сохраните комбинированный сертификат (содержащий сам сертификат и промежуточные CA, если есть) в data/assets/ssl/cert.pem, а соответствующий ключ — в data/assets/ssl/key.pem.

ВАЖНО: Не используйте символические ссылки! Обязательно скопируйте сертификаты, а не ссылайтесь на них в data/assets/ssl.

После этого перезапустите затронутые службы:

docker restart $(docker ps -qaf name=postfix-animails)
docker restart $(docker ps -qaf name=nginx-animails)
docker restart $(docker ps -qaf name=dovecot-animails)

См. Post-hook скрипт для сторонних ACME-клиентов для ознакомления с полным примером скрипта.

Тестирование через staging-директорию ACME

Отредактируйте animails.conf и добавьте LE_STAGING=y.

Выполните команду ниже для активации изменений:

docker compose up -d
docker-compose up -d

Пользовательский URL директории

Отредактируйте animails.conf и добавьте соответствующий URL в переменную DIRECTORY_URL:

DIRECTORY_URL=https://acme-custom-v9000.api.letsencrypt.org/directory

Вы не можете использовать LE_STAGING одновременно с DIRECTORY_URL. Если установлены оба параметра, будет использоваться только LE_STAGING.

Выполните команду ниже для активации изменений:

docker compose up -d
docker-compose up -d

Использование CAA-записей с параметром accounturi

Let's Encrypt позволяет ограничивать выдачу сертификатов конкретными ID аккаунтов с помощью параметра accounturi в CAA-записях. Вы можете использовать вспомогательный скрипт generate_caa_record.py для генерации CAA-записи с accounturi, которую затем можно добавить у вашего DNS-провайдера:

./helper-scripts/generate_caa_record.py --account-key data/assets/ssl/acme/account.pem --contact mailto:your_acme_email@example.com

Проверка конфигурации

Выполните команду ниже, чтобы выяснить причину ошибки валидации:

docker compose logs --tail=200 acme-animails
docker-compose logs --tail=200 acme-animails

Чтобы проверить, отдает ли Nginx правильный сертификат, просто используйте любой браузер и проверьте сведения о сертификате.

Для проверки сертификатов, отдаваемых Postfix, Dovecot и Nginx, используйте openssl:

# Подключение через SMTP STARTTLS (587)
openssl s_client -starttls smtp -connect MAILCOW_HOSTNAME:587 | openssl x509 -noout -text
# Подключение через SMTP (465)
openssl s_client -connect MAILCOW_HOSTNAME:465 | openssl x509 -noout -text

# Подключение через IMAP STARTTLS (143)
openssl s_client -starttls imap -connect MAILCOW_HOSTNAME:143 | openssl x509 -noout -text
# Подключение через IMAP (993)
openssl s_client -connect MAILCOW_HOSTNAME:993 | openssl x509 -noout -text

# Подключение через HTTPS (443)
openssl s_client -connect MAILCOW_HOSTNAME:443 | openssl x509 -noout -text

Чтобы проверить даты истечения срока действия, возвращаемые openssl для MAILCOW_HOSTNAME, можно использовать наш вспомогательный скрипт:

cd /opt/animails
bash helper-scripts/expiry-dates.sh