Postfixadmin+postfix+dovecot+roundcube (sqlite) для soho (Попытаемся построить свой почтовый сервер с блекджеком и...)

Полезные советы и программы от пользователей нашего форума.

Модератор: Модераторы разделов

Аватара пользователя
kasak
Сообщения: 894
ОС: OpenBSD

Postfixadmin+postfix+dovecot+roundcube (sqlite) для soho

Сообщение kasak »

Друзья, я хотел бы рассказать о своей попытке найти более простую замену зимбре.
Сегодня уже придумана целая куча разных решений по почтовым серверам, все со своими достоинствами и недостатками.
Я снесу под спойлер мои лирические отступления по этому поводу, если читателю интересно будет прочесть плюсы и минусы, то пожалуйста читайте моё личное мнение. Если нет - ничего полезного под спойлером вы не найдёте.
Spoiler
Конечно чтобы начать перечислять плюсы и минусы готовых решений, надо сначала объяснить что же меня не устраивает в зимбре.
Зимбра хорошо "вошла" в прошлом, благодаря наличию бесплатной открытой сборки. Очень многие подсели на этот крючок, и теперь с него очень сложно слезть. Открытой версии давно уже нет. Точнее она есть в виде исходных кодов, которые раньше благородно собирал для нас zextras, а теперь и они отказались это делать. Да, если хорошо погуглить можно найти сборки "от Васяна" даже новой зимбры 10. Однако, я не знаю, можно ли считать это надёжным решением. Никто не может сказать, сколько ещё "Васян" будет этим заниматься.
Стоимость платной зимбры неадекватно велика. Кроме того zimbra 9 уже становится EOL, что создаёт ещё больше проблем.
Исходя из вышесказанного, давайте я перечислю какие на мой взгляд самые явные плюсы и минусы зимбры.
Ещё раз повторяюсь это моё СУГУБО ЛИЧНОЕ МНЕНИЕ.
Плюсы:
+Глобальная адресная книга с поиском
+Возможность из админки зайти в почтовый ящик любого пользователя
+Возможность легко создавать списки рассылок (без необходимости вручную вбивать адреса)
+Выдача квот без забот
На этом наверное все плюсы и заканчиваются.
А вот минусов куда больше:
-В последнее время все обновления это танцы с бубном. Даже то что подтягивалось из репозиториев ломало то mailboxd то slapd каждый раз надо что-то поправлять.
-Получить сертификат letsencrypt это танцы с бубном.
-Я подозреваю что зимбра достаточно дырявая. Взлом почтовых ящиков происходил достаточно часто. Чтобы как-то с этим бороться я оставил у зимбры открытыми только 578 и 443 порт. Количество взломанных ящиков уменьшилось в разы (2-3 ящика за 3 года) однако те случаи когда ящик всё же взломали меня очень удивили. Это точно не брутфорс, потому что fail2ban банит юзеров на месяц за некорректный ввод пароля дважды. И со взломанными коллегами была проведена беседа. Пароли были сложные, кроме того пользователь, которого взломали, даже никогда не вводил никуда этот пароль, он использовал только outlook. Из чего я делаю вывод что возможно есть какая-то дыра в самой зимбре о которой я не знаю.
-Из вышесказанного понятно что "нормальных" сборок зимбры в ближайшее время мы не увидим.
-Бекапить зимбру очень накладно
-Зимбра это как "верша" когда ты туда заползаешь, вылезти обратно очень сложно. Зимбра хранит всю почту в закрытом формате и просто так перенести её в другое решение очень сложно. imapsync - это боль.
-Зимбра крайне монолитный и не гибкий продукт. Например вы не можете поменять spamassassin на rspamd. Что-либо выключить или поменять в зимбре очень сложно и чревато последствиями.
-Вы не можете поменять "лицевую" страницу зимбры из-за лицензионных ограничений. (Нельзя заменить логотип на свой)

Рассматривая вариант переезда на что-то другое, я изучил другие решения и тоже составил список плюсов и минусом для себя:
iredmail:
+Гибкое решение
+Хорошо документирован
-Некоторые функции потихоньку "утекают" в платную версию. И по личным наблюдениям всего за год это явление очень усилилось.

mail-in-a-box
-работает только на убунту
-слишком плохо документирован

modoboa
-вообще нет представления что это такое. Предлагается установить и по ходу разобраться.

mailcow
+крутая админка
+красивая корова
-докер

Если посмотреть на всё это очень внимательно мы увидим что "глобальная адресная книга" может быть с очень большим трудом натянута разве что на iredmail, а таких удобных списков рассылки как в зимбре нет ни в одном решении.
Кроме того для меня нашёлся фатальный недостаток во всех этих решениях:
1) докер - сразу нет
2) mail-in-a-box и modoboa - оба представляют из себя чёрте что, и нигде толком не написано, что именно. Я не смог понять подходит ли мне такое решение или нет.
3) iredmail показался мне практически тем что нужно, однако я боюсь что через пару лет он сделает такой же финт ушами как зимбра и от бесплатной версии останется лишь обрубок ни на что не годный.
Не смотря на обилие уже готовых решений, я всё равно пошёл своим путём и решил изобрести велосипед. И своими наработками я хочу поделиться тут, на своём любимом unixforum.

Обратите внимание:
Данный способ рассчитан на малые рабочие группы (20-100 почтовых ящиков)
Чем мой мануал лучше остальных в интернете?
Я не просто выложу сюда какие-то конфиги, как делают большинство авторов. Я буду пояснять, что делает та или иная опция, как она работает.
Прочитав мой мануал вы сможете не просто запустить почту в формате "тяп-ляп и готово", вы будете понимать процессы, как всё работает изнутри.
На кого рассчитан этот мануал?
На админов, которые не считают себя экспертами. Потребуется знать и уметь самостоятельно настроить понравившийся http сервер.
Можно ли заменить этой связкой зимбру?
Полноценной замены не получится. Невозможно организовать глобальную адресную книгу без использования ldap. ldap это единственное решение как сделать глобальную адресную книгу. А postfixadmin не работает с ldap. Есть и другие мелкие нюансы
Что нам потребуется?
Я взял за основу Fedora server, но подойдёт и любой другой дистрибутив.
Обратите внимание что selinux придётся выключить или переключить в режим permissive. Дело в том что selinux служит для разделения привилегий. dovecot должен работать с одними файлами, httpd с другими, а мы как раз собираемся разделить это всё между ними всеми, и конечно selinux будет этому противиться.

Описание формата:
Кусочки конфигов которые надо поправить будут в поле code.
Команды которые надо вводить будут в поле shell.
Жирным отмечены имена файлов.
Большими буквами - заголовки.

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

Postfixadmin
Postfixadmin - это веб инструмент для администрирования базы данных, подходящий для интеграции с postfix.
Сам postfixadmin ничего не делает, кроме администрирования базы данных. Он не создаёт папки в файловой системе, ничего не передаёт и не принимает. Он только администрирует базу данных. А наша задача - создать конфигурацию вокруг этой базы данных.
Скачайте postfixadmin из проверенного источника и распакуйте в директорию нужного веб сервера.
Ссылка на postfixadmin: https://github.com/postfixadmin/postfixadmin/releases
У меня дистрибутив как я уже говорил fedora, поэтому я распаковал постфиксадмин в /var/www/postfixadmin
После чего просто добавил алиас для apache.

Код: Выделить всё

Alias /postfixadmin /var/www/postfixadmin/public
Постфиксадмин разумеется нужно скрыть от лишних глаз, но у каждого будет своя собственная конфигурация, зависящая от реальных возможностей и потребностей, поэтому задача "скрыть от лишних глаз" ложится на читателя и будет индивидуальной для каждого случая.
Далее нужно установить php. Тут тоже для каждого дистрибутива всё индивидуально, но список пакетов для федоры я всё же приведу:

Код: Выделить всё

php
php-cli
php-common
php-enchant
php-fpm
php-gd
php-intl
php-ldap
php-mbstring
php-opcache
php-pdo
php-pecl-zip
php-process
php-sodium
php-xml
Внутри директории /var/www/postfixadmin создайте директорию templates_c и задайте ей владельца apache (для ubuntu и bsd владелец будет другой)

Shell

mkdir /var/www/postfixadmin/templates_c
chown apache:apache /var/www/postfixadmin/templates_c
Это единственная директория в которую postfixadmin будет что-то писать.
Теперь нам нужно определиться с тем, где будет лежать база данных.
Место может быть любое. Можете выбрать /etc/postfixadmin или /var/postfixadmin или что угодно другое, лишь бы вам было удобно бекапить.
Я решил использовать для своего решения sqlite, хотя 99.9% других авторов описывают mysql или в крайнем случае pgsql.
Почему я так поступил?
Во-первых я уже указал что это решение на небольшое количество ящиков. Зачем нужно жрать память и держать включенным сервер mysql ради сотни строк в таблице? И тем более pgsql которую надо вручную обновлять при выходе мажорной версии? Это слишком накладно.
sqlite это простое решение, которое не нужно руками обновлять, легко бекапить и в нашем случае размер базы будет составлять килобайты, поэтому бекапить её можно будет хоть 100 раз в день, а для бекапа достаточно сохранить всего один файл.
Здесь и далее я размещу файл в директории /var/www/postfixadmin/database. У этой директории должны быть права на запись пользователю apache, остальным же достаточно прав на чтение:

Shell

mkdir /var/www/postfixadmin/database
touch /var/www/postfixadmin/database/postfixadmin.db
chown -R apache:apache /var/www/postfixadmin/database
Теперь можно создать конфиг для postfixadmin. Находится он в папке /var/www/postfixadmin и называется config.local.php. Выглядит он следующим образом:

Код: Выделить всё

<?php

$CONF['database_type'] = 'sqlite';
$CONF['database_name'] = '/var/www/postfixadmin/database/postfixadmin.db';
$CONF['configured'] = true;
$CONF['encrypt'] = 'dovecot:BLF-CRYPT';

?>
Первые две опции это разумеется указание нашей бд. Третья опция сообщает что мы готовы к началу работы. Четвертую добавил я.
По-умолчанию postfixadmin шифрует пароли в довольно простеньком md5, я решил сразу же усилить шифрование.
Конечно в системе должен быть установлен dovecot, но он нам всё равно сейчас понадобится. Желающие могут так же применить тут php crypt вместо довекота, например так: $CONF['encrypt'] = 'php_crypt:SHA512';

Теперь заходим на страницу http://нашсервер/postfixadmin/setup.php
Если мы всё сделали правильно, postfixadmin предложит сгенерировать мастер-пароль. Запомните этот пароль, он нужен если впоследствии можно было поменять пароль "суперадмина" (который занимается не установкой а непосредственно управлением ящиками и тд)
Постфиксадмин покажет вам строку которую надо будет добавить в config.local.php например такая:
$CONF['setup_password'] = '$2y$10$3ybxsh278eAlZKlLf8Zp9e4hmuDaW/TCYd5IZagV7coeAfzBW/GzC';
Разумеется копировать мою строку не надо, генерируйте свою.
Когда вы добавите строку в config.local.php, postfixadmin сгенерирует для нас базу данных. И мы сможем создать логин и пароль для суперадмина.
После чего переходить уже в сам postfixadmin где и создавать ящики.
Первая, самая простая часть закончена. Теперь я предлагаю переходить к конфигурации dovecot.

Dovecot
В нашем случае dovecot - это основа всего. Он будет отвечать за хранение почты и за авторизацию пользователей.
К сожалению я не уверен что в каждом дистрибутиве dovecot поставляется с одинаковым расположением и наполнением конфигов.
Я буду приводить те кусочки которые я менял относительно дефолтного конфига.
Для начала посмотрите на то как они вообще расположены:

Код: Выделить всё

├── conf.d
│   ├── 10-auth.conf
│   ├── 10-director.conf
│   ├── 10-logging.conf
│   ├── 10-mail.conf
│   ├── 10-master.conf
│   ├── 10-metrics.conf
│   ├── 10-ssl.conf
│   ├── 15-lda.conf
│   ├── 15-mailboxes.conf
│   ├── 20-imap.conf
│   ├── 20-lmtp.conf
│   ├── 20-pop3.conf
│   ├── 20-submission.conf
│   ├── 90-acl.conf
│   ├── 90-plugin.conf
│   ├── 90-quota.conf
│   ├── auth-checkpassword.conf.ext
│   ├── auth-deny.conf.ext
│   ├── auth-dict.conf.ext
│   ├── auth-ldap.conf.ext
│   ├── auth-master.conf.ext
│   ├── auth-passwdfile.conf.ext
│   ├── auth-sql.conf.ext
│   ├── auth-static.conf.ext
│   └── auth-system.conf.ext
├── dovecot.conf
└── dovecot-sql.conf.ext
Файл dovecot-sql.conf.ext нам нужно создать самостоятельно!
Содержимое:

Код: Выделить всё

driver = sqlite
connect = /var/www/postfixadmin/database/postfixadmin.db

password_query = SELECT username AS user, password FROM mailbox WHERE username = '%u' AND active='1'
user_query = SELECT '/var/mail/vmail/' || maildir AS home FROM mailbox WHERE username = '%u' AND active = '1'

# For using doveadm -A:
iterate_query = SELECT username as user FROM mailbox WHERE active = '1'
Первые две строчки надеюсь понятны. А вот чтобы лучше понять password_query и user_query нам следует сделать запрос на таблицу mailbox где эти данные и хранятся.
Вот такая структура у этой таблицы:

Код: Выделить всё

sqlite> .schema mailbox
CREATE TABLE mailbox (
          `username` varchar(255) NOT NULL,
          `password` varchar(255) NOT NULL,
          `name` varchar(255) NOT NULL,
          `maildir` varchar(255) NOT NULL,
          `quota` bigint(20) NOT NULL DEFAULT 0,
          `local_part` varchar(255) NOT NULL,
          `domain` varchar(255) NOT NULL,
          `created` datetime NOT NULL default '2000-01-01',
          `modified` datetime NOT NULL default '2000-01-01',
          `active` tinyint(1) NOT NULL DEFAULT '1', 
          `phone` varchar(30) NOT NULL DEFAULT '', 
          `email_other` varchar(255) NOT NULL DEFAULT '', 
          token varchar(255)  NOT NULL DEFAULT '', 
          token_validity datetime NOT NULL default '2000-01-01', 
          password_expiry datetime NOT NULL default '2000-01-01',
          PRIMARY KEY (`username`));
username хранит в себе емеил адрес в формате user@domain, name это реальное имя например "Иван Иванов".
maildir это указание на домашнюю директорию пользователя в формате domain/user. local_part это user без домена.
domain это домен.
active это флаг говорящий включен пользователь или нет.

Теперь, когда мы создали свой собственный файл конфигурации и запрос, нужно доделать всё остальное.
Для начала нужно включить авторизацию через sql. Для этого в файле 10-auth.conf в самом конце раскомментируем нужную строку:

Код: Выделить всё

#!include auth-deny.conf.ext
#!include auth-master.conf.ext

#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext
По-умолчанию раскоментирован auth-system, его надо закоментировать.
Есть ещё один нюанс. Если вы хотите разрешить пользователям почты авторизацию без realm, то есть без указания домена, в этом же файле найдите строку

Код: Выделить всё

auth_default_realm =
и добавьте к ней ваш домен.

У меня в файле auth-sql.conf.ext я ничего не менял. Но если вдруг у вас он окажется другой, я приведу его содержимое тут (я разумеется отрезал комментарии):

Код: Выделить всё

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
Следующий файл который надо поправить это 10-mail.conf
В нём поправьте расположение почтовых ящиков:

Код: Выделить всё

mail_location = maildir:/var/mail/vmail/%d/%n
Разумеется директорию с ящиками можете указать ту, которая вам больше нравится. А вот конец %d/n% рекомендуется оставить как есть.
В таком виде ящики будут создаваться в /var/mail/vmail/domain/user
Я так же рекомендую в этом же файле поправить строки

Код: Выделить всё

mail_uid = vmail
mail_gid = vmail
Это указывает пользователя который будет владельцем принятых писем.
Но это необязательно.

Следующий файл который нужно поправить это 15-mailboxes.conf. Я его правлю для лучшей интеграции с roundcube да и вообще с другими imap клиентами. Однако, мне следует указать что для достижения всех поставленных задач это не обязательная правка.
Нам нужно добавить строку auto = subscribe в каждую директорию:

Код: Выделить всё

namespace inbox {
  # These mailboxes are widely used and could perhaps be created automatically:
  mailbox Drafts {
    auto = subscribe
    special_use = \Drafts
  }
  mailbox Junk {
    auto = subscribe
    special_use = \Junk
  }
  mailbox Trash {
    auto = subscribe
    special_use = \Trash
  }

  # For \Sent mailboxes there are two widely used names. We'll mark both of
  # them as \Sent. User typically deletes one of them if duplicates are created.
  mailbox Sent {
    auto = subscribe
    special_use = \Sent
  }
Это нужно чтобы imap клиент автоматически создавал при первом входе папки "Черновик", "Корзина", "Спам" и "Отправленные" в ином случае будет доступна только папка "Входящие" и это меня огорчает.

Наконец самый важный и страшный файл который надо поправить это

Код: Выделить всё

10-master.conf
.
В нём нужно поправить две строки, lmtp и auth.
Найдите их и приведите к такому виду:
lmtp:

Код: Выделить всё

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0666
    user = postfix
    group = postfix
  }
auth:

Код: Выделить всё

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
Вероятнее всего такие строки у вас уже есть. И всё что нужно просто их раскомментировать. Возможно поправить mode.
Теперь же объясню зачем всё это надо.
LMTP это механизм передачи почты от postfix к dovecot.
Я знаю о трёх видах доставки почты:
  1. postfix может класть письма в нужные папки самостоятельно. Но так dovecot не будет обновлять свои индексы и это не рекомендуется.
  2. postfix может передавать письма внешней программе (dovecot-lda например) и эта программа будет раскладывать письма по папкам.
    Такой подход возможен если ящиков мало и письма приходят редко.
  3. postfix может передавать письма сервису, который работает постоянно через unix socket. Это рекомендуемый тип если письма могут приходить часто.
auth это unix socket, который будет принимать запросы на авторизацию от postfix, проверять через свою бд, которую мы уже настроили, и отвечать постфиксу можно ли отправлять письмо или нет.
С довекотом пока что всё. Как видите, тут всё просто и легко!
Не забудьте создать аккаунт для хранения почты, если вы указывали его в 10-mail.conf:

Shell

useradd -d /var/mail/vmail -c "Virtual mail user" -M -s /sbin/nologin vmail
Postfix
Постфикс можно править через редактирование файла /etc/postfix/main.cf но так делать не рекомендуется.
Рекомендуется все настройки проводить через postconf, как мы и будем делать.
Но для начала нам нужно создать "карты". Если будет угодно - мапинги.
Что такое "виртуальный" юзер с точки зрения постфикс? Это может изначально запутать начинающего админа, но на самом деле нет ничего проще.
Для постфикса любой пользователь или "реальный" или "виртуальный". Реальный это такой пользователь, который существует в системе и мы можем увидеть его в файле /etc/password. Виртуальный же пользователь это такой, которого в системе нет, и база таких пользователей существует в другом месте. Вот именно это место мы и будем постфиксу показывать. Нам нужно научить его делать запросы в нашей бд, чтобы он мог понять, принимать письмо или не принимать.
Для начала создайте папку /etc/postfix/sqlite а в ней создайте три файла:
virtual_sender_maps.cf
virtual_alias_maps.cf
virtual_domains_maps.cf


Содержимое файлов будет такое:
virtual_alias_maps.cf

Код: Выделить всё

# Path to database 
dbpath = /var/www/postfixadmin/database/postfixadmin.db

# Query
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
virtual_domains_maps.cf

Код: Выделить всё

# Path to database 
dbpath = /var/www/postfixadmin/database/postfixadmin.db

# Query
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
virtual_sender_maps.cf

Код: Выделить всё

# Path to database 
dbpath = /var/www/postfixadmin/database/postfixadmin.db

# Query
query = SELECT username FROM mailbox WHERE username='%s' AND active = true
Зачем конкретно нужны эти запросы мы обсудим чуть позже, а пока нужно подружить postfix и dovecot.
Помните мы создавали lmtp и auth socket в dovecot?
Нужно указать на них постфиксу.

auth:

Shell

postconf -e smtpd_sasl_auth_enable = yes
postconf -e smtpd_sasl_type = dovecot
postconf -e smtpd_sasl_path = private/auth
Обратите внимание что postconf это исполняемый файл! Он сам редактирует main.cf
Объяснение:
1 строка включает авторизацию в postfix (по умолчанию она выключена).
2 строка включает совместимость с довекотом.
3 строка указывает постфиксу где находится сокет для авторизации (на самом деле он в /var/spool/postfix/private/auth, но postfix ищет сокет относительно "рабочей директории")

Теперь подружим доставку lmtp:

Shell

postconf -e virtual_transport=lmtp:unix:private/dovecot-lmtp
postconf -e virtual_alias_maps=proxy:sqlite:/etc/postfix/sqlite/virtual_alias_maps.cf
postconf -e virtual_mailbox_domains=proxy:sqlite:/etc/postfix/sqlite/virtual_domains_maps.cf
postconf -e smtpd_sender_login_maps=proxy:sqlite:/etc/postfix/sqlite/virtual_sender_maps.cf
Объяснение:
1 строка указывает тип транспорта для входящих сообщений. Он указывается в формате type:nexthop.
type у нас lmtp, nexthop - unix:private/dovecot-lmtp это разумеется место где ждёт сокет от довекота.
2 строка задаёт таблицу для виртуальных алиасов
3 строка задаёт таблицу доменов для которых мы будем получать письма. На самом деле, если домен всего один, можно было бы просто его указать, без вот этих вот запросов.
4 строка опциональная. Она в будущем послужит для того чтобы сверять адрес отправителя с таблицей пользователей. Например если пользователь авторизовался как friend@domain а пытается отправить письмо от имени abuser@domain, у него не получится.
Если такая проверка не нужна, не активируйте эту функцию.

И наконец поправим master.cf, раскомментировав submission:

Код: Выделить всё

submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject_unauth_destination
  -o smtpd_sender_restrictions=reject_sender_login_mismatch
  -o smtpd_recipient_restrictions=reject_unknown_recipient_domain,permit_sasl_authenticated,reject
Этот кусочек включает порт 587 submission и задаёт некоторые ограничения для отправителя. (Включая в том числе проверку отправителя через smtpd_sender_login_maps) о чём я писал чуть выше.
Ещё раз напомню:
По сути это запрещает авторизованным пользователям отправлять письма от имени других пользователей, а так же запрещает неавторизованным пользователям отправлять письма от имени существующих.

И так же надо не забыть разрешить постфиксу "слушать" все интерфейсы:

Shell

postconf -e inet_interfaces=all
Ну и на этом конфигурация постфикса пока что завершена.
Ещё раз обращаю ваше внимание что это "частный случай" и тут приведены примеры лишь для универсального решения. Любые хотелки такие как "а мне надо чтобы было вот так" должны додумываться по месту.

Теперь следует заключительная часть моего опуса, но не заключительная для всей инструкции в целом.
Надо установить и настроить roundcube.

Roundcube
Круглокуб - по-моему самое подходящее завершение нашей небольшой системы. У него есть серьёзные преимущества относительно других решений. Например: roundcube поддерживает sieve, что позволит нашим пользователям создавать фильтры. Он поддерживает плагины, с помощью которых функционал можно значительно расширить. И наконец, у него есть встроенный плагин для изменения пароля.
Поскольку у меня fedora, а в федоре круглокуб есть в пакетах, я буду использовать его оттуда. Но если у вас другой дистрибутив, скачать круглокуб можно в официального сайта и распаковать в /var/www.
Если у вас федора или иной дистрибутив где roundcube из пакетов, его конфигурация скорее всего будет находится в /etc.
У меня это /etc/roundcube
найдите там config.inc.php.dist и скопируйте в config.inc.php. После чего приступайте к редактированию.
Прежде всего выберите тип базы данных где будет хранится пользовательская информация. Там будут хранится сессии, записи адресных книг и данные пользователей. У меня пользователи почты совсем не активные, потому я снова выбираю sqlite.

Код: Выделить всё

$config['db_dsnw'] = 'sqlite:////var/lib/roundcubemail/roundcube.db?mode=0640';
Далее поправьте адреса imap и smtp серверов.

Код: Выделить всё

$config['imap_host'] = 'tls://localhost:143';
$config['smtp_host'] = 'tls://localhost:587';
tls:// перед адресом обязателен в нашем случае, т.к. наша конфигурация без tls не будет работать.
Далее добавьте модуль password в список модулей:

Код: Выделить всё

$config['plugins'] = [
    'archive',
    'zipdownload',
    'emoticons',
    'password',
];
Далее добавьте две вот такие опции с указанием домена:

Код: Выделить всё

$config['username_domain'] = 'вашдомен';
$config['mail_domain'] = 'вашдомен';
Первая опция автоматически добавляет домен к имени пользователя, если тот залогинился без него. например user вместо user@domain.
Вторая опция автоматически присваивает домен к идентификатору нового пользователя.
Например, если пользователь сначала зайдёт под логином user, а потом под логином user@domain, roundcube будет считать что это два разных пользователя и у них будут разные адресные книги, настройки и т.д.
Указание этой опции приводит всё в порядок.
Конечно же, если вы собираетесь собирать почту для нескольких доменов, авторизацию без доменов следует полностью убрать.
И наконец, следует выключить проверку сертификата для tls:

Код: Выделить всё

$config['smtp_conn_options'] = [
     'ssl' => [
         'verify_peer'  => false,
         'verify_peer_name' => false,
         'allow_self_signed' => true,
     ],
];

$config['imap_conn_options'] = [
     'ssl' => [
         'verify_peer'  => false,
         'verify_peer_name' => false,
         'allow_self_signed' => true,
     ],
];
Если у вас есть заверенный сертификат, это конечно необязательно, а если этот сервер - бекэнд (как у меня) и сертификат там самоподписанный, залогиниться не получится без этих опций.

Теперь сконфигурируем модуль password.
Этого так же скопируйте password.inc.php.dist в password.inc.php и внесите в password.inc.php следующие правки:
Алгоритм шифрования пароля:

Код: Выделить всё

$config['password_algorithm'] = 'blowfish-crypt';
Разумеется если вы выбрали для postfixadmin другой алгоритм, тут тоже нужно выбрать такой же.

Код: Выделить всё

$config['password_algorithm_prefix'] = '{BLF-CRYPT}';
Аналогично, установите значение соответствующее выбранному для postfixadmin типу.
Далее укажите расположение базы данных postfixadmin:

Код: Выделить всё

$config['password_db_dsn'] = 'sqlite:////var/www/postfixadmin/database/postfixadmin.db';
И укажите запрос для смены пароля:

Код: Выделить всё

$config['password_query'] = 'UPDATE mailbox SET password=%P WHERE username=%u';
На этом конфигурацию roundcube можно завершить. Теперь создайте базу данных для roundcube. Если это sqlite как у меня,
это делается довольно просто:

Shell

touch /var/lib/roundcubemail/roundcube.db
cat /usr/share/roundcube/SQL/sqlite.initial.sql | sqlite3 /var/lib/roundcubemail/roundcube.db
Сервер http вам опять же предлагается настроить самостоятельно.
Кто-то любит nginx, кто-то apache, что-то lighttpd. Многое зависит от всякого, и если я буду приводить конфиги http под все возможные случаи, читать это и без того длинное сочинение станет совсем невозможно.

На этом настройку простейшей почты можно завершить. Я надеюсь все понимают что для работы почты нужна ещё целая куча тонкостей. Записи spf, dkim, mx в dns, запись PTR в обратном dns и так далее. Добавьте эти записи как того требует ваша конфигурация.

А теперь я вам расскажу как для нашего сервера сделать смартхост.

На случай если кто-то вдруг не знает что такое смартхост - это сервер который находится не за nat, а непосредственно в интернете с маршрутизируемым ip адресом, и служит для перенаправления запросов на бекэнд. Иногда его называют relayhost, иногда просто relay, иногда frontend.

Smarthost
Мы будем делать на связке opensmtpd + rspamd.
Почему так? Ну во-первых так интереснее. Про postfix я вам уже рассказал, а про opensmtpd нет.
А во-вторых так проще. Конфигурация opensmtpd в десятки раз проще чем postfix.

Для начала нужно opensmtpd установить, вместе с фильтром который называется opensmtpd-filter-rspamd.
У меня smarthost это OpenBSD и пакет называется именно так.

Я приведу конфиг целиком, а потом мы разберём подробно что он делает.

Код: Выделить всё

pki domain.ru cert "/etc/ssl/domain.ru.fullchain.pem"
pki domain.ru key "/etc/ssl/private/domain.ru.key"
pki gater cert "/etc/ssl/snakeoil.pem"
pki gater key "/etc/ssl/private/snakeoil.key"

filter "rspamd" proc-exec "filter-rspamd"

table mailer { 192.168.0.25 }
table aliases file:/etc/mail/aliases

listen on socket
listen on lo0
listen on egress tls pki domain.ru hostname domain.ru filter rspamd ciphers compat
listen on 192.168.0.1 tls pki gater filter rspamd

action "local_mail" mbox alias <aliases>
action "outbound" relay helo domain.ru
action "tomailer" relay host 192.168.0.25 tls no-verify

match from local for local action "local_mail"

match from any for domain "domain.ru" action "tomailer"
match from src <mailer> for any action "outbound"
match from local for any action "outbound"
Ну и теперь по порядочку что тут зачем:
pki настраивает сертификаты в формате pki <name> <type> <path>
где name - произвольное имя, type может быть cert или key и path - путь к сертификату.
У меня задано два сертификата для внешнего доступа и внутреннего.

filter указывает путь к фильтру в формате filter <name> <type> <path>
где name - произвольное имя, type в нашем случае исполняемый процесс и filter-rspamd это исполняемый файл который мы установили из opensmtpd-filter-rspamd.

table - таблицы в формате <name> <path>, но вместо path может быть сразу задан массив элементов.

listen on socket - включает unix сокет для приёма почты. listen on lo0 - оба этих пункта нужны для отправки почты между локальными пользователями.

listen on egress - включает прослушивание на "внешнем" интерфейсе. tls - включает starttls, pki domain.ru указывает сертификат для tls, hostname domain.ru указывает каким именем сервер будет представляться подключающимся. filter rspamd включает фильтрацию на этом подключении и наконец ciphers compat тут для совместимости со всякими косячными клиентами которые не знают что такое tls1.2

listen on 192.168.0.1 у нас для того чтобы принимать почту от "бэкенда"

Далее идёт список действий. эти действия в последствии назначаются для совпадений (match)

action "local_mail" mbox alias <aliases> эта строка нужна чтобы передавать почту между локальными пользователями (из /etc/passwords) например от cron к root.

action "outbound" relay helo domain.ru - это действие отправляет почту куда следует, представляясь именем domain.ru

action "tomailer" relay host 192.168.0.25 tls no-verify - это действие отправляет почту на ip адрес 192.168.0.25 без верификации валидности сертификата.

Далее у нас идут "совпадения". Они отсортированы так чтобы "первое совпадение срабатывало". В конце указывается "действие" которое надо выполнить с сообщением.

match from local for local action "local_mail" - отправка от локального пользователя к локальному.

match from any for domain "domain.ru" action "tomailer" - принимает письмо из любого места для домена domain.ru и передаёт действию tomailer
а действие tomailer в свою очередь - хосту 192.16.0.25.

match from src <mailer> for any action "outbound" - если письмо получено от хоста из таблицы mailer, передать действию outbound (а оно отправит его в мир)

match from local for any action "outbound" - эта строка нужна например для того чтобы пользователь root мог отправить письмо админу (например когда срабатывает датчик или cron).

И теперь нам нужно к этому всему приделать rspamd. Этот инструмент очень хорош тем, что может и заниматься подписями dkim, и проверять спам, и грейлистить, и антивирус, и вообще крайне конфигурируемая штука.
Обратите внимание что ВСЯ конфигурация делается в папке /etc/rspamd/local.d и больше нигде.
Поэтому переходим по пути /etc/rspamd/local.d и всё делаем только там.
Указываем путь к redis
redis.conf

Код: Выделить всё

servers = "/var/run/redis/redis.sock";
dkim_signing.conf

Код: Выделить всё

try_fallback = false;
allow_hdrfrom_mismatch = true;
allow_username_mismatch = true;

domain {
  # Domain name is used as key
  domain.ru {
    # Private key path
    path = "${DBDIR}/dkim/domain.ru.dkim.key";
    # Selector
    selector = "dkim";
  }
}
Для генерации ключей воспользуйтесь утилитой rspamadm dkim_keygen.
А так же возпользуйтесь утилитой rspamadm pw чтобы сгенерировать пароль и добавить его в worker-controller.inc
в таком виде:
worker-controller.inc

Код: Выделить всё

password = "$2$b7hmkfg5tqssugtf5f5m5ptaswharw7z$uh4xxhg41utgyn6qbdfhmb65x5ayeksojcj1dea6pfncugmybrdb";
Минимально этого достаточно для того чтобы фильтровать спам и подписывать сообщения.
А для того чтобы postfix начал отправлять письма через наш smarthost нужно указать ему:

Shell

postconf -e relayhost=192.168.0.1
Послесловие

Друзья, мой опус и так получился слишком большой, а за кадром ещё осталась целая куча объемных вещей, например прикручивание sieve к нашему dovecot и roundcube, прикручивание rspamd fuzzy к нашему sieve, тонкая настройка rspamd на smarthost чтобы отвечать на самые хитрые спамерские уловки. А так же добавка dmarc, mta-sts, mx зон в DNS но я надеюсь начинающий админ сможет справится с такой простой задачей. Но к сожалению если я всё это начну описывать дальше в этом же тексте, он получится безумно огромный и непонятно как вообще его читать. Я бы сказал что полное обширное решение даже такой простой задачи достойно своей книги.
Я же представил вам принципы построения очень простого почтальона для малых организаций.
Конечно он не лишён своих минусов которые я сразу же тут и перечислю:
-К сожалению roundcube не умеет подхватывать реальные имена пользователей из базы данных. Поэтому получается что если пользователь сам не укажет имя, оно будет пустым. Это частично решается подключением плагина new_user_dialog который будет спрашивать сотрудника его имя при первом входе.
-К сожалению организовать глобальную адресную книгу с использованием sql невозможно. Глобальная адресная книга может быть доступна только при использовании ldap. А для ldap нет инструмента похожего на postfixadmin.
-Довольно сложно в такой конфигурации делать списки рассылки. В той же зимбре можно отобразить список учёток и перетащить в список рассылки. В нашем случае список придётся составлять руками.
-Полноценной заменой зимбры это конечно не может послужить
Но есть и много плюсов
+Вы узнали кое-что новое (может быть)
+Это решение крайне гибкое и его можно подстроить под всё что угодно
+Относительно зимбры это решение жрёт значительно меньше озу, горазно меньше места на диске
+Это всё куда легче забекапить относительно любого другого продукта. По сути надо бекапить 1 файл и 1 директорию.
+Вы можете всё что угодно кастомизировать и вставлять свои логотипы, никто не придерётся.
+Работает быстрее.
Linux kasakoff 6.10.11-200.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Sep 18 21:09:58 UTC 2024 x86_64 GNU/Linux
Спасибо сказали:
Аватара пользователя
SwapON
Сообщения: 210
ОС: Gentoo Xfce4

Re: Postfixadmin+postfix+dovecot+roundcube (sqlite) для soho

Сообщение SwapON »

КросссафффчЕГ...! За труды - респект! На моей практике в проде таких серверов 3 - 4 с количеством ящиков 50 - 70, но ни на одном сервере я почему-то не додумался заюзать sqlite. Везде марию использовал.
Спасибо сказали: