UMGUM.COM (лучше) 

Let‘s Encrypt + Zimbra ( Настройки подсистемы получения и автоматического обновления сертификатов "Let's Encrypt" для почтового сервиса "Zimbra". )

15 сентября 2019  (обновлено 1 января 2020)

OS: "Linux Ubuntu 16/18 LTS", "Linux Debian 8/9/10".
Application: "Certbot client v.0.28/1.0" for "Let`s Encrypt" (on Python), "Zimbra".

Основная инструкция по настройке "Let`s Encrypt" в спарке с web-сервером "Nginx" опубликована отдельно. Здесь рассматриваются лишь отличия от неё в плане интеграции со встроенным в комплекс приложений почтового сервиса "Zimbra" web-сервером "Nginx".

Инструкция на сайте разработчиков "Zimbra" подразумевает длительную остановку сервиса для запроса сертификатов и последующего их применения. На мой взгляд это категорически неприемлемо.

Для валидации на базе FQDN используется протокол HTTP, а пользовательский web-интерфейс должен работать в максимально безопасном режиме, только на HTTPS. Таким образом можно указать "Zimbra" не использовать порт TCP:80 (по умолчанию уже так и есть), выделив его для сервиса "Let`s Encrypt".


Предварительная настройка интегрированного в "Zimbra" сервера "Nginx".

Несмотря на то, что компоненты почтовой системы "Zimbra" (по большей части написанные на "Java") могут обслуживать сетевые подключения пользователей самостоятельно, в целях оптимизации и удобства перенаправления трафика их спрятали за фронтальным web-прокси, в роли которого используется легковесный сервер "Nginx".

Как и все компоненты "Zimbra", web-прокси настраивается динамически, в процессе запуска сервиса, путём сборки из нескольких блоков конфигурации (в директории "/etc/opt/conf/nginx"), подключение которых определяется параметрами глобальной конфигурации. Изменять или дополнять эти файлы конфигурации нет необходимости - достаточно указать сервису использовать удобные нам.

За интересующую нас часть режима работы web-прокси отвечает значение пары параметров конфигурации:

# su - zimbra
$ zmprov gs `zmhostname` | grep -i mailmode

zimbraMailMode: https
zimbraReverseProxyMailMode: https

Если действующий режим не "https", переключиться в него можно задав соответствующим переменным конфигурации нужно значение:

$ zmprov ms `zmhostname` zimbraReverseProxyMailMode https
$ zmprov ms `zmhostname` zimbraMailMode https

Убедимся, что "Zimbra" прослушивает только TCP:443:

# netstat -apn | grep -i 'listen' | grep -ie '^tcp' | grep -E ':(80|443)\s'

tcp ... 0.0.0.0:443 0.0.0.0:* LISTEN .../nginx: master

Развёртываем выделенный web-сервер "Nginx".

Устанавливаем предназначаемый для обслуживания запросов "Let`s Encrypt" web-сервер "Nginx":

# apt-get install --no-install-recommends nginx-light

Создаём локальную директорию, которая доступна для чтения web-серверу, куда утилита "Certbot client" будет укладывать временные валидационные файлы, размещая заодно там тестовую HTML-страничку:

# mkdir -p /var/www/letsencrypt/.well-known/acme-challenge/
# echo "Let\`s Encrypt" > /var/www/letsencrypt/.well-known/acme-challenge/index.html
# chown certbot:www-data -R /var/www/letsencrypt

Формируем описание простейшего сайта, обрабатывающего только запросы валидации через зарезервированный ISRG путь к ресурсам "/.well-known/acme-challenge/" и перенаправляющего всё остальное сервису "Zimbra", работающему на HTTPS:

# vi /etc/nginx/sites-enabled/mail.example.net

server {
  listen 80;
  server_name mail.example.net;

  # Блок обработки запросов верификации Let`s Encrypt
  location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /var/www/letsencrypt;
    break;
  }

  # Блок перехвата всего остального трафика HTTP и перенаправления его в HTTPS
  location ~* ^/(?!(\.well-known)) {
    rewrite ^ https://$host$request_uri permanent;
  }
}

Деактивируем дистрибутивный вариант конфигурации, проверяем синтаксическую корректность нашей и указываем web-серверу принять изменения:

# rm -f /etc/nginx/sites-enabled/default
# ln -s /etc/nginx/sites-available/mail.example.net /etc/nginx/sites-enabled/mail.example.net
# nginx -t && systemctl reload nginx

Теперь у нас два web-сервера "Nginx", каждый из которого прослушивает назначенный ему TCP-порт:

# netstat -apn | grep -i 'listen' | grep -ie '^tcp' | grep -E ':(80|443)\s'

tcp ... 0.0.0.0:80  0.0.0.0:* LISTEN .../nginx: master
tcp ... 0.0.0.0:443 0.0.0.0:* LISTEN .../nginx: master

Проверяем, доступен ли через HTTP файл ".well-known/acme-challenge/index.html" из интернета:

$ wget -nv -O - http://mail.example.net/.well-known/acme-challenge/index.html

Первичное получение и применение SSL-сертификата.

Прежде всего скорее всего придётся вручную получить сертификат какого-нибудь корневого центра проверки подлинности - не все компоненты "Zimbra" способны сделать это самостоятельно, а сертификаты "Let`s Encrypt" содержат цепочку только до своих серверов, предполагая, что сертификаты таковых уже будут присутствовать в клиентских приложениях. Для современных web-браузеров это работает, но java-приложения "Zimbra" наверняка это не примут.

В современных дистрибутивах "Linux" подходящий SSL-сертификат возможно уже имеется, например в "Linux Ubuntu 18" он размещён в файле "/etc/ssl/certs/DST_Root_CA_X3.pem".

Если требуемого сертификата нет, то получим его с сайта сервиса "IdenTrust". На странице загрузки "https://www.identrust.com/dst-root-ca-x3" забираем содержимое сертификата "DST Root CA X3" и размещаем в текстовом файле, предполагая в дальнейшем неоднократное его использование:

# mkdir -p /usr/local/etc/ssl/certs
# vi /usr/local/etc/ssl/certs/DST_Root_CA_X3.pem

-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
....
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----

Подготовка окружения, установка "Certbot Client" и запрос сертификатов "Let`s Encrypt" не представляют сложности и рассматриваются в основной инструкции. После того, как SSL-сертификаты получены, потребуется дополнить их "корневым" и проверить их корректность с точки зрения "Zimbra".

Делаем резервную копию возможно уже используемых сертификатов, выкладываем вместо них свежие и дополняем их ранее вручную полученным "корневым":

# mkdir -p /opt/zimbra/ssl/letsencrypt
# cp -f /etc/letsencrypt/live/mail.example.net/* /opt/zimbra/ssl/letsencrypt/
# cat /usr/local/etc/ssl/certs/DST_Root_CA_X3.pem >> /opt/zimbra/ssl/letsencrypt/chain.pem
# chown -R zimbra:zimbra /opt/zimbra/ssl/letsencrypt

Проверяем корректность сертификатов утилитой из дистрибутивного набора "Zimbra":

# su - zimbra
$ cd /opt/zimbra/ssl/letsencrypt
$ /opt/zimbra/bin/zmcertmgr verifycrt comm privkey.pem cert.pem chain.pem

Сохраняем резервную копию набора действующих сертификатов:

# cp -a /opt/zimbra/ssl/zimbra /opt/zimbra/ssl/zimbra.$(date "+%Y%m%d")

Перед применением SSL-сертификатов в "Zimbra" потребуется подложить в "секретное место" закрытый ключ, переименовав его попутно в соответствии с предписаниями:

$ cp -f /opt/zimbra/ssl/letsencrypt/privkey.pem /opt/zimbra/ssl/zimbra/commercial/commercial.key

Указываем "Zimbra" применить новые сертификаты для всех компонентов:

$ cd /opt/zimbra/ssl/letsencrypt
$ /opt/zimbra/bin/zmcertmgr deploycrt comm cert.pem chain.pem
$ echo $?

Раскладывание сертификатов по конфигурациям компонентов происходит быстро, но дальнейшее применение их потребует перезапуска "Zimbra", что вызовет пару минут простоя сервиса:

# su - zimbra
$ zmcontrol restart
$ zmcontrol status

Проверка использования сертификата.

Web via HTTPS:

$ echo QUIT | openssl s_client -connect mail.example.net:443 | openssl x509 -noout -text | less

IMAP via SSL:

$ echo QUIT | openssl s_client -connect mail.example.net:993 | openssl x509 -noout -text | less

POP3 via SSL:

$ echo QUIT | openssl s_client -connect mail.example.net:995 | openssl x509 -noout -text | less

SMTP via SSL:

$ echo QUIT | openssl s_client -connect mail.example.net:465 | openssl x509 -noout -text | less

SMTP via TLS/StartTLS:

$ echo QUIT | openssl s_client -starttls smtp -connect mail.example.net:587 | openssl x509 -noout -text | less

Очевидно, что вывод выше приводимых запросов не должен содержать уведомлений об ошибках. Кроме того полезно приглядеться к датам выдачи и срока прекращения действия сертификата - вдруг он не обновился на самом деле, будучи при этом корректным до скорого истечения.

Автоматизация продления сертификатов.

Общая идея и способ реализации автоматического продления сертификатов рассматривается в основной инструкции, а здесь лишь приводится специфичный для "Zimbra" набор команд применения обновлённой конфигурации:

# vi /opt/eff.org/cert-renew.sh

#!/bin/bash
....

# Даём указание использующей сертификаты почтовой системе "Zimbra" принять сертификаты
[ "${?}" -eq "0" ] && /opt/eff.org/cert-apply-zimbra.sh
....

Повторяющий рассматриваемые на протяжении инструкции выше шаги скрипт адаптации сертификатов "Let`s Encrypt" к формату "Zimbra" и применения таковых в почтовой системе:

# vi /opt/eff.org/cert-apply-zimbra.sh && chmod +x /opt/eff.org/cert-apply-zimbra.sh

#!/bin/bash

# Preparation of certificates
rm -rf /opt/zimbra/ssl/letsencrypt
mkdir -p /opt/zimbra/ssl/letsencrypt
cp -f /etc/letsencrypt/live/mail.example.net/* /opt/zimbra/ssl/letsencrypt/
cat /usr/local/etc/ssl/certs/DST_Root_CA_X3.pem >> /opt/zimbra/ssl/letsencrypt/chain.pem

# Сertificate placement
cp -a /opt/zimbra/ssl/zimbra /opt/zimbra/ssl/zimbra_prev
cp -f /opt/zimbra/ssl/letsencrypt/privkey.pem /opt/zimbra/ssl/zimbra/commercial/commercial.key
chown -R zimbra:zimbra /opt/zimbra/ssl/letsencrypt
chown -R zimbra:zimbra /opt/zimbra/ssl/zimbra

# Activation of the certificate in Zimbra
sudo -i -u zimbra -- bash -c "cd /opt/zimbra/ssl/letsencrypt && /opt/zimbra/bin/zmcertmgr deploycrt comm cert.pem chain.pem"

# Application restart
[ "${?}" -eq "0" ] && { sudo -i -u zimbra /opt/zimbra/bin/zmcontrol restart; }

exit $?


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )