Pull to refresh

Автоматическое обновление сертификатов LetsEncrypt в почтовом сервере MDaemon: пошаговая инструкция

Reading time10 min
Views14K

Всем привет!

Некоторое время назад ко мне обратился один мой хороший знакомый с внезапно образовавшейся у него проблемой и попросил помочь в её решении. Проблема заключалась в следующем: организация, в которой он работал, имела у себя Windows-сервер с поднятым на нём почтовиком MDaemon от компании Alt-N Technologies. Пару лет назад на этот почтовик был установлен SSL-сертификат StartSSL от компании StartCom. И всё работало вполне себе нормально, каши не просило, как вдруг от StartCom пришло грустное письмо, информирующее о том, что скоро всем их сертификатам придёт полный и безоговорочный кирдык. Мол, спасайтесь — кто может, пока не бомбануло. Сегодня я расскажу вам, как мы спасались — глядишь, кому-нибудь эта информация окажется полезной.

Немного лирики


Что перво-наперво приходит в голову нормальному человеку, когда ему задают вопрос про замену сертификата? Вариантов два: или — а почему бы вам не купить его? Или — так есть же замечательная артель Let's Encrypt, которая бесплатно раздаёт сертификаты направо и налево! Первый вариант был смущённо отвергнут как несостоятельный, ввиду того, что, как было сказано ранее, сервер работал, каши не просил, и объяснять руководству, почему оно должно расстаться с энной суммой вечнозелёных денег желания не было никакого. Второй вариант был просто суперпривлекательным, но на горизонте маячили кое-какие проблемы, которые предстояло объехать: оконность почтовика наводила на грустные размышления о его совместимости со скриптами LetsEncrypt, а получать и устанавливать сертификат вручную каждые три месяца совершенно не хотелось.

Поэтому был выбран второй вариант — только нужно было найти способ автоматизировать процессы получения сертификата и привязки его к почтовику.

Начали мы, естественно, с перекапывания великого и ужасного Интернета в поисках уже готового решения. И, о чудо! Оказалось, что доблестные программисты из Alt-N Technologies уже озаботились этим и выдали на-гора скрипты, делающие всё что нужно! Как говорится — снимаю шляпу! Но и тут не обошлось без ложки дёгтя: эти скрипты просто так всем и каждому не раздавались, а были включены в состав последних версий MDaemon. Однако наш подопечный сервер имел на борту довольно старую версию MDaemon — 13.6.3. Софт был совершенно легальный, купленный некогда за самые что ни на есть настоящие деньги, работал замечательно и его апгрейд в планы руководства конечно же не входил (см. пункт про покупку сертификата).

Поэтому было принято решение попытаться хирургическим путём пересадить скрипты из новой версии MDaemon в старую и заставить их там заработать. Подумано — сделано: на виртуальную машину была установлена самая свежая на тот момент триальная версия MDaemon и из неё изъята папка LetsEncrypt со всем содержимым. Что теперь делать с этим добром? — читайте ниже.

Исходные данные


  • Сервер под управением ОС Windows Server 2008 R2.
  • Почтовый сервер MDaemon версии 13.6.3.
  • На этом же сервере поднят IIS, обслуживающий корпоративный сайт организации.
  • MDaemon использовал собственный встроенный WEB-сервер WorldClient, который был доступен из интернета через порт 3000.

Обязательные требования


Как было написано в этой статье, скрипты LetsEncrypt для MDaemon не являются абсолютно универсальными и предполагают выполнение следующих обязательных условий:

  • Наличие оболочки PowerShell версии 3.0.
  • Наличие установленного фреймворка Microsoft .NET версии не ниже 4.0.
  • Наличие установленного пакета IIS Management Scripts and Tools.
  • Из интернета через порт 80 должен быть доступен WorldClient сервера — либо напрямую, либо через IIS.

Как видим — часть из этих требований исходно не выполнялась, поэтому сначала была выполнена привязка WorldClient к IIS с целью пересадки его на порт 80. Информация о том, как это сделать была получена из вот этой статьи с сайта Alt-N.

Пара слов о «граблях»


Прежде чем приступить к описанию пошаговой инструкции хочу задержать ваше внимание на кое-каких непредвиденных заморочках, осложнивших процесс пересадки скриптов и получения сертификатов.

Во-первых, практически в самом начале скрипта была реализована проверка на то, что параметр 'EnableWCServer' в файле 'Mdaemon.ini' установлен в 'Yes'. И если это было не так, то скрипт немедленно завершал свою работу с выдачей сообщения о критической ошибке 'Error: WorldClient must be enabled'. Но, как это ни странно, в нашем случае этот параметр был установлен в 'No' — несмотря на то, что нами уже была выполнена привязка WorldClient к IIS и WorldClient прекрасно открывался из интернета. Недолго думая, мы отключили эту проверку, закомментарив её в скрипте. Это позволило скрипту продолжить работу.

Во-вторых, на этом же сервере был поднят корпоративный сайт и к кое-каким страницам этого сайта доступ выполнялся по протоколу https с использованием самоподписанного сертификата. А старые Windows-сервера предполагают, что к одному IP может быть привязан только один сертификат. Мы наступили на эти грабли в самом конце пути — когда сертификат от LE уже успешно получался, но никак не мог прибиндиться к адресу 0.0.0.0. В итоге проблема была решена быстрым, но несколько кривоватым способом: WorldClient был отсажен на отдельный IP-адрес (благо он был в наличии) и опять же пришлось править скрипт — в список его входных параметров был добавлен IP-адрес, к которому нужно было привязывать сертификат. А так как привязка WorldClient к IIS была уже полностью выполнена, то мы не стали запускать собственный WEB-сервер MDaemon-а и оставили всё как есть.

Поехали.

Часть 1: предварительная подготовка


  1. Любым известным вам способом делаем бакап сервера!
  2. Устанавливаем .NET версии выше или равной 4.0.
  3. Добавляем Role Services: идём в 'Control Panel' -> 'Administrative Tools' -> 'Server Manager' -> 'Roles' и нажимаем на линк 'Add Role Services'.

    Ставим крыжики на:
    • Web Server/Application Development/ISAPI Extensions
    • Web Server/Application Development/ISAPI Filters
    • Management Tools/IIS Management Scripts and Tools

    Нажимаем 'Next', ну и так далее.
  4. Устанавливаем Windows Management Framework 3.0 — это установит в систему PowerShell версии 3.0 (см. раздел 'Обязательные требования'):
    • Скачиваем WMF 3.0 с сайта Microsoft.
    • Устанавливаем нужный WMF. Для Windows Server 2008 R2 это 'Windows6.1-KB2506143-x64.msu'.
    • Перезагружаем сервер.


Часть 2: создание в IIS сайта для доступа к серверу WorldClient


Примечание 1: если у вас используется встроенный в MDaemon сервер WorldClient и он уже монопольно сидит на порту 80, то можете смело пропустить эту часть и перейти сразу к части 3.

Примечание 2: 'Host name' сайта должно быть таким-же, как полное доменное имя хоста MDaemon, по которому он доступен из интернета.

Чтобы узнать полное доменное имя хоста MDaemon: запускаем GUI Mdaemon, идём в меню: 'Настройка' -> 'Первичный домен/серверы' -> 'Домен и серверы по умолчанию' -> 'Домен' и смотрим поле 'Полное доменное имя хоста'.

Итак, приступим. Запускаем IIS-менеджер и добавляем в нём новый сайт:

  1. В поле 'Site name' вводим название сайта — какое нравится.
  2. В поле 'Physical path' вводим путь к папке HTML World-клиента.
  3. В поле 'Host name' прописываем полное доменное имя хоста (см. примечание 2 выше).
  4. В поле 'IP-address' оставляем 'All unassigned', если интерфейс используется монопольно, или выбираем из списка IP, принадлежащий почтовику.
  5. Поля 'Type' и 'Port' оставляем как есть — 'http' и '80', соответственно.

Редактируем список дефолтных документов сайта - заходим в подраздел 'Default Document':


  1. Очищаем весь список.
  2. Добавляем документ 'WorldClient.dll': в правой панели 'Actions' нажимаем 'Add...' и в поле 'Name' набираем 'WorldClient.dll'.
  3. Добавляем документ 'MDSyncML.dll': в правой панели 'Actions' нажимаем 'Add...' и в поле 'Name' набираем 'MDSyncML.dll'.
  4. Ставим 'WorldClient.dll' первым в списке: выделяем его и нажимаем 'Move Up' в правой панели 'Actions'.

Переходим в раздел 'Handler Mappings':


  1. Редактируем 'Feature Permissions': в правой панели 'Actions' нажимаем на 'Edit Feature Permissions...' и ставим все крыжики - 'Read', 'Script' и 'Execute'.
  2. Находим в списке 'ISAPI-dll' и заходим в него.

  3. В поле 'Request path' пишем 'WorldClient.dll'.
  4. В списке 'Module' выбираем 'IsapiModule'.
  5. В поле 'Executable (optional)' указываем путь к WorldClient.dll.
  6. Добавляем новый обработчик: в правой панели 'Actions' нажимаем 'Add Module Mapping...'

  7. В поле 'Request path' пишем 'MDSyncML.dll'.
  8. В списке 'Module' выбираем 'IsapiModule'.
  9. В поле 'Executable (optional)' указываем путь к MDSyncML.dll.
  10. В поле 'Name' пишем что-нибудь членораздельное. Например, 'SyncML-ISAPI'.

Редактируем 'MIME Types' - если этого не сделать, то робот LetsEncrypt не сможет получить от нас файл без расширения:


  1. Переходим в раздел 'MIME Types'.
  2. В правой панели 'Actions' нажимаем 'Add...'.
  3. В поле 'File name extension' пишем точку.
  4. В поле 'MIME type' пишем 'text/plain'.

Редактируем 'Application Pool', автоматически созданный при создании нашего сайта:


  1. Идём в 'Application Pools' -> 'MDaemon WorldClient' -> 'Advanced Settings...'.
  2. В секции 'Process Model' меняем 'Identity' на 'Network Service'.
  3. Если операционка — 64-разрядная, то в секции 'General' меняем 'Enable 32-Bit Applications' на 'True'.

Закрываем консоль. IIS настроен.

Далее, даём пользователям 'IUSR' и 'NETWORK SERVICE' полный доступ к папке MDaemon:

  1. Идём в проводник, открываем 'Properties' папки 'MDaemon', переходим на закладку 'Security', нажимаем 'Edit'.
  2. Нажимаем 'Add' -> 'Advanced' -> 'Find Now' — выделяем в списке 'Search Results' пользователя 'IUSR', нажимаем 'OK'.
  3. Ставим крыжик 'Full control' в списке 'Permissions for IUSR'.
  4. Нажимаем 'Add' -> 'Advanced' -> 'Find Now' — выделяем в списке 'Search Results' пользователя 'NETWORK SERVICE', нажимаем 'OK'.
  5. Ставим крыжик 'Full control' в списке 'Permissions for NETWORK SERVICE'.
  6. Закрываем оба окна нажатием на 'OK'.

WorldClient настроен. Проверяем, что WorldClient открывается нормально, зайдя на него браузером через интернет по полному доменному имени хоста.

Часть 3: установка и настройка скриптов LetsEncrypt


  1. Скачиваем архив со скриптами отсюда и распаковываем его в корень папки 'MDaemon'. Важное примечание: в скрипте основной сервер LetsEncrypt заменён на тестовый — чтобы предотвратить бан из-за многократных попыток получить сертификат во время процесса отладки. В следующей части будет написано — как переключиться на основной сервер.
  2. Дописываем в переменную окружения 'PSModulePath' путь к модулям, используемым скриптом:


    • Идём в 'Control Panel' -> 'System' -> 'Advanced system settings' -> 'Advanced' -> 'Environment Variables'.
    • Ищем в списке 'System Variables' переменную 'PSModulePath'.
    • Дописываем через ';' в её конец путь к папке 'Modules', находящейся внутри папки 'LetsEncrypt'. В моём случае такой: 'c:\MDaemon\LetsEncrypt\Modules\'
    • Перелогиниваемся.
  3. Запускаем консоль cmd.
  4. Запускаем скрипт letsencrypt.ps1 командой:

    powershell -ExecutionPolicy ByPass -File c:\mdaemon\letsencrypt\letsencrypt.ps1
    Здесь параметром 'File' задаётся путь к скрипту.

    Можно использовать дополнительные параметры:
    • -IISSiteName «MDaemon WorldClient»
      Если WorldClient работает через IIS, то этим параметром нужно указать скрипту имя сайта WorldClient (см. часть 2)
    • -WCIPAddress xxx.xxx.xxx.xxx
      Этим параметром задаётся IP-адрес, к которому скрипт должен прибиндить полученный сертификат. Его нет необходимости указывать, если к порту 443 не привязано никаких других сертификатов.
    • -To «admin@server.com»
      Этим параметром задаётся имейл, на который будет отправлен лог работы скрипта в случае возникновения какой-либо ошибки.

    Смотрим в окно консоли - скрипт должен выполниться без ошибок.

    Если что-нибудь пойдёт не так — вам придётся разобраться с этой проблемой самостоятельно.

    Если всё выполнилось успешно, то можно попробовать зайти в WorldClient браузером по протоколу https: так как мы использовали тестовый сервер LetsEncrypt, то браузер должен выругаться на сертификат сайта сообщением 'SEC_ERROR_UNKNOWN_ISSUER'.

    Кстати говоря, помните — я рассказывал про «грабли» с параметром 'EnableWCServer' в файле 'Mdaemon.ini' — что при использовании связки с IIS он установлен в 'No'? Так вот после успешной отработки скрипта этот параметр изменился на 'Yes'. Однако произошло это несколько поздновато, поэтому раскомментаривать проверку этого параметра в скрипте мы не стали.

Часть 4: перевод скрипта в «боевой режим»


  1. Открываем в текстовом редакторе скрипт letsencrypt.ps1 из папки LetsEncrypt.
  2. Находим в нём строки:

    
    #Initialize-ACMEVault -ErrorVariable LogText
    Initialize-ACMEVault -BaseURI https://acme-staging.api.letsencrypt.org/ -ErrorVariable LogText
    
  3. Первую строку раскомментариваем, а вторую закомментариваем:

    
    Initialize-ACMEVault -ErrorVariable LogText
    #Initialize-ACMEVault -BaseURI https://acme-staging.api.letsencrypt.org/ -ErrorVariable LogText
    
  4. Сохраняем скрипт.

Часть 5: Удаление всех следов «тестовой» жизнедеятельности


Если этого не сделать, то скрипт ещё пару месяцев будет продолжать выдавать нам «фальшивый» сертификат, несмотря на то, что мы внесли в скрипт нужные изменения.

  1. Удаляем тестовый сертификат из MDaemon:
    • Запускаем GUI MDaemon и идём в меню 'Безопасность' -> 'Параметры безопасности' -> 'SSL & TLS'.
    • В списке сертификатов выделяем наш тестовый сертификат (у него в поле 'Отправитель' будет 'Fake LE Intermediate X1') и нажимаем кнопку 'Удалить' под списком.
    • Если список сертификатов стал пуст — придётся создать самоподписанный сертификат, иначе MDaemon будет ругаться при попытке закрыть окно.
  2. Удаляем хранилище ключей, созданное скриптом: если работали под админским аккаунтом, то идём в 'c:\ProgramData\', а если под пользовательским — в 'C:\Users\имя_пользователя\AppData\Local\' и удаляем оттуда папку 'ACMESharp' вместе со всем содержимым.
  3. Удаляем XML-файл, созданный скриптом: идём в папку 'MDaemon\LetsEncrypt' и удаляем файл LetsEncrypt.XML оттуда.
  4. Удаляем тестовый сертификат: идём в папку 'MDaemon\Pem', находим там сертификат (файл с расширением 'pfx') и удаляем его.

Часть 6: Настройка запуска скрипта по расписанию


  1. Идём в 'Control Panel' -> 'Administrative Tools' -> 'Computer Management' -> 'System Tools' -> 'Task Scheduler' -> 'Task Scheduler Library'.
  2. Создаём новую задачу: нажимаем 'Create Task...' в правой панели 'Actions'.
  3. На закладке 'General':
    • В поле 'Name' пишем имя задачи — произвольно по вашему желанию.
    • В подразделе 'Security Options' выбираем пункт 'Run whether user is logged on or not'.
  4. На закладке 'Triggers':
    • Нажимаем кнопку 'New...' — откроется окно 'New Trigger'.
    • В списке 'Begin the task' выбираем 'On a schedule'.
    • Устанавливаем подходящую периодичность запуска: например, раз в неделю по воскресеньям. Скрипт при каждом старте будет проверять — сколько сертификату осталось жить: и если меньше месяца, то обновит его.
  5. На закладке 'Actions':
    • Нажимаем кнопку 'New' — откроется окно 'New Action'.
    • В списке 'Action' выбираем 'Start a program'.
    • В поле 'Program/script' пишем 'powershell'.
    • В поле 'Add arguments (optional)' пишем '-ExecutionPolicy ByPass -File c:\MDaemon\LetsEncrypt\letsencrypt.ps1'. В хвост строки дописываем требуемые дополнительные параметры (см. часть 3).
  6. На закладке 'Conditions' ставим крыжики по своему усмотрению.
  7. На закладке 'Settings' ставим крыжики:
    • Allow task to be run on demand
    • Stop the task if it runs longer than 1 hour
    • If the running task does not end when requested, force it to stop
  8. Нажимаем кнопку 'OK'. Вводим пароль текущего пользователя.

Часть 7: первый «боевой» запуск


Выполняем старт скрипта вручную:

  1. Выделяем только-что созданную задачу в списке.
  2. Нажимаем 'Run' в правой панели Actions'. Никакого окна при этом не откроется.
  3. Время от времени рефрешим список задач — чтобы видеть изменения в поле 'Status': 'Status' должен смениться на 'Run'. Рефрешим список, пока 'Status' снова не станет 'Ready'.
  4. Смотрим результат выполнения скрипта в лог-файле 'MDaemon\Logs\LetsEncrypt.log'.

Если, судя по лог-файлу, всё прошло успешно, значит дело сделано — сертификат получен и можно проверять работоспособность приёма/отправки почты по защищённому каналу. И да, не забудьте зайти в почтовик браузером по протоколу https — чтобы убедиться, что WorldClient тоже работает без проблем.

Часть последняя — заключительная


В заключение хочу сказать, что во время написания статьи у меня уже не было доступа к боевому серверу, поэтому все скриншоты делались с виртуальной машины, на которую была установлена ещё более старая версия MDaemon — 13.0.4 — из-за чего внешний вид окон может отличаться от других версий.

Ну вот и всё. Всё что знал — рассказал. Поздравляю всех с наступающим Новым Годом! Здоровья вам и удачи!
Tags:
Hubs:
+9
Comments2

Articles