Я люблю линукс, юникс и системное администрирование по странной причине. Это не оплата труда и не возможность управления сложными комплексами через консоль, а интересные, неформатные задачи, которые порой попадаются на пути самураев опенсорса. Об одной такой задаче я и расскажу.

Предпосылки


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

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

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

  • Почтовый сервер живёт на Slackware 10.1.0.
  • Отправка писем осуществляется по SMTP по 25 порту и только с внутренних IP.
  • MTA — Sendmail, все почтовые пользователи заносятся скриптом как системные и живут в /etc/passwd.
  • Есть веб-интерфейс. Очень брутальный SquirrelMail. Гиперссылки в теле писем он отображать не умеет и никак не сообщает об их наличии. Последняя версия вышла в 2013 году.
  • Первичная фильтрация спама осуществляется через блоклист, который пополняется вручную.
  • Вторичная фильтрация спама осуществляется через старинную версию Amavis, и получение писем с кодами подтверждения регистрации от, например, «Твиттера» занимает от трёх часов — всё это время их маринует спам-фильтр. Пока идёт код подтверждения, его действие уже заканчивается.

Приветливая Slackware приветствует очередной мудрой цитатой.

Общая задача — перевести почтовый сервер на современные рельсы.

Основные подзадачи:

  • Актуализировать список активных почтовых аккаунтов на старом сервере.
  • Развернуть новый сервер. Как и какой — выбор за мной.
  • Перенести аккаунты на новый сервер, желательно без смены паролей, вместе с алиасами, списками рассылки и адресными книгами из SquirrelMail.
  • Пережить обязательную бурю недовольства, отвечая на гневные письма вежливо и спокойно. Решать проблемы, которые обязательно последуют.


Подготовка


Актуализация аккаунтов началась с изучения Sendmail, с которым сталкивался до этого лет пятнадцать назад.

В /etc/mail/aliases находятся алиасы, а также списки рассылки, в том числе и самый для меня на тот момент полезный — рассылка всем пользователям.

В /etc/mail/access находятся правила обработки писем и забитая вручную первичная фильтрация. Они мне понадобятся чуть позже.

Из списка рассылки получился адрес всех пользователей электронной почты, коих оказалось около пятисот. Сохранил его в файл allusers, отсортировал через sort.

Главам подразделений был выслан приказ предоставить список пользователей электронной почты. Из разрозненных экселевских табличек собрался единый список активных логинов по версии подразделений. Сохранил его в файл active, отсортировал через sort.

Получаю аццеслист — список активных юзеров:

#comm -12 allusers active > accesslist

Часть указанных подразделениями аккаунтов была написана с ошибкой, часть — находилась на сторонних почтовых серверах; нескольких вообще не существовало. Это норма.

Получаю чёрный список из тех, кто не вошел в acceslist:

#comm -23 allusers accesslist > blocklist

Блоклист прогоняю через простенький скрипт, генерирующий часть конфигурации sendmail:

#nano lockgen

#!/bin/bash

sed «s/^/To:/;s/$/@domain.ru        	REJECT/» blacklist > tmp1

sed «s/^/From:/;s/$/@domain.ru      	550 Your mailbox is locked, contact your system administrator mail.support@domain.ru/» blocklist > tmp2

paste -d»\n» tmp1 tmp2

rm -f tmp1 tmp2

#chmod +x lockgen

#./lockgen > lockconf

Сгенерированный конфиг переношу в /etc/mail/access на старом сервере и перезапускаю sendmail.

Теперь юзернеймам из чёрного списка, при попытке проверить или отправить почту, выдаётся сообщение с призывом связаться со мной. Таких набралось довольно много. И, забегая вперёд, такие пользователи появлялись и спустя полгода, уже после переезда на новый сервер.

Аццеслист же был залит и на старый сервер, и на тот, о котором пойдёт речь дальше.

Новой платформой я выбрал iRedMail и развернул его на виртуалке с CentOS 8 в Proxmox VE. Процесс в деталях описывать смысла нет, у iRedMail подробная документация и активное комьюнити, что и послужило основной причиной выбора. CentOS — чисто личное решение, так как больше всего работал именно с ним. Перенести всё на другую систему не будет проблемой.

Платная поддержка iRedMail не приобреталась, поскольку пока не сталкивался с необходимостью, хотя допускаю, что в будущем пригодится.

Процесс переезда начался с переноса аккаунтов вместе с паролями. Со старого сервера взял файл /etc/shadow и обработал его парой кривеньких скриптов.

Чищу shadow, оставляю только строки с аккаунтами аццеслиста:

#grep -f acceslist shadow > accshadow

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

Оставляю только связку логин/хэш:

cat accshadow | cut -f1,2 -d':' > userhash

Скорее всего, стоило пойти по более простому пути и сформировать запрос на создание аккаунтов сразу из полученного файла с хэшем. Но пошёл чуть в обход.

В скрипте инструмента iRedMail для создания SQL аккаунтов меняю квоту ящика по умолчанию (параметр DEFAULT_QUOTA) и создаю импорт-файл для создания аккаунтов из аццеслиста с одним и тем же паролем:

#!/bin/bash

echo «#!/bin/bash»

sed «s/^/bash \/path\/to\/iRedMail-1.3.1\/tools\/create_mail_user_SQL.sh /;s/$/@domain.ru '12345678' >> addusers.sql/» accesslist

Обрабатываю полученный импорт-файл, заменяя SSHA512 хэши на MD5:

#nano changehash

#!/bin/bash

awk 'BEGIN{number=1;}

{

cmd=«sed \x27«number»!D;s/^.*://\x27 userhash»;

cmd|getline hash;

sub(/{SSHA512}.*\x27, \x27/,»{CRYPT}«hash»\x27, \x27»);

print;

if (/CRYPT/) number=number+1;

}' addusers_temp.sql;

#chmod +x changehash

#./changehash > addusers.sql

В БД iRedMail для хранения паролей по умолчанию используются хэши SSHA512, но можно использовать и менее надёжные хэши MD5, вытащенные из shadow. Они могут мирно сосуществовать, так что при смене пароля или введении нового пользователя MD5 хэши будут потихоньку исчезать из базы.

Делаю список внутренней рассылки по всем пользователям и добавляю модератора:

MariaDB [vmail]> INSERT INTO alias (address, domain, active) VALUES ('all-users@domain.ru', 'domain.ru', 1);

MariaDB [vmail]> INSERT INTO moderators (address, moderator, domain, dest_domain) VALUES ('all-users@domain.ru', 'moderatormail@domain.ru', 'domain.ru', 'domain.ru');

Формирую ещё один импорт-файл:

#nano createlist

#!/bin/bash

while IFS= read -r username

do

  echo «INSERT INTO forwardings (address, forwarding, domain, dest_domain, is_list, active)»

  echo «VALUES ('all-users@domain.ru', '$username@domain.ru', 'domain.ru', 'domain.ru', 1, 1);»

done < accesslist

#chmod +x createlist

#./changehash > addlist.sql

Этот скрипт использовался потом ещё несколько раз для создания целевых списков рассылки, например, главам отделов.

Импортирую оба файла в БД:

MariaDB [vmail]> SOURCE addusers.sql;

MariaDB [vmail]> SOURCE addlist.sql;

Можно попробовать залогиниться с известным паролем в веб-интерфейс.

Roundcube по умолчанию требует указывать в качестве логина почтовый адрес полностью.

Миграция


На этом этапе записи DNS были переключены на использование нового почтового сервера. Сделано это было в пятницу вечером, с предупреждением пользователей за неделю через общую рассылку. Как только волна обновлений дошла до заокеанских DNS, был подключён сертификат Let's Encrypt по мануалу iRedMail.

Также на этом этапе обязательно следовало ограничить количество отсылаемых писем в день. Я это сделал гораздо позже, когда последовала волна взломов аккаунтов из-за недостаточно надёжных паролей (пользователи привыкли, что почта работает на отправку только внутри сети, и широко использовали цифровые пароли и вариации qwerty) и постовик загремел в блоклисты спамеров. Поток исходящего спама также вводил в ступор dovecot, который начинал сыпать очень странными ошибками, посылавшими меня по ложному пути поиска их причины.

Сотни в день будет достаточно:

MariaDB [iredapd]> INSERT INTO throttle (account, kind, priority, period, msg_size, max_msgs, max_quota) VALUES ('@domain.ru','outbound',60,86400,-1,100,-1);

Отдельным аккаунтам можно поднять лимиты:

MariaDB [iredapd]> INSERT INTO throttle (account, kind, priority, period, msg_size, max_msgs, max_quota) VALUES ('mass@domain.ru','outbound',100,86400,-1,500,-1);

На старом сервере всем юзернеймам из аццеслиста выставляется один и тот же пароль:

sed «s/$/:some123/» accesslist > pwdpatch

chpasswd < pwdbatch

На новом сервере создаётся управляющий аккаунт, который может управлять любым ящиком без необходимости знать его пароль:

Формируем хэш (далее подразумевается пароль some456):

#doveadm pw -s SSHA512

Помещаем полученный хэш в /etc/dovecot/dovecot-master-users:

postmigrate@domain.ru:{SSHA512}B0VHomJaMk6aLXOPglgNgJtCU...

Разворачивается imapsync по общедоступному мануалу. Формируется скрипт массового переноса почты:

#nano createmigrate

#!/bin/bash

echo «#!/bin/bash»

while IFS= read -r username

do

  echo «/root/imapsync --nosyncacls --subscribe --syncinternaldates --nosslcheck \\»

  echo «--host1 123.123.123.123  --authmech1 LOGIN --user1 $username --password1 some123 --nossl1 --notls1 \\»

  echo «--host2 127.0.0.1	--authmech2 LOGIN --user2 $username@domain.ru*postmigrate@domain.ru --password2 some456 --prefix1 INBOX.  --regextrans2 \«s/&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-/Sent/\» --addheader --folder \«Sent\» --folder \»&BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1-\«»

done < accesslist

#chmod +x createmigrate

Запуск:

# ./createmigrate > domigrate

# chmod +x domigrate

# nohup ./domgrate > process.out &

На этом этапе возникло множество проблем, и скрипт несколько раз дорабатывался и запускался снова с учётом возникающих ошибок. Оказалось, что размер ящиков на старом сервере регламентирован не был, многие ящики были куда большего размера, чем изначальные 2Gb. Пришлось избирательно увеличивать квоты. С названиями почтовых директорий было ещё хуже — старый сервер стоял на костях ещё более древних реализаций почтового сервера, у части клиентов директории были на русском.

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

Осталось перенести адресные книги в новый веб-интерфейс — Roundcube. SquirrelMail, как оказалось, лежал на другом сервере отдельно от MTA. После получения пароля от него выгрузил адресные книги в формате *.abook на новый сервер. Тут, по счастью, нашлось готовое решение — вот это.

В скрипте указываются параметры БД Roundcube (лежат в его конфиге). Всё достаточно просто, почтовые книги появились в веб-интерфейсе.

Последствия


По счастью, вся вертикаль власти от меня до директора весьма прогрессивная. Поток концентрированного недовольства от консерваторов был ожидаем, и от меня требовались только корректность и терпение. Критически недовольными изменениями были всего несколько пользователей, что составило менее 2% от их общего числа. Однозначный успех мероприятия.

Из-за слишком нового SSL отвалились старые версии TheBat (да, его ещё используют и даже пришлось покупать ключи от актуальной версии для совсем непримиримых пользователей).

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

Для нормальной работы оповещалок UPS-ов и части самописных сервисов института разрешил отправку сообщений с внутренних IP без авторизации с несуществующих аккаунтов:

#echo "MYNETWORKS = ['123.123.123.0/23']" >> /opt/iredapd/settings.py
#service iredapd restart

Что-то ещё тюнилось по мелочи типа более суровой настройки fail2ban или настройки DNS, но решения быстро находились в гугле и форуме iRedMail. Не отложилось в памяти.

На будущее


Что хотел бы реализовать, но пока не дошли руки:

  • Служебный Telegram-бот, в том числе с сигнализацией о выходе аккаунта за лимит отправки писем в день (что в 99% случаев означает взлом аккаунта из-за слабого пароля). При сильном выходе за лимит — автоблокировка сменой пароля. Пока приходится мониторить maillog через grep.
  • Интеграция с Nextcloud (был параллельно развёрнут на соседней виртуалке)
  • Интеграция с OTRS.

На этом всё. Сервер работает с начала этого года. К концу года переедет с CentOs на что-то ещё по известным причинам. Но это будет уже совсем не так романтично, как переносить старый почтовик на Slackware.


— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS
— 20% на выделенные серверы AMD Ryzen и Intel CoreHABRFIRSTDEDIC.
Доступно до 31 декабря 2021 г.

Комментарии (18)


  1. ophil
    20.10.2021 10:50
    +3

    привет коллега - плюсанул, навеяло - telnet ххххххх.com 25, ещё жив мой древний сервер, лет 20 уж ему


    1. Stalker_RED
      22.10.2021 15:57

      Да, раньше можно было почту на меилру через телнет читать.
      А сейчас вот вин10 пишет "telnet не является внутренней или внешней командой, исполняемой программой или пакетным файлом."
      Надо где-то галочку ставить чтобы он установился.


      1. DMGarikk
        22.10.2021 16:07
        +1

        а телнет из стандартной поставки еще во временя Win7… если даже не в висте, выпилили


  1. F0iL
    20.10.2021 11:04
    +1

    На тему открытия сервера "наружу" - а не лучше ли было поднять VPN-сервер для доступа к нему? С одной стороны, пользователям чуть менее удобно, с другой строны, более надежно/безопасно (можно, например, авторизовываться по сертификатам или с TOTP), плюс в будущем можно использовать VPN для каких-нибудь других сервисов, например, тот же NextCloud.


    1. 1shaman Автор
      20.10.2021 15:10
      +1

      Людям хочется с мобильников, домашних компов и т.д. Пока полет нормальный, после серии взломов qwerty паролей, уже довольно давно, все тихо.
      А wireguard давно поднят, конечно.


      1. F0iL
        20.10.2021 16:28

        Людям хочется с мобильников, домашних компов и т.д.

        Ну это вообще не проблема. Например IPsec/L2TP есть из коробки под все популярные ОС и мобильные устройства, а если использовать какой-нибудь комбайн типа SoftEther, то там вообще можно оторваться по-полной :)


        1. 1shaman Автор
          21.10.2021 13:12
          +2

          Зависит от количества юзеров и их квалификации. НИИ крупный, средний возраст пользователей запенсионный. Необходимость привыкать к новому веб-интерфейсу и так проблема, а IPsec/L2TP — катастрофа.


  1. DMGarikk
    20.10.2021 11:13

    Из-за слишком нового SSL отвалились старые версии TheBat (да, его ещё используют и даже пришлось покупать ключи от актуальной версии для совсем непримиримых пользователей).

    учитывая что у вас сервер не обновлялся 15 лет, то и политика внутренней безопасности соответствующая… и тогда вопрос — а зачем вообще ssl на почту внутри сети?


    1. 1shaman Автор
      20.10.2021 15:13

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


      1. DMGarikk
        20.10.2021 15:18

        всмысле большая дыра? для кого? у вас реальный вектор атаки внутри сети существует? ваши маршрутизаторы допустят arp-spoofing? боитесь что Клавдия Ильинична из бухгалтерии будет читать почту генерального директора организовов mitm? (а какже изоляция сегментов?)
        сертификат на ssl внутри сети вы сами выпускаете? поддерживаете его перевыпуск? храните ключи в сейфе?
        ==
        я вот просто сталкивался с серьёзной настройкой ИБ, когда шифрование во все щели и политики безопасности такие что пукнуть нельзя, сразу алерт ИБшником и всё лочится

        но вот без этого всего, просто ставить шифрование на внутренних коммуникациях, это как бронированную дверь в забор из гнилых досок на огороде
        ===
        аа, я понял похоже, вы из интернета снаружи на свой сервер ходите через bat?
        но это еще больше не сходтся с обновлением сервера раз в 15 лет


        1. 1shaman Автор
          20.10.2021 15:32
          +1

          Так кто сказал, что его ещё 15 лет не будут обновлять? Статья исключительно про переезд на более новую платформу. Которую проще поддерживать в актуальном состоянии.
          Про организацию внутренней сети рассказывать долго и незачем, но при текущем уровне её развития — ssl изнутри не лишний.


  1. amarao
    20.10.2021 11:42
    +3

    8ая центось - ошибка. Либо Rocky, либо Alma.


    1. Bonio
      20.10.2021 12:06

      На замену CentOS появилась целая пачка форков, бинарно совместимых. Поди разберись теперь, что выбирать из этой кучи… Да такое название классное потеряли.


    1. PocketM
      20.10.2021 23:02

      Либо Oracle Linux


      1. Bonio
        09.11.2021 14:27

        А чем оно лучше Rocky и Alma?


  1. osscombat
    20.10.2021 12:11
    +2

    я думал в НИИ сейчас в тренде импортозамещение


  1. ta4ukoma
    24.10.2021 18:05
    +1

    Упоминание OTRS лично у меня вызвало ощущение что вы только что снова окунулись в некромантию, не успев вылезти из нее с сервером почтовым.


  1. NikiN
    29.10.2021 10:57

    Железо видать хорошее, 15 лет отпахать.