Расширенная настройка 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.tldADDITIONAL_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