Home » Linux » Debian » Настройка postfix + dovecot + postfixadmin + roundcube + dkim на Debian

Настройка postfix + dovecot + postfixadmin + roundcube + dkim на Debian

Несмотря на то, что облачные сервисы вытесняют локальные, некоторые вещи остаются актуальны по сей день. Я расскажу про установку и настройку почтового сервера на базе postfix, dovecot, postfixadmin, roundcube на ОС Debian. Последнее время инфраструктура информационных систем стремительно изменяется, но классические почтовые сервера по прежнему актуальны и востребованы.

Углубленный онлайн-курс по MikroTik

Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном онлайн-курcе по администрированию MikroTik. Автор курcа – сертифицированный тренер MikroTik Дмитрий Скоромнов. Более 40 лабораторных работ по которым дается обратная связь. В три раза больше информации, чем в MTCNA.

Цели статьи

  1. Рассказать о настройке DNS записей для почтового сервера.
  2. Установить и настроить базовый функционал почтового сервера на базе Debian с помощью Postfix и Dovecot.
  3. Настроить панель управления почтовым сервером Postfixadmin.
  4. Настроить Web интерфейс Roundcube, а так же его плагины acl, managesieve.
  5. Рассказать о способах борьбы со спамом средствами Postfix.

Данная статья является частью единого цикла статьей про сервер Debian.

Введение

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

В связи с этим какая-то часть пользователей подобных сервисов захочет переехать на свой почтовый сервер. Думаю, статья по его настройке будет актуальна и своевременна. А у меня, ко всему прочему, есть хороший опыт по установке, настройке и эксплуатации почтовых серверов.

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

Как я уже сказал, настраивать почтовый сервер буду на ОС Linux, а точнее на Debian. За основу будет взят Postfix, который присутствует в этой системе из коробки. Инструкция получится универсальной, можно использовать и для других дистрибутивов. Все основные конфиги легко переносятся на разные системы, требуя минимальной правки, в основном путей. Думаю, что вообще без какой-то дополнительной правки эта же статья будет полностью актуальна для Ubuntu.

Я напишу статью на самом что ни на есть реальном примере, без какой-либо правки доменов, ip и прочего, чтобы не ошибиться и показать максимально возможный реальный пример. У меня есть домен rocky-linux.ru. Я буду использовать его в своей работе. Почтовый сервер будет иметь имя mail.rocky-linux.ru.

Настройка DNS для почтового сервера

Начнем потихоньку подготовку к настройке нашего почтового сервера. Первым делом нужно подготовить DNS записи. Это очень важно. Без правильной наcтройки DNS нормально работать сервер не будет. Вернее, работать то он будет, но ваша почта может улетать в спам у принимающей стороны. Неправильная настройка DNS всегда прибавляет очень много баллов для любого антиспам фильтра.

Для написания этой статьи, я сделал поддомен mail.rocky-linux.ru. Для работы почты нет никакой разницы, используется домен первого, второго или третьего уровня. Почтовые ящики у меня будут вида user1@rocky-linux.ru. Внешний ip адрес, на котором будет работать сервер - 62.113.115.231.

Для подготовки к настройке почтового сервера вам нужно добавить следующие DNS записи в панели управления DNS вашего домена:

Имя Тип Значение
mail.rocky-linux.ru A 62.113.115.231
@ MX mail.rocky-linux.ru.

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

Настройка DNS для почтового сервера

Но это не всё. К сожалению, указанных DNS записей недостаточно. Для вашего внешнего IP адреса должна быть прописана обратная зона - PTR. В обратной зоне IP адресу ставится в соответствие доменное имя. То есть вашему IP адресу должно соответствовать доменное имя mail.rocky-linux.ru. Это идеальная ситуация, когда обратная зона соответствует имени почтового сервера. Не всегда это возможно. Важно, чтобы PTR зона была прописана и соответствовала реально существующему статическому доменному имени.

Настройками обратной зоны во многих случаях вы не можете управлять. Иногда это возможно через панель управления провайдера, если это какой-то хостер с VPS или выделенным сервером. В остальных случаях нужно обратиться к вашему провайдеру, который выделил вам внешний IP и сказать ему, что вы хотите настроить почтовый сервер и вам необходимо прописать обратную зону с именем mail.rocky-linux.ru на внешний IP адрес. Это обычная просьба, и тех поддержка без проблем сделает то, что вы просите, если они предоставляют такую услугу. Чаще всего провайдеры, работающие с юридическими лицами, такую услугу предоставляют. Домовые провайдеры для физиков - нет.

Проверить обратную зону для домена можно в консоли сервера с помощью команды host. Вот пример для моего внешнего IP. Я не стал прописывать домен mail.rocky-linux.ru, так как этот IP адрес используется в том числе для других целей. Привожу просто для примера:

# host 62.113.115.231
231.115.113.62.in-addr.arpa domain name pointer serveradmin.ru.

Выделенное является PTR записью. В идеале тут должен быть прописан не просто какой-то домен, а полное DNS имя вашего почтового сервера. Для примера приведу полностью корректно настроенные DNS записи.

Проверка DNS

Тут полное соответствие всех записей. MX запись соответствует A записи, а IP адрес A записи резолвится в доменное имя, указанное в MX. Вам в идеале нужно сделать также. Иногда люди путают, называют, к примеру, сервер mail.site.ru, а обратную зону делают просто site.ru или srv.site.ru. Вроде всё правильно, домен один и тот же, но соответствие не полное. Чтобы всё было корректно, должно быть полное соответствие всех записей - A, MX, PTR. Очень много спам фильтров используют эти записи для проверки домена отправителя на полное соответствие. Отклонение от идеала добавляет лишние баллы, но не означает, что почта не будет доставлена.

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

Подготовка сервера

После того, как закончите с DNS, можно приступать к настройке самого сервера. Рекомендую воспользоваться услугами провайдера Selectel. У него помимо очень дешёвых выделенных серверов, есть в том числе и бесплатная услуга по хостингу DNS. Я обычно там заказываю дешёвый выделенный сервер, устанавливаю туда Proxmox, создаю виртуалки. И одну из них использую под почтовый сервер.

Если у вас еще не настроен сервер с Debian, рекомендую мои материалы на эту тему:

Отдельно потратьте время на настройку iptables. Я не буду касаться этого вопроса в данной статье, чтобы не раздувать ее второстепенными вещами. Удобнее, когда всё по отдельности рассказано и описано с должной глубиной. Сваливать все в одну кучу не хочется.

Установка postfixadmin

Начнем с установки и настройки панели управления почтовым сервером postfix — postfixadmin. Без него начинать что-то делать неудобно, так как управлять пользователями, ящиками, алиасами будет нечем. По своей сути postfixadmin — набор php скриптов для управления записями в MySQL базе данных, которую использует сервер postfix во время своей работы. Соответственно, для работы postfixadmin нам нужен web сервер.

Подробно на настройке веб сервера я останавливаться не буду. Быстро установим всё необходимое для дальнейшей работы, в том числе и веб интерфейса с tls сертификатами. Привожу только команды, с минимумом комментариев.

Установка nginx:

# apt update
# apt install nginx
# systemctl enable --now nginx

Установка php-fpm со всеми модулями, которые нам понадобятся во время настройки по данному руководству:

# apt install php php-fpm php-cli php7.4-mysql php-json php7.4-gmp php7.4-imap php-gd php-ldap php-odbc php7.4-common php7.4-opcache php-pear php-xml php-xmlrpc php-mbstring php-snmp php-soap php-zip php-curl php-imagick php-intl
# systemctl enable --now php7.4-fpm

Установка MariaDB:

# apt install mariadb-server mariadb-client
# systemctl enable mariadb
# mysql_secure_installation

Для простоты откажитесь от unix_socket authentication и задайте пароль root. Не хочется в этой статье останавливаться на настройке MariaDB.

Теперь, зайдя браузером на страницу с ip адресом сервера, вы должны увидеть приветственную страницу Nginx.

Установка NGINX

Если страница не открывается, то скорее всего у вас не настроен firewall. Займитесь его настройкой, ссылку я давал в начале. Если он вам не нужен, то удалите или отключите его.

Предлагаю сразу поставить phpmyadmin, с ним удобно работать с базой. В нашем случае все пользователи будут храниться в mysql, иногда может понадобиться туда заглянуть.

# apt install phpmyadmin

По умолчанию у phpmyadmin нет готовой настройки под nginx, поэтому настроим вручную. Сделаем символьную ссылку:

# ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin

Приведёт дефолтный конфиг nginx /etc/nginx/sites-available/default к следующему виду:

server {
	listen 80 default_server;

	root /var/www/html;
	index index.html index.htm index.nginx-debian.html index.php;
	server_name _;

	location / {
		try_files $uri $uri/ =404;
	}

	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/run/php/php7.4-fpm.sock;
	}
}

Проверяем и перезапускаем nginx:

# nginx -t
# nginx -s reload

При переходе по адресу http://ip-сервера/phpmyadmin вы должны попадать в интерфейс панели управления. Можно зайти под учётной записью root. Если вы настроили веб сервер на внешнем интерфейсе, то оставлять phpmyadmin доступным для всех крайне нежелательно. Нужно ограничить доступ тем или иным способом. Можно по IP, либо паролем. Закроем паролем:

# apt install apache2-utils
# htpasswd -c /etc/nginx/.htpasswd pmauser01

Создали пользователя pmauser01. Теперь включим аутентификацию в nginx. Добавляем новые параметры.

server {
	listen 80 default_server;

	root /var/www/html;
	index index.html index.htm index.nginx-debian.html index.php;
	server_name _;

        auth_basic           "Administrator’s Area";
	auth_basic_user_file /etc/nginx/.htpasswd;

	location / {
		try_files $uri $uri/ =404;
	}

	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/run/php/php7.4-fpm.sock;
	}

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

Устанавливаем postfixadmin. Его, к сожалению, нет в базовых репозиториях Debian, поэтому скачаем и установим свежую версию вручную. Адрес для загрузки возьмём в репозитории на github.

# apt install acl
# wget https://github.com/postfixadmin/postfixadmin/archive/refs/tags/postfixadmin-3.3.13.tar.gz
# tar xzvf postfixadmin-3.3.13.tar.gz
# mv postfixadmin-postfixadmin-3.3.13 /var/www/html/postfixadmin
# chown -R www-data:www-data /var/www/html/postfixadmin

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

# cp /var/www/html/postfixadmin/config.inc.php /var/www/html/postfixadmin/config.local.php

Убедитесь, что файл config.local.php содержит следующие исправленные параметры.

<?php
$CONF['configured'] = true;
$CONF['default_language'] = 'ru';
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'password';
$CONF['database_name'] = 'postfix';
$CONF['admin_email'] = 'root@rocky-linux.ru';
$CONF['encrypt'] = 'md5crypt';
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'YES';
$CONF['transport_default'] = 'virtual';
$CONF['show_footer_text'] = 'YES';
$CONF['footer_text'] = 'Return to http://172.22.178.62/padmin/public/';
$CONF['footer_link'] = 'http://172.22.178.62/padmin/public/';
$CONF['default_aliases'] = array (
 'abuse' => 'root',
 'hostmaster' => 'root',
 'postmaster' => 'root',
 'webmaster' => 'root'
);

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

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

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

У меня распространены ситуации, когда я удаленно администрирую сервера, а на месте поддержка работает с пользователями. Чаще всего это не очень аккуратные и ответственные люди, иначе они бы работали с серверами :) Они часто забывают записать пароль, путают что-то и т.д. В итоге, когда один человек увольняется и приходит другой, оказывается, что найти пароли на некоторые ящики просто невозможно. Тут очень выручает возможность посмотреть пароль в базе. Я новому админу либо пароль говорю, либо весь дамп сразу отдаю, пусть работает.

Если вы сами работаете с сервером и всё аккуратно ведёте, записываете, например, в keepass все пароли от почтовых ящиков, то смело шифруйте все пароли, так будет спокойнее.

Последние 2 параметра domain_path и domain_in_mailbox указывайте по своему усмотрению. В файле конфигурации в комментариях расписано, за что они отвечают и в чём отличие. Мне кажется, удобно хранить директории именно в таком виде, как я указал. Получится следующий путь до ящика, если у вас архив почты будет жить, к примеру, в директории /mnt/mail/mnt/mail/rocky-linux.ru/root@rocky-linux.ru. Если доменов будет несколько, в такой иерархии удобно работать.

В базе данных Mysql необходимо создать указанные выше в конфигурации пользователя и базу postfix. Если устанавливали phpmyadmin, то можете это сделать там.

С параметрами разобрались. Сохраняем конфиг. Еще один маленький нюанс. Для работы панели управления нужна директория templates_c с правами на запись для web сервера. Сделаем ее и дадим права.

# mkdir /var/www/html/postfixadmin/templates_c
# chown -R www-data:www-data /var/www/html/postfixadmin/templates_c

Идем по адресу http://ip-сервера/postfixadmin/public/setup.php и начинаем установку postfixadmin. Первым делом идет проверка всех необходимых для установки и работы компонентов. Для продолжения установки у вас должна быть такая картинка.

Установка postfixadmin

Нам необходимо указать пароль установки, на основе которого будет сгенерирован hash, который нужно будет добавить в config.local.php. Для этого в форму Generate setup_password введите два раза пароль, который обязательно должен содержать буквы и 2 цифры.

После генерации пароля, под формой появится строка конфига:

$CONF['setup_password'] = '$2y$10$BGiyhSLns.dyd1mPT68xR.nTSdhcl2PPA15EzFrGZKptfGMnyEBPi';

Её нужно добавить в config.local.php в директории postfixadmin. Достаточно заменить строку, которая там есть по умолчанию со значением changeme.

После того, как это сделаете, обновите страницу в браузере. Информация там изменится. У вас не должно быть замечаний к конфигурации, кроме предупреждений по поводу PostgreSQL, так как она нам не нужна и мы её не настраивали. А все остальные проверки должны быть с зелёными индикаторами. Если есть какие-то ошибки, то исправьте их. Обычно забывают или неправильно указывают параметры доступа к MySQL, копируя конфиги из статьи.

Настройка postfixadmin

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

Панель управления Postfix

Используя созданную учётную запись, можно авторизоваться в панели управления. Для этого перейдите по ссылке http://ip-сервера/postfixadmin/public/login.php

Интерфейс postfixadmin

Сразу же добавим наш домен в список почтовых доменов. Идем в раздел Список доменов -> Новый домен и добавляем свой домен. Я обычно не ставлю никаких ограничений.

Добавление домена

При создании домена были добавлены стандартные алиасы, получателя для которых мы указали еще в конфиге — ящик root@rocky-linux.ru. Создание таких алиасов - требование стандартов, но по факту, кроме спама, вы скорее всего ничего не будете получать по этим адресам. Так что их создание оставляйте на свое усмотрения. Я обычно их не делаю, так как ящик для этих алиасов все равно не читаю.

Далее создадим почтовый ящик администратора — root@rocky-linux.ru (на картинках имя ящика admin, уже в процессе передумал и решил делать root). Для этого идем в раздел Обзор -> Создать ящик и заполняем поля.

Вы получите ошибку, что невозможно отправить сообщение. Это нормально, так как непосредственно почтового сервера у нас еще нет, только панель управления для него. Сам ящик на диске создан тоже не будет, но запись в базе данных появится. Это можно проверить через phpmyadmin.

Почтовый ящик в mysql базе

Как вы видите, пароль зашифрован. На этом установку и настройку postfixadmin завершаем. Интерфейс для управления почтовым сервером мы подготовили. Теперь можно заняться непосредственно настройкой postfix.

Настройка postfix

Сердце нашего почтового сервера на Linux — Postfix. В дистрибутиве Debian в минимальной установке он по умолчанию отсутствует. Так что сначала устанавливаем postfix.

# apt install postfix postfix-mysql ca-certificates

Во время установки будет задан вопрос по поводу назначения этого сервера. Тут не важно, что выбрать. Всё равно конфигурацию мы полностью составим сами. Так что можете оставить тот вариант, что будет по умолчанию. Имя сервера укажите как в DNS записи. В моём случае - mail.rocky-linux.ru.

Приводим конфиг postfix /etc/postfix/main.cf к следующему виду, предварительно сохранив оригинальный (рекомендую всегда так делать).

# cp /etc/postfix/main.cf /etc/postfix/main.cf.orig
soft_bounce = no
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/sbin
data_directory = /var/lib/postfix
mail_owner = postfix

myhostname = mail.rocky-linux.ru
mydomain = rocky-linux.ru
myorigin = $myhostname

inet_interfaces = all
inet_protocols = ipv4

mydestination = localhost.$mydomain, localhost
unknown_local_recipient_reject_code = 550
mynetworks = 127.0.0.0/8

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

smtpd_banner = $myhostname ESMTP $mail_name

debug_peer_level = 2
# Строки с PATH и ddd должны быть с отступом в виде табуляции от начала строки
debugger_command =
    PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
    ddd $daemon_directory/$process_name $process_id & sleep 5

setgid_group = postdrop
html_directory = no

relay_domains = mysql:/etc/postfix/mysql/relay_domains.cf
virtual_alias_maps = mysql:/etc/postfix/mysql/virtual_alias_maps.cf,
 mysql:/etc/postfix/mysql/virtual_alias_domain_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual_mailbox_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf

smtpd_discard_ehlo_keywords = etrn, silent-discard
smtpd_forbidden_commands = CONNECT GET POST
broken_sasl_auth_clients = yes
smtpd_delay_reject = yes
smtpd_helo_required = yes
smtp_always_send_ehlo = yes
disable_vrfy_command = yes

smtpd_helo_restrictions = permit_mynetworks,
 permit_sasl_authenticated,
 reject_non_fqdn_helo_hostname,
 reject_invalid_helo_hostname

smtpd_data_restrictions = permit_mynetworks,
 permit_sasl_authenticated,
 reject_unauth_pipelining,
 reject_multi_recipient_bounce,

smtpd_sender_restrictions = permit_mynetworks,
 permit_sasl_authenticated,
 reject_non_fqdn_sender,
 reject_unknown_sender_domain

smtpd_recipient_restrictions = permit_mynetworks,
 permit_sasl_authenticated,
 reject_non_fqdn_recipient,
 reject_unknown_recipient_domain,
 reject_multi_recipient_bounce,
 reject_unauth_destination,

smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtpd_tls_security_level = may
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
smtp_tls_session_cache_database = btree:$data_directory/smtp_tls_session_cache
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtpd_tls_key_file = /etc/postfix/certs/key.pem
smtpd_tls_cert_file = /etc/postfix/certs/cert.pem
tls_random_source = dev:/dev/urandom
smtpd_tls_mandatory_ciphers = low
smtpd_tls_ciphers = low
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3
smtp_tls_mandatory_protocols  = !SSLv2,!SSLv3
smtp_tls_ciphers = low
smtp_tls_mandatory_ciphers = low
smtp_tls_protocols = !SSLv2,!SSLv3
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy_maps
# фиксировать в логе имена серверов, выдающих сообщение STARTTLS, поддержка TLS для которых не включена
smtp_tls_note_starttls_offer = yes

# Ограничение максимального размера письма в байтах
message_size_limit = 20000000
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 15
smtpd_error_sleep_time = 20
anvil_rate_time_unit = 60s
smtpd_client_connection_count_limit = 20
smtpd_client_connection_rate_limit = 30
smtpd_client_message_rate_limit = 30
smtpd_client_event_limit_exceptions = 127.0.0.0/8
smtpd_client_connection_limit_exceptions = 127.0.0.0/8

maximal_queue_lifetime = 1d
bounce_queue_lifetime = 1d

smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/dovecot-auth

# Директория для хранения почты
virtual_mailbox_base = /mnt/mail
virtual_minimum_uid = 1100
virtual_uid_maps = static:1100
virtual_gid_maps = static:1100
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

sender_bcc_maps = hash:/etc/postfix/sender_bcc_maps
recipient_bcc_maps = hash:/etc/postfix/recipient_bcc_maps

compatibility_level=2

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

# mkdir /etc/postfix/mysql && cd /etc/postfix/mysql
# mcedit relay_domains.cf

hosts = 127.0.0.1:3306
user = postfix
password = password
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1'
# mcedit  virtual_alias_domain_maps.cf

hosts = 127.0.0.1:3306
user = postfix
password = password
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1
# mcedit virtual_alias_maps.cf

hosts = 127.0.0.1:3306
user = postfix
password = password
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
# mcedit virtual_mailbox_domains.cf

hosts = 127.0.0.1:3306
user = postfix
password = password
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
# mcedit virtual_mailbox_maps.cf

hosts = 127.0.0.1:3306
user = postfix
password = password
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'

Создадим файл tls_policy_maps, с помощью которого можно вручную задавать версию tls протокола для общения серверов, либо полностью отключать его. Это иногда бывает нужно, если подключаешься к очень старому серверу, который не поддерживает современные протоколы. Приходится использовать нешифрованное подключение.

# mcedit /etc/postfix/tls_policy_maps
93.175.56.122		none
77.221.87.91		encrypt protocols=TLSv1
# postmap /etc/postfix/tls_policy_maps

Так же не стоит забывать, что в современных ОС зачастую на уровне всей системы запрещено использование старых протоколов шифрования, таких как tls 1.0 или ssl3. Чтобы разрешить их, недостаточно настроек почтового сервера. Надо менять системные настройки. Например, вот так это делается в Centos и производных rpm системах - Centos 8 и TLS 1.0 и 1.1.

Продолжаем настройку почтового сервера postfix. Редактируем файл /etc/postfix/master.cf. Нам надо добавить строки, касающиеся настройки Submission для того, чтобы почтовый сервер работал на 587 порту. Смартфоны очень часто при настройке используют этот порт по умолчанию, где-то даже без возможности изменить эту настройку. Приводим секцию, отвечающую за эту работу, к следующему виду.

# cp /etc/postfix/master.cf /etc/postfix/master.cf.orig
submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_tls_auth_only=yes
  -o smtpd_reject_unlisted_recipient=no
  -o smtpd_recipient_restrictions=
  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

Обращаю внимание на пробел в начале строки, начиная со второй. Его надо обязательно оставить. Добавляем еще настройки для того, чтобы наш сервер поддерживал протокол SSL/TLS и слушал порт 465

smtps inet n - n - - smtpd
 -o syslog_name=postfix/smtps
 -o smtpd_tls_wrappermode=yes
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
 -o smtpd_relay_restrictions=permit_mynetworks,permit_sasl_authenticated,defer_unauth_destination
 -o milter_macro_daemon_name=ORIGINATING

В этот же файл добавляем еще одну настройку, которая будет указывать postfix, что доставкой почты у нас будет заниматься dovecot, который мы настроим следом. Добавляем в master.cf в самый конец.

dovecot unix - n n - - pipe
 flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

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

Создаем директорию и сами сертификаты:

# mkdir /etc/postfix/certs
# openssl req -new -x509 -days 3650 -nodes -out /etc/postfix/certs/cert.pem -keyout /etc/postfix/certs/key.pem

Для генерации вам зададут несколько вопросов по поводу данных о сертификате. В принципе, можете там писать все, что угодно. Вот мои данные.

Настройка postfix

Создадим файлы для информации об ящиках, куда будет собираться вся входящая и исходящая почта.

# mcedit /etc/postfix/recipient_bcc_maps
@rocky-linux.ru all_in@rocky-linux.ru
# mcedit /etc/postfix/sender_bcc_maps
@rocky-linux.ru all_out@rocky-linux.ru

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

# postmap /etc/postfix/recipient_bcc_maps /etc/postfix/sender_bcc_maps

Теперь создайте два почтовых ящика all_in@rocky-linux.ru и all_out@rocky-linux.ru через postfixadmin.

Немного поясню по этим ящикам — для чего они нужны. Изначально я их делал, когда пользователи использовали протокол pop3 без сохранения писем на сервере. Это позволяло организовать бэкап всей переписки. Эти ящики очень быстро заполняются и занимают огромный объем, поэтому их обязательно надо чистить. Я просто скриптами регулярно собирал всю почту в архивы с именами в виде дат. Если нужно было какое-то письмо найти, то просто распаковывал нужный архив. Пример прямого поиска писем по дате я показывал в статье про обслуживание почтовой базы.

В случае с imap роль бэкапа отпадает, так как вся почта хранится на сервере. Но эти ящики все равно бывают полезны, когда пользователь, к примеру, удалил какое-то важное письмо и потом делает вид, что его и не было. Если это письмо пришло только сегодня и еще не успело улететь в бэкап, то кроме записи в логах об этом письме, вы не увидите само содержимое. А с такими ящиками все сразу будет понятно, и вопросы отпадут. Последнее применение — служба безопасности. Если у вас есть кто-то, кому положено читать всю переписку, то реализовать этот функционал можно таким простым способом.

Все основные настройки для postfix мы сделали. Некоторые из них завязаны на работу с dovecot, который мы еще не настроили. Поэтому больше postfix не трогаем, не перезапускаем. Идем настраивать dovecot — imap сервер нашей почтовой системы.

Настройка dovecot

Займемся настройкой dovecot — сервер доставки почты пользователю по протоколам pop3 и imap. Я не вижу причин использовать pop3. Он неудобен по сравнению с imap. Чаще всего pop3 отключаю вовсе. Но это уже на ваше усмотрение. Приведу пример с настройкой обоих протоколов. Помимо основного функционала по доставке почты, я настрою несколько полезных плагинов. Расскажу о них поподробнее:

  • Sieve — выполняет фильтрацию почты по заданным правилам в момент локальной доставки на почтовом сервере. Удобство такого подхода в том, что вы один раз можете настроить правило сортировки, и оно будет работать во всех клиентах, которыми вы будете получать почту по imap. Правила создаются, хранятся и исполняются на самом сервере.
  • Acl — позволяет пользователям расшаривать папки в своем почтовом ящике и предоставлять доступ к этим папкам другим пользователям. Не часто видел, чтобы этот функционал настраивали и использовали. Думаю, просто по незнанию. По мне так очень удобный и полезный функционал.

Часто вижу, что люди настраивают плагин quota, который позволяет ограничивать максимальный размер почтового ящика. Я лично в своей работе его не использую. Возможно, когда у тебя клиентов сотни и тысячи это имеет значение и надо обязательно настроить ограничение. Когда же ящиков меньше, нет смысла напрягать людей постоянной чисткой. Сейчас диски стоят не так дорого. Мне кажется, проще и дешевле увеличить место на сервере, нежели постоянно беспокоить пользователей необходимостью чистки ящика. Лучше ограничить максимальный размер письма, скажем 20-ю мегабайтами. Тогда сильно забить ящик даже при большом желании быстро не получится. А почта все-таки важный инструмент в работе. Мне кажется, ее лучше хранить как можно дольше.

Есть еще один полезный плагин - expire, который позволяет удалять устаревшие письма в определенных папках. Например, удалять все письма старше 30-ти дней в корзине и папке со спамом. Но реально пользоваться им не получается по простой причине. Разные почтовые клиенты создают различные папки для корзины и спама. Thunderbird создает папки с латинскими именами trash и spam, outlook с русскими, которые на почтовом сервере преобразуются в кодировку UTF7, мобильные клиенты тоже используют разные имена папок. В итоге нет единообразия, плагин полноценно не работает.

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

Небольшую теорию я дал, теперь переходим к практике. Устанавливаем необходимые для dovecot пакеты.

# apt install dovecot-imapd dovecot-pop3d dovecot-mysql dovecot-sieve dovecot-managesieved dovecot-lmtpd

Изначально конфиг dovecot разбит на отдельные сегменты и лежат они в директории /etc/dovecot/conf.d. Каждый файл — отдельный функционал. Мне не нравится прыгать по файлам, поэтому я храню всё в едином общем файле конфигурации /etc/dovecot/dovecot.conf. С ним мы и будем работать. Обращаю внимание, что это только вопрос удобства. Можете оставить все файлы отдельности, если вам так привычнее. Приводим конфиг к следующему виду.

# cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
listen = *

mail_plugins = mailbox_alias acl
protocols = imap pop3 sieve lmtp

mail_uid = 1100
mail_gid = 1100

first_valid_uid = 1100
last_valid_uid = 1100

auth_verbose = yes
log_path = /var/log/dovecot/main.log
info_log_path = /var/log/dovecot/info.log
debug_log_path = /var/log/dovecot/debug.log

ssl_min_protocol = SSLv3
verbose_ssl = yes
ssl_cert = </etc/postfix/certs/cert.pem
ssl_key = </etc/postfix/certs/key.pem

ssl_cipher_list = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
ssl_prefer_server_ciphers = yes

disable_plaintext_auth = no

mail_location = maildir:/mnt/mail/%d/%u/

auth_default_realm = rocky-linux.ru

auth_mechanisms = PLAIN LOGIN

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

unix_listener auth-userdb {
 user = vmail
 group = vmail
 mode = 0660
 }
}

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

 inet_listener lmtp {
 address = 127.0.0.1
 port = 24
 }
}

userdb {
 args = /etc/dovecot/dovecot-mysql.conf
 driver = sql
 }

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

auth_master_user_separator = *
 
plugin {
 auth_socket_path = /var/run/dovecot/auth-master

 acl = vfile
 acl_shared_dict = file:/mnt/mail/shared-folders/shared-mailboxes.db
 sieve_dir = ~/.sieve/
 mailbox_alias_old = Sent
 mailbox_alias_new = Sent Messages
 mailbox_alias_old2 = Sent
 mailbox_alias_new2 = Sent Items
}

protocol lda {
 mail_plugins = $mail_plugins sieve
 auth_socket_path = /var/run/dovecot/auth-master
 deliver_log_format = mail from %f: msgid=%m %$
 log_path = /var/log/dovecot/lda-errors.log
 info_log_path = /var/log/dovecot/lda-deliver.log
 lda_mailbox_autocreate = yes
 lda_mailbox_autosubscribe = yes
# postmaster_address = root
}

protocol lmtp {
 info_log_path = /var/log/dovecot/lmtp.log
 mail_plugins = quota sieve
 postmaster_address = postmaster
 lmtp_save_to_detail_mailbox = yes
 recipient_delimiter = +
}

protocol imap {
 mail_plugins = $mail_plugins imap_acl
 imap_client_workarounds = tb-extra-mailbox-sep
 mail_max_userip_connections = 30
}

protocol pop3 {
 mail_plugins = $mail_plugins
 pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
 pop3_uidl_format = %08Xu%08Xv
 mail_max_userip_connections = 30
}

service imap-login {
 service_count = 1
 process_limit = 500
 }

service pop3-login {
 service_count = 1
 }

service managesieve-login {
 inet_listener sieve {
 port = 4190
 }
}

service stats {
    unix_listener stats-reader {
        user = vmail
        group = vmail
        mode = 0660
    }

    unix_listener stats-writer {
        user = vmail
        group = vmail
        mode = 0660
    }
}

namespace {
 type = private
 separator = /
 prefix =
 inbox = yes

 mailbox Sent {
 auto = subscribe
 special_use = \Sent
 }
 mailbox "Sent Messages" {
 auto = no
 special_use = \Sent
 }
 mailbox "Sent Items" {
 auto = no
 special_use = \Sent
 }
 mailbox Drafts {
 auto = subscribe
 special_use = \Drafts
 }
 mailbox Trash {
 auto = subscribe
 special_use = \Trash
 }
 mailbox "Deleted Messages" {
 auto = no
 special_use = \Trash
 }
 mailbox Junk {
 auto = subscribe
 special_use = \Junk
 }
 mailbox Spam {
 auto = no
 special_use = \Junk
 }
 mailbox "Junk E-mail" {
 auto = no
 special_use = \Junk
 }
 mailbox Archive {
 auto = no
 special_use = \Archive
 }
 mailbox Archives {
 auto = no
 special_use = \Archive
 }
}

namespace {
 type = shared
 separator = /
 prefix = Shared/%%u/
 location = maildir:%%h:INDEX=%h/shared/%%u
 subscriptions = yes
 list = children
}

Создаем группу и пользователя с указанными в конфиге uid 1100. Если у вас уже занят этот uid, то везде замените его на другой или удалите пользователя с uid 1100, если он вам не нужен.

# groupadd -g 1100 vmail
# useradd -d /mnt/mail/ -g 1100 -u 1100 vmail
# usermod -a -G dovecot vmail
# chown vmail:vmail /mnt/mail

Создаем конфигурационные файлы для доступа к mysql базе.

# mcedit /etc/dovecot/dovecot-mysql.conf
driver = mysql
default_pass_scheme = CRYPT
connect = host=127.0.0.1 dbname=postfix user=postfix password=password
user_query = SELECT '/mnt/mail/%d/%u' as home, 'maildir:/mnt/mail/%d/%u' as mail, 1100 AS uid, 1100 AS gid, concat('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
password_query = SELECT username as user, password, '/mnt/mail/%d/%u' as userdb_home, 'maildir:/mnt/mail/%d/%u' as userdb_mail, 1100 as userdb_uid, 1100 as userdb_gid, concat('*:bytes=', quota) AS userdb_quota_rule FROM mailbox WHERE username = '%u' AND active = '1'

Обращаю внимание на параметр шифрования паролей. Если пароли не зашифрованы, то параметр будет PLAIN.

Создадим директорию и файлы для логов.

# mkdir /var/log/dovecot
# cd /var/log/dovecot && touch main.log info.log debug.log lda-errors.log lda-deliver.log lmtp.log
# chown -R vmail:dovecot /var/log/dovecot

Создаем служебную папку для плагина acl.

# mkdir /mnt/mail/shared-folders
# chown -R vmail:vmail /mnt/mail

На этом основная настройка почтового сервера на базе postfix и dovecot завершена. Можно запускать службы и проверять работу системы.

# systemctl restart postfix
# systemctl start dovecot
# systemctl enable postfix
# systemctl enable dovecot

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

Настройка logrotate для dovecot

Для того, чтобы логи Dovecot не разрослись до бесконечности, их имеет смысл периодически ротировать с помощью logrotate. Для этого создадим файл конфигурации /etc/logrotate.d/dovecot следующего содержания:

/var/log/dovecot/*.log {
    weekly
    rotate 3
    compress
    missingok
    notifempty
    postrotate
	doveadm log reopen
    endscript
    create 0644 vmail dovecot
}

Для логов postfix этого делать не нужно, так как они обрабатываются с помощью системной службы rsyslog, для которой ротация обычно уже настроена в системе по умолчанию.

Проверка работы почтового сервера

Самый простой и быстрый способ проверить работу почтового сервера — отправить на него письмо. Я буду отправлять со своего почтового адреса zeroxzed@gmail.com на адрес root@rocky-linux.ru. Вот что должно быть в логе, если у вас все правильно настроено и почтовый сервер нормально работает.

# tail -f /var/log/mail.log
Dec 13 22:36:38 serveradmin postfix/smtpd[3261414]: connect from mail-ej1-f43.google.com[209.85.218.43]
Dec 13 22:36:38 serveradmin postfix/smtpd[3261414]: Anonymous TLS connection established from mail-ej1-f43.google.com[209.85.218.43]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
Dec 13 22:36:38 serveradmin postfix/smtpd[3261414]: B6ED05C76F: client=mail-ej1-f43.google.com[209.85.218.43]
Dec 13 22:36:38 serveradmin postfix/cleanup[3261419]: B6ED05C76F: message-id=<CAHWPLcM7Nfh517h81Sr1zWXcwZ2vxwCcA9LGULroib8H12Wzkg@mail.gmail.com>
Dec 13 22:36:38 serveradmin postfix/qmgr[3228618]: B6ED05C76F: from=<zeroxzed@gmail.com>, size=3098, nrcpt=1 (queue active)
Dec 13 22:36:38 serveradmin postfix/pipe[3261420]: B6ED05C76F: to=<root@rocky-linux.ru>, relay=dovecot, delay=0.13, delays=0.02/0.01/0/0.1, dsn=2.0.0, status=sent (delivered via dovecot service)
Dec 13 22:36:38 serveradmin postfix/qmgr[3228618]: B6ED05C76F: removed

Пояснять тут нечего, по логу все понятно. Было подключение от сервера mail-ej1-f43.google.com[209.85.218.43] с использованием протокола шифрования и шифров TLSv1.3 with cipher TLS_AES_128_GCM_SHA256.

Письмо было доставлено в указанный ящик. В директории /mnt/mail была создана директория с именем домена rocky-linux.ru, а в ней создана папка с именем ящика root@rocky-linux.ru. В итоге новое, ещё не прочитанное письмо, лежит здесь - /mnt/mail/rocky-linux.ru/root@rocky-linux.ru/new. Можно зайти и прочитать его прямо через консоль. Это обычный файл в текстовом формате.

Во время этого теста у меня был отключен сбор входящей почты в отдельный ящик all-in. Если бы это было включено, то в логе отдельной строкой было бы указано, что письмо сохранено и в этот ящик.

Dec 13 22:36:38 serveradmin postfix/pipe[3261420]: B6ED05C76F: to=<all_in@rocky-linux.ru>, relay=dovecot, delay=0.13, delays=0.02/0.01/0/0.1, dsn=2.0.0, status=sent (delivered via dovecot service)

Директории с почтовыми ящиками создаются в момент получения первого письма в ящик. Непрочитанное письмо помещается в директорию new в почтовом ящике. После прочтения переносится в cur.

Попробуем теперь подключиться к почтовому ящику по imap, прочитать письмо и отправить ответ. Настроим любой почтовый клиент для проверки работы настроенного почтового сервера. Я для этих целей буду использовать Thunderbird. Из всех почтовых клиентов мне он нравится больше всего. В основном из-за его портированной версии. Указываем следующие настройки.

Настройка почтового сервера в Thunderbird

Так как мы используем самоподписанный сертификат tls, почтовый клиент предупредит нас о том, что серверу нельзя доверять.

Самоподписанный сертификат в Thunderbird

Нас это не пугает, добавляем сертификат в список доверенных и продолжаем работать. Позже получим и настроим нормальный сертификат. На этом этапе чаще всего возникают проблемы. Если не получается подключиться к ящику, смотрите логи postfix и dovecot. Можете показать ошибки в комментариях, я подскажу, в какую сторону смотреть.

Я подключился к почтовому ящику и увидел тестовые письма. Отвечу на одно из них и посмотрю в логе, как прошла отправка. У меня еще раз выскочило окно с предупреждением о небезопасном сертификате. Еще раз добавляю его в исключения. Это нормально, сертификат проверяется во время получения почты в dovecot, а во время отправки в postfix. Так что нужны 2 подтверждения. Отправляю письмо еще раз и смотрю лог.

# tail -f /var/log/mail.log
Dec 13 23:16:26 serveradmin postfix/smtpd[3262078]: connect from broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139]
Dec 13 23:16:26 serveradmin postfix/smtpd[3262078]: Anonymous TLS connection established from broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
Dec 13 23:16:26 serveradmin postfix/smtpd[3262078]: 6D8415C76F: client=broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139], sasl_method=PLAIN, sasl_username=root@rocky-linux.ru
Dec 13 23:16:26 serveradmin postfix/cleanup[3262085]: 6D8415C76F: message-id=<b76aecc7-9d78-aaa3-2aed-686240d74faf@rocky-linux.ru>
Dec 13 23:16:26 serveradmin postfix/qmgr[3228618]: 6D8415C76F: from=<root@rocky-linux.ru>, size=1134, nrcpt=1 (queue active)
Dec 13 23:16:26 serveradmin postfix/smtpd[3262078]: disconnect from broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139] ehlo=2 starttls=1 auth=1 mail=1 rcpt=1 data=1 quit=1 commands=8
Dec 13 23:16:26 serveradmin postfix/smtp[3262086]: Trusted TLS connection established to gmail-smtp-in.l.google.com[108.177.14.26]:25: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256
Dec 13 23:16:26 serveradmin postfix/smtp[3262086]: 6D8415C76F: to=<zeroxzed@gmail.com>, relay=gmail-smtp-in.l.google.com[108.177.14.26]:25, delay=0.55, delays=0.05/0.02/0.24/0.25, dsn=2.0.0, status=sent (250 2.0.0 OK 1670962586 g20-20020ac24d94000000b004b4b6264a59si1352638lfe.486 - gsmtp)
Dec 13 23:16:26 serveradmin postfix/qmgr[3228618]: 6D8415C76F: removed

Все в порядке. Видно подключение с моего ip, успешную sasl авторизацию, формирование письма на сервере, присваивание ему message-id, отправка в ящик получателя. Все этапы прошли без ошибок.

Расскажу, куда еще надо смотреть для отладки почтовой системы. Да и не только отладки, во время работы периодически придется разбираться, куда ушло то или иное письмо, кто и когда подключался к ящику. Разные ситуации бывают. В файле /var/log/dovecot/lda-deliver.log содержится информация обо всех пришедших письмах — когда, от кого и в какой ящик было положено.

Dec 13 22:36:38 lda(root@rocky-linux.ru)<3261421><MKrJMUbUmGPtwzEARRIZ7g>: Info: mail from zeroxzed@gmail.com: msgid=<CAHWPLcM7Nfh517h81Sr1zWXcwZ2vxwCcA9LGULroib8H12Wzkg@mail.gmail.com> saved mail to INBOX

В /var/log/dovecot/info.log информация о подключениях к почтовым ящикам — кто, когда, откуда и каким способом подключался к серверу. Вот пример успешной аутентификации:

Dec 13 23:16:34 imap-login: Info: Login: user=<root@rocky-linux.ru>, method=PLAIN, rip=75.22.224.139, lip=62.113.115.231, mpid=3262089, TLS, session=<1HPjS7vvfSpNJeCL>

А вот неудачной:

Dec 13 23:13:00 auth-worker(3262032): Info: conn unix:auth-worker (pid=3262012,uid=111): auth-worker<1>: sql(root@rocky-linux.ru,75.22.224.139,<WkcmP7vvMypNJeCL>): Password mismatch

Тут кто-то пытается подключиться, используя несуществующий ящик:

Dec 13 23:20:13 auth-worker(3262143): Info: conn unix:auth-worker (pid=3262142,uid=111): auth-worker<1>: sql(administracion@rocky-linux.ru,194.55.186.126): unknown user

Эти три лога основные для разбора ситуаций:

  • postfix - mail.log
  • dovecot - lda-deliver.log
  • dovecot - info.log

На текущий момент почтовый сервер на базе postfix и dovecot полностью работоспособен. В таком виде им без проблем можно пользоваться. Но функционала мало. Использовать плагины sieve и acl через удаленные почтовые клиенты неудобно. Проще всего их настроить через web почту roundcube. Установим эту web панель на наш почтовый сервер.

Установка web интерфейса roundcube

Установим и настроим самый популярный web интерфейс для postfix — roundcube. Вообще говоря, его не обязательно ставить на почтовый сервер. Более того, я бы рекомендовал его ставить в другое место. Если в инфраструктуре имеется отдельный веб сервер, лучше поставить roundcube туда. Но в рамках этой статьи, я всё буду ставить на один сервер для простоты и наглядности. Если у вас всё получится на одном сервере, потом сможете не спеша разнести по разным.

Скачиваем исходники последней LTS или STABLE версии roundcube. Я обычно использую именно LTS версию, хотя она достаточно старая. Но моя практика показывает, что именно в ней всё работает стабильно и сразу, без лишней возни. К примеру, когда я готовил эту статью, у меня не получилось настроить работу автоответчика, о котором я расскажу отдельно ниже. Я его включал, а он просто не работает. За разумный срок (1 час) я не смог выяснить причину этого и опять откатился на LTS версию, где все заработало сразу.

Если есть желание, попробуйте последнюю версию. Может всё, что вам надо, заработает. Но в целом, там во всех версиях всё примерно одинаковое. В новых версиях есть адаптивный скин elastic, но кто-то по-прежнему использует стандартный larry.

# cd ~ && wget https://github.com/roundcube/roundcubemail/releases/download/1.5.3/roundcubemail-1.5.3-complete.tar.gz

Распаковываем и перемещаем на веб-сервер. Я установлю веб интерфейс для почты на отдельный поддомен webmail, а исходники положу в директорию /web/sites/webmail.rocky-linux.ru/www. Это моя стандартная структура каталогов для веб сервера. Вы можете сделать, как вам удобно. Не обязательно полностью повторять за мной.

# tar xzvf roundcubemail-1.5.3-complete.tar.gz
# cp -R roundcubemail-1.5.3/* /web/sites/webmail.rocky-linux.ru/www
# chown -R www-data:www-data /web/sites/webmail.rocky-linux.ru
Не забудьте проверить в момент установки номер актуальной версии roundcube и заменить его в приведенных выше командах.

Отмечу, что если для вас не критично использовать максимально свежую версию, можете установить roundcube из стандартного репозитория Debian. Но даже LTS версия там старее, чем та, что есть на сайте. На момент написания статьи в репозитории была версия 1.4.13 от 30-го декабря 2021 года, а на сайте 1.5.3 от 26 июня 2022 года. Разница в пол года.

Установим необходимые для работы roundcube зависимости:

# apt install aspell aspell-en dbconfig-common fonts-glyphicons-halflings javascript-common libaspell15 libjs-bootstrap libjs-bootstrap4 libjs-codemirror libjs-jquery libjs-jquery-minicolors libjs-jquery-ui libjs-jstimezonedetect libjs-popper.js libjs-sizzle node-jquery php-auth-sasl php-mail-mime php-masterminds-html5 php-net-sieve php-net-smtp php-net-socket php-pspell php7.4-pspell

Меняем некоторые параметры в php. Редактируем или добавляем в /etc/php/7.4/fpm/php.ini:

post_max_size = 32M
upload_max_filesize = 32M
date.timezone = Europe/Moscow

Перезапускаем php-fpm.

# systemctl restart php7.4-fpm

Создаём конфигурацию виртуального хоста для roundcube. Если вы планируете заходить в веб почту по ip адресу, как в phpmyadmin или postfixadmin, то ничего настраивать не надо. Просто положите исходники в папку веб сервера /var/www/html и заходите по ip.

server {
    listen 80;
    server_name webmail.rocky-linux.ru;
    root /web/sites/webmail.rocky-linux.ru/www;
    index index.php index.html index.htm;

    access_log /web/sites/webmail.rocky-linux.ru/logs/access.log;
    error_log /web/sites/webmail.rocky-linux.ru/logs/error.log;

    auth_basic           "Administrator's Area";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        try_files  $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
    try_files  $uri =404;
    fastcgi_pass   unix:/run/php/php7.4-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param DOCUMENT_ROOT /web/sites/webmail.rocky-linux.ru/www/;
    fastcgi_param SCRIPT_FILENAME /web/sites/webmail.rocky-linux.ru/www$fastcgi_script_name;
    fastcgi_param PATH_TRANSLATED /web/sites/webmail.rocky-linux.ru/www$fastcgi_script_name;
    include fastcgi_params;
    }
}

Я сразу же закрыл доступ посторонним к roundcube дополнительным паролем через basic auth, как я это сделал в самом начале с phpmyadmin. Это не обязательно делать. Roundcube вполне безопасная панель и её можно оставлять в открытом доступе. Но и в ней находили критические уязвимости. Так что за ней нужно внимательно следить и регулярно обновлять, защищать от перебора учёток и т.д. Если закрыть доступ отдельным паролем, то можно следить не так внимательно. Как делать - решать вам. Для пользователей лишняя аутентификация всегда нежелательна.

Сохраняем конфигурацию nginx в файл /etc/nginx/sites-available/webmail.rocky-linux.ru.conf и делаем символьную ссылку с него в /etc/nginx/sites-enabled:

# ln -s /etc/nginx/sites-available/webmail.rocky-linux.ru.conf /etc/nginx/sites-enabled/webmail.rocky-linux.ru.conf

Проверяем конфигурацию nginx и перезапускаем:

# nginx -t && nginx -s reload

Если всё в порядке, то можно идти по адресу http://webmail.rocky-linux.ru/installer/ и выполнять настройку roundcube. Вы должны увидеть интерфейс установщика и все проверки в состоянии OK, кроме тех, что касаются сторонних баз. Нам нужна только MySQL

Установка roundcube

В самом низу нажимайте NEXT. Здесь нужно будет указать параметры подключения к базе данных. Создайте отдельную базу данных для roundcube и укажите данные подключения.

Также на этой странице нужно будет указать несколько параметров:

  • smtp_server — localhost
  • smtp_port — 25
  • Use the current IMAP username and password for SMTP authentication — галочка должна стоять
  • language — ru_RU
  • skin — elastic (можете поменять на larry, если вам он больше нравится)
  • Выбираем плагины — acl, managesieve, userinfo. Остальные на свое усмотрение.

Жмем CREATE CONFIG. Должны увидеть сообщение:

The config file was saved successfully into /web/sites/webmail.rocky-linux.ru/www/config directory of your Roundcube installation.

Жмем CONTINUE. Открывается страница с проверкой настроек. Нам нужно инициализировать базу данных. Для этого жмите на соответствующую кнопку.

Roundcube webmail installer

Тут проверять отправку почты неудобно, можно этого не делать. Зайдем в почтовый ящик и там всё проверим. Если что, конфиг потом всё равно можно вручную отредактировать. Папку installer удаляем. Заходим в почтовый ящик через roundcube. Набирать нужно полное имя ящика и пароль. Если всё сделали правильно, должны попасть в свой почтовый ящик.

Веб интерфейс roundcube

Мне уже успели спам прислать, пока писал статью. Можете попробовать написать и отправить письмо. В настройках можно изменить некоторые параметры web интерфейса. Если будут какие-то ошибки, можно посмотреть лог самого roundcube - /web/sites/webmail.rocky-linux.ru/www/logs/errors.log Он достаточно информативен. В этой же директории будет вестись лог всех отправленных писем через web интерфейс.

Если вы хотите, чтобы пользователи могли самостоятельно изменять свой пароль от почтового ящика, смотрите отдельную статью, как это настроить - изменение почтового пароля пользователем через roundcube.

Настройка фильтра почты sieve

Sieve очень удобная штука, но вот хорошего интерфейса для управления через почтовый клиент я не знаю. Существует плагин для Thunderbird, который так и называется - sieve. Но лично мне он не понравился вообще, так как предлагает писать правила определенным кодом. Для этого надо знать синтаксис, тратить время. Можете сами на него посмотреть — https://github.com/thsmi/sieve.

К счастью, есть удобный способ писать правила фильтрации для sieve через roundcube. Там это реализовано отдельным плагином managesieve, который мы активировали во время установки. Его конфиг находится в директории plugins/managesieve. Скопируйте дефолтный конфиг и проследите, чтобы там были следующие настройки.

# cp config.inc.php.dist config.inc.php
$config['managesieve_port'] = 4190;
$config['managesieve_host'] = 'localhost';
$config['managesieve_usetls'] = false;

Для создания правила фильтрации, зайдите в свой почтовый ящик через roundcube. Переходите в раздел Настройки -> Фильтры и создавайте новое правило.

Настройка фильтра почты sieve

После этого письма будут обрабатываться правилом сразу после поступления в почтовый сервер, вне зависимости от вашего подключения к ящику. В ящике в папке .sieve появилась запись с настроенным правилом. Можете познакомиться с синтаксисом написания правил. Он несложный.

Настройка автоответчика

В roundcube есть замечательная возможность настроить автоответчик в почтовом ящике. Это актуально, к примеру, если вы уходите в отпуск. Вы можете сами настроить автоответчик, который будет отправлять письмо с указанной вами информацией всем, от кого будут приходить письма в ваш ящик. Возможность эта реализована на базе того же плагина managesieve. По умолчанию она отключена. Активировать ее нужно вручную.

Для того, чтобы модуль автоответчика заработал, отредактируйте конфигурационный файл плагина. Для этого открываем его в моем случае по следующему адресу /plugins/managesieve/config.inc.php. Изменяем там параметр:

$config['managesieve_vacation'] = 1;

После этого достаточно просто обновить веб интерфейс roundcube, и появятся новые настройки по адресу Настройки -> Вне офиса.

Настройка автоответчика в postfix

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

Общие папки по imap

Рассмотрим настройку необычного и полезного функционала в виде общих папок. С их помощью один пользователь почтового ящика может предоставить другому пользователю доступ к папке внутри своего почтового ящика. Где и как использовать этот функционал, каждый может придумать сам, в зависимости от своих потребностей. Мне кажется это удобным в том случае, когда создан какой-то общий ящик, на который только поступает информация и нет необходимости писать ответ от его имени. То есть по сути работает как обычный почтовый алиас. Но в случае с алиасом и несколькими почтовыми ящиками, письмо падает в каждый ящик. Если таких писем и получателей много, то идет большое дублирование одного и того же письма в рамках почтового сервера. Если сделать ящик и настроить общий доступ к папке, подключить ее всем пользователям, то дублирования почты не будет. Каждый сможет прочитать письмо, без необходимости его доставки в каждый конкретный ящик.

Настроим общую папку imap. Хотя настраивать нам, по сути, нечего. Мы уже всё настроили ранее. Добавили соответствующие настройки в dovecot и активировали плагин acl в roundcube. Теперь нужно просто сделать папку и открыть ее для другого пользователя. Для этого идем в раздел Настройки -> Папки. Создаем там любую папку. В моем случае это папка с названием Общая. После того, как создали папку, открываем ее еще раз.

Общие imap папки

Добавляем необходимый доступ либо всем ящикам в домене, либо какому-то конкретному. Так же можно указать, какого рода это будет доступ:

  • чтение
  • запись
  • удаление

Права доступа на почтовые папки

Заходим в ящик, которому добавили общий доступ и проверяем.

Подключение общей папки почты

Все в порядке, общая папка imap настроена и подключена. В папке /mnt/mail/shared-folders появился файл с настроенным выше правилом.

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

Настройка DKIM

Напишу своими словами как я понимаю работу dkim. С помощью dkim вся исходящая почта сервера подписывается электронной цифровой подписью, связанной с именем домена. Открытый ключ шифрования с помощью DNS публикуется в txt записи. Таким образом, удаленный сервер, при получении письма от вас, сравнивает цифровую подпись с опубликованным в DNS открытым ключом вашего домена. Если всё в порядке, то считает, что ваше письмо в самом деле пришло от вас, а не от мошенников. То есть с помощью этой технологии можно однозначно идентифицировать отправителя.

Не путать эту технологию с защитой от спама. Защиты тут нет. Любой спамер так же может себе сделать dkim подпись. Спамеру не составит большого труда настроить на своем сервере dkim и отправлять спам, но подписанный электронной цифровой подписью. Теоретически, dkim помогает защититься от подделки адреса отправителя, когда письмо якобы от вас шлет совсем другой сервер. Но с этим можно бороться и другими способами. В общем, я до конца не понимаю, зачем это надо. Я много лет эксплуатировал сервера без dkim подписей и проблем это не вызывало. Но так как настроить dkim не сложно, сейчас всегда это делаю.

Для настройки dkim устанавливаем соответствующие пакеты:

# apt install opendkim opendkim-tools

Создаем директорию для хранения ключей:

# mkdir -p /etc/postfix/dkim && cd /etc/postfix/dkim

Генерируем ключи для домена:

# opendkim-genkey -D /etc/postfix/dkim/ -d rocky-linux.ru -s mail
rocky-linux.ru имя почтового домена
mail селектор, я обычно указываю как имя самого сервера

На выходе получаете пару файлов — закрытый (приватный) и открытый ключ. Закрытый останется на сервере, открытый будет опубликован в DNS. Переименуем их сразу, чтобы не путаться, если у вас будет несколько доменов. Ключи нужно будет делать для каждого домена.

# mv mail.private mail.rocky-linux.ru.private
# mv mail.txt mail.rocky-linux.ru.txt

Создаем файл с таблицей ключей, в которой будут описаны все домены. В данном случае только один.

# mcedit keytable
mail._domainkey.rocky-linux.ru rocky-linux.ru:mail:/etc/postfix/dkim/mail.rocky-linux.ru.private

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

# mcedit signingtable
*@rocky-linux.ru mail._domainkey.rocky-linux.ru

Выставляем права доступа на все файлы:

# chown root:opendkim *
# chmod u=rw,g=r,o= *

Рисуем конфиг службы.

# cp /etc/opendkim.conf /etc/opendkim.conf.orig
# mcedit /etc/opendkim.conf
AutoRestart yes
AutoRestartRate 10/1h
Umask 022
Syslog yes
SyslogSuccess yes
LogWhy yes
Mode sv
UserID opendkim:opendkim
Socket inet:8891@localhost
PidFile /var/run/opendkim/opendkim.pid
Canonicalization relaxed/relaxed
Selector default
MinimumKeyBits 1024
KeyFile /etc/postfix/dkim/mail.rocky-linux.ru.private
KeyTable /etc/postfix/dkim/keytable
SigningTable refile:/etc/postfix/dkim/signingtable

Добавляем в конфигурационный файл postfix в самый конец следующие параметры:

# mcedit /etc/postfix/main.cf
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
milter_protocol = 2

Перезапускаем postfix и dkim, последний добавляем в автозагрузку.

# systemctl restart postfix
# systemctl restart opendkim.service
# systemctl enable opendkim.service

Теперь нам надо добавить открытый ключ в DNS. Идём в консоль управления DNS и добавляем новую TXT запись. Ее содержание берем из файла /etc/postfix/dkim/mail.rocky-linux.ru.txt

# cat /etc/postfix/dkim/mail.rocky-linux.ru.txt
mail._domainkey	IN	TXT	( "v=DKIM1; h=sha256; k=rsa; "
	  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAodU6tspBDprFmj0aloGo2AH0vwq9OTyyfNRjeHsIFvZUKyBWvDtYZNuPqnQXi+DLrxjYW8rkEXqipoV29/GQaNUbzKqeUF+C6JS5ehxR8p3dS1E5sR8lrHOrmwfiQN/Bgn9HPAXc8mvJ7m2Y2DJbIgpFEas7g76AtphXZOKGZECmiaQHPpA4I1bPLFdg46tNK0S4vrmNWDXvLR"
	  "5Q2culydzdfduUjbaRfUjsIw05uObxO2zV4FivSghgeEfsHsVt48QhXM5wU+pwOji+cDTc6a6FuzU+t8Xx0Wrxg1WyRyRAA1CnqN5siokTMsyXG5Q4hCOiIW4DdD+uBaFpaV12RwIDAQAB" )  ; ----- DKIM key mail for rocky-linux.ru

Убираем кавычки, лишние пробелы и вставляем. Должно получиться вот так:

v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAodU6tspBDprFmj0aloGo2AH0vwq9OTyyfNRjeHsIFvZUKyBWvDtYZNuPqnQXi+DLrxjYW8rkEXqipoV29/GQaNUbzKqeUF+C6JS5ehxR8p3dS1E5sR8lrHOrmwfiQN/Bgn9HPAXc8mvJ7m2Y2DJbIgpFEas7g76AtphXZOKGZECmiaQHPpA4I1bPLFdg46tNK0S4vrmNWDXvLR5Q2culydzdfduUjbaRfUjsIw05uObxO2zV4FivSghgeEfsHsVt48QhXM5wU+pwOji+cDTc6a6FuzU+t8Xx0Wrxg1WyRyRAA1CnqN5siokTMsyXG5Q4hCOiIW4DdD+uBaFpaV12RwIDAQAB

Настройка DKIM

Проверяю работу. Отправляю письмо на gmail и смотрю лог почтового сервера:

# tail -f /var/log/mail.log

Dec 14 01:14:20 serveradmin postfix/smtpd[3265746]: connect from broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139]
Dec 14 01:14:20 serveradmin postfix/smtpd[3265746]: Anonymous TLS connection established from broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
Dec 14 01:14:20 serveradmin postfix/smtpd[3265746]: ED9E25C77B: client=broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139], sasl_method=PLAIN, sasl_username=root@rocky-linux.ru
Dec 14 01:14:21 serveradmin postfix/cleanup[3265750]: ED9E25C77B: message-id=<67773a25-1b7b-a29c-03ad-63b4e9787d38@rocky-linux.ru>
Dec 14 01:14:21 serveradmin opendkim[3265392]: ED9E25C77B: DKIM-Signature field added (s=mail, d=rocky-linux.ru)
Dec 14 01:14:21 serveradmin postfix/qmgr[3228618]: ED9E25C77B: from=<root@rocky-linux.ru>, size=1177, nrcpt=1 (queue active)
Dec 14 01:14:21 serveradmin postfix/smtpd[3265746]: disconnect from broadband-75-22-224-139.ip.moscow.rt.ru[75.22.224.139] ehlo=2 starttls=1 auth=1 mail=1 rcpt=1 data=1 quit=1 commands=8
Dec 14 01:14:21 serveradmin postfix/smtp[3265751]: Trusted TLS connection established to gmail-smtp-in.l.google.com[64.233.162.27]:25: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256
Dec 14 01:14:21 serveradmin postfix/smtp[3265751]: ED9E25C77B: to=<zeroxzed@gmail.com>, relay=gmail-smtp-in.l.google.com[64.233.162.27]:25, delay=1, delays=0.19/0.02/0.2/0.59, dsn=2.0.0, status=sent (250 2.0.0 OK 1670969661 r22-20020ac24d16000000b004b582a5d845si1457974lfi.198 - gsmtp)
Dec 14 01:14:21 serveradmin postfix/qmgr[3228618]: ED9E25C77B: removed

Все в порядке, электронная цифровая подпись установлена. Проверим, как google отреагировал на нашу подпись:

Проверка DKIM

Тоже всё в порядке. Подпись выполнена корректно, проверку прошла. Дополнительно проверить корректность dkim записи в dns можно онлайн сервисом — http://dkimcore.org/c/keycheck. Не забывайте, что DNS записи обновляются не мгновенно. Прежде чем проверять DKIM, подождите от 10 минут до часа, а может и больше.

Настройка SPF

Настроим еще одно средство для повышения доверия к нашей почте со стороны других серверов — spf. Расскажу опять своими словами для чего это нужно. Spf запись добавляется в виде TXT записи в DNS вашего домена. С помощью этой записи вы указываете, какие ip адреса имеют право отправлять почту от вашего имени. Если кто-то из спамеров будет использовать ваше имя домена при рассылке спама, он не пройдет проверку по spf и скорее всего будет идентифицирован как спам.

Можно указать конкретные ip адреса в записи, а можно сказать, чтобы ip адреса проверялись по спискам A и MX записей. У нас простой случай и только 1 сервер с одним ip, поэтому укажем конкретно этот ip адрес. Идём в панель управления dns и добавляем новую TXT запись.

rocky-linux.ru. TXT v=spf1 ip4:62.113.115.231 ~all

Настройка SPF

Больше ничего делать не надо. Можно снова отправить письмо на gmail и проверить. Обращаю внимание, что gmail может и без настройки spf в dns указать, что проверка spf прошла, хотя txt запись еще не была создана. Гугл умный. Думаю, он автоматом сопоставляет все dns записи домена и убеждается, что отправка идет с доверенного сервера, к которому привязана A запись и MX запись.

Но отправка может идти не только с почтового сервера. К примеру, может быть отдельно web сервер с интернет магазином. Он по каким-то причинам может отправлять почту сам (нет модуля для smtp отправки, не работает smtp авторизация, разработчики хотят использовать php_mail и т.д.), а не через настроенный почтовый сервер. Так часто бывает. Тогда нужно обязательно добавить в spf запись ip адрес этого web сервера, с которого будет идти отправка.

Настройка DMARC

Для настройки DMARC на самом почтовом сервере ничего делать не надо. По своей сути это просто указание другим, что делать с письмами от вас, не прошедшими проверки dkim и spf (которые являются подделками, если у вас всё настроено правильно). Для этого сам принимающий почтовый сервер должен поддерживать работу в соответствии с dmark. Плюс, для вашего домена должны быть настроены правила, что делать в том или ином случае.

Есть три типа действий, которые можно настроить с помощью dmark:

  1. Отклонить письмо.
  2. Пометить письмо как спам.
  3. Ничего не делать.

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

Указанные правила мы сейчас и добавим с помощью TXT записи в DNS. Запись будет такая:

v=DMARC1; p=none; rua=mailto:dmarc@rocky-linux.ru

Настройка DMARC

Отчеты будут приходить в xml формате на ящик dmarc@rocky-linux.ru. Нужно будет еще потрудиться, чтобы в них разобраться :) В общем случае, я вообще не слежу за dmark. Думаю, это актуально только для крупных компаний, где есть отдельные люди, которые занимаются обслуживанием почты.

Дополнительный функционал почтового сервера postfix

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

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

  1. Защиту от подбора паролей с помощью fail2ban.
  2. Мониторинг почтового сервера postfix с помощью zabbix.
  3. Сбор статистики с помощью pflogsumm или чего-то подобного.
  4. Просмотр и анализ логов с помощью webmin.
  5. Использование бесплатных сертификатов let’s encrypt.
  6. Регулярную очистку служебных почтовых ящиков.
  7. Бэкап всей почтовой базы.
  8. Сбор логов с почтовых серверов в ELK Stack.

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

  1. Clamav — известный антивирус. Считаю, что сейчас он не актуален, так как вирусов, от которых он способен защитить, я уже давно не видел. Сейчас вирусная эпидемия шифровальщиков. От них он не защищает. К тому же на момент написания статьи доступ к антвирусным базам с IP адресов РФ заблокирован. Нужно использовать прокси.
  2. Spamassasin или spamd — популярные бесплатные антиспам фильтры. Скажу честно, работал с ними очень мало и могу быть не объективен. Насколько я видел их настройку и работу — они требуют к себе некоторого внимания, калибровки, особенно на начальном этапе. Мне обычно не хочется этим заниматься. Вместо этого я использую либо платный антиспам от компании Kaspersky, либо перед почтовым сервером ставлю Proxmox Mail Gateway, который имеет все фильтры уже в настроенном виде с управлением через веб интерфейс.
  3. Graylist — эффективное средство борьбы со спамом. Я уже подробно его рассматривал, когда писал про iredmail, так что не буду повторяться. Скажу лишь, что режет спам очень эффективно и бесплатно, но есть существенные неудобства, которые по моему мнению не перекрывают плюсы. Поэтому я не использую.

В качестве антиспама я предпочитаю коммерческое решение — Kaspersky Anti-Spam. Я знаю этот продукт уже лет 15. Он действительно отлично фильтрует спам. Ложных срабатываний вообще не припомню, 95% спама фильтрует, может больше. Субъективно, работает лучше чем антиспам у того же Gmail или Яндекса. С ним вопрос спама отпадает вообще. Стоит он недорого, можно купить лицензию на меньшее количество ящиков, чем реально используется в системе. Этот вопрос никак не отслеживается и на качество работы не влияет. Но нужно понимать, что это уже нарушение лицензионного соглашения. Но можно всякие хитрости придумать, чтобы и фильтровать и не нарушать.

Борьба со спамом средствами postfix

Сначала хотел сразу все настройки postfix разместить в соответствующем разделе в едином конфиге, но потом передумал и решил все же вынести этот вопрос на отдельное рассмотрение. Возможно, не каждому захочется сразу в эту тему углубляться. Всё, что рассказано выше, позволит настроить полноценный почтовый сервер, который будет успешно принимать почту и доставлять её пользователям. Но в таком виде он будет принимать слишком много спама, но зато не будет проблем с тем, что от кого-то что-то не придет. Как ни крути, но все средства борьбы со спамом так или иначе несут накладные расходы в виде ложных срабатываний с той или иной вероятностью. Если вы решите не заморачиваться и купить Kaspersky Anti-Spam, можете этот раздел не читать. Он сам реализует все те проверки, что мы будем делать. Если же хотите своими силами бороться со спамом средствами postfix, то давайте дальше разбираться.

Я буду использовать штатные возможности postfix, позволяющие отсеять спам по тем или иным параметрам еще до получения письма. Это очень эффективный способ с точки зрения производительности. Благодаря этому правильно настроенный на отсев спама postfix часто ставят перед exchange, чтобы снизить на него нагрузку. Сразу дам ссылки на официальную документацию с описанием параметров, которые я буду использовать:

  1. smtpd_helo_restrictions
  2. smtpd_sender_restrictions
  3. smtpd_recipient_restrictions
  4. smtpd_data_restrictions
  5. smtpd_client_restrictions

Есть еще парочка — smtpd_etrn_restrictions и smtpd_end_of_data_restrictions, но я ими не пользуюсь.

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

Долго думал, как лучше всего представить информацию по этому разделу. В итоге решил просто написать часть конфига, которая отвечает за restrictions с комментариями. Более подробную информацию по каждой настройке вы можете найти в официальной документации postfix, ссылки я привел выше, либо в гугле. Данные настройки это моя многолетняя калькуляция различных параметров, собранных из черновиков и рабочих серверов. Не везде всё было настроено именно в таком виде, так как ситуации бывают разные. Сейчас я постарался всё собрать в одном месте и аккуратно описать. Те проверки в борьбе со спамом, что вам не нужны, просто закомментируйте. В конце я еще пройдусь по некоторым из них и поделюсь своим опытом.

#Описание списков исключений
smtpd_restriction_classes = white_client_ip,
                            black_client_ip,
                            block_dsl,
                            white_client,
                            white_helo,
                            black_client,
                            mx_access

# IP адреса, которые нужно пропускать всегда
white_client_ip		= check_client_access hash:/etc/postfix/lists/white_client_ip

# IP адреса, которые нужно блокировать всегда
black_client_ip		= check_client_access hash:/etc/postfix/lists/black_client_ip

# E-mail, которые нужно пропускать всегда
white_client		= check_sender_access hash:/etc/postfix/lists/white_client

# E-mail, которые нужно блокировать всегда
black_client		= check_sender_access hash:/etc/postfix/lists/black_client

# Неправильные значения HELO, которые мы тем не менее принимаем
white_helo = check_sender_access hash:/etc/postfix/lists/white_helo
# Правила для блокировки различных динамических ip.
block_dsl 		= check_client_access regexp:/etc/postfix/lists/block_dsl

# Список приватных сетей, которые не могут быть использованы в качестве IP для MX записей
mx_access		= check_sender_mx_access cidr:/etc/postfix/lists/mx_access

# Проверки на основе данных, переданных в HELO/EHLO hostname
smtpd_helo_restrictions =	permit_mynetworks,
		permit_sasl_authenticated,
		white_client_ip,
                white_helo,
		black_client_ip,
		block_dsl,
		# Отказываем серверам, у которых в HELO несуществующий или не FQDN адрес 
		reject_invalid_helo_hostname,
		reject_non_fqdn_helo_hostname,
		# Запрещаем приём писем от серверов, представляющихся адресом, для которого не существует A или MX записи.
		reject_unknown_helo_hostname

# Проверки клиентского компьютера или другого почтового сервера, который соединяется с сервером postfix для отправки письма
smtpd_client_restrictions = 	permit_mynetworks,
		permit_sasl_authenticated,
		# Отвергает запрос, когда клиент отправляет команды SMTP раньше времени, еще не зная, поддерживает ли Postfix конвейерную обработку команд ESMTP
		reject_unauth_pipelining,
		# Блокируем клиентов с адресами from, домены которых не имеют A/MX записей
		reject_unknown_address,
		reject_unknown_client_hostname

# Проверки исходящей или пересылаемой через нас почты на основе данных MAIL FROM
smtpd_sender_restrictions =	permit_mynetworks,
		permit_sasl_authenticated,
		white_client,
		black_client,
		# Запрет отправки писем, когда адрес MAIL FROM не совпадает с логином пользователя
		reject_authenticated_sender_login_mismatch,
		# Отклоняем письма от несуществующих доменов
		reject_unknown_sender_domain,
		# Отклоняем письма от доменов в не FQDN формате
		reject_non_fqdn_sender,
		# Отклонение писем с несуществующим адресом отправителя
		reject_unlisted_sender,
		reject_unauth_destination,
		# Отклонять сообщения от отправителей, ящики которых не существуют, использовать аккуратно
		#reject_unverified_sender,
		mx_access

# Правила приема почты нашим сервером на основе данных RCPT TO
smtpd_recipient_restrictions =  permit_mynetworks,
		permit_sasl_authenticated,
		# Отклоняет всю почту, что адресована не для наших доменов
		reject_unauth_destination,
		# Отклонение писем с несуществующим адресом получателя
		reject_unlisted_recipient,
		# Отклоняет сообщения на несуществующие домены
		reject_unknown_recipient_domain,
		# Отклоняет сообщения если получатель не в формате FQDN
		reject_non_fqdn_recipient,
		# Отклоняем прием от отправителя с пустым адресом письма, предназначенным нескольким получателям.
		reject_multi_recipient_bounce

У меня во всех ограничениях первыми правилами стоят разрешения для mynetworks и авторизовавшихся пользователей (permit_sasl_authenticated). Важно понимать, что это значит и для чего сделано. Ограничения читаются последовательно в порядке их перечисления. Таким образом, мы своих пользователей пускаем мимо ограничений, а для всех остальных выполняются проверки.

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

  • reject_invalid_helo_hostname и reject_unknown_helo_hostname — под эти правила иногда попадают почтовые серверы клиентов, которые не очень хорошо настроены. У них бывают неправильные адреса, кривые записи dns, отсутствие обратных зон и т.д. Их немного, но попадаются. Это не страшно, если вы регулярно следите за сервером. Отправитель получит сразу сообщение о том, что его письмо не дошло до вас. Если он как-то сообщит вам о проблеме, вы легко добавите его в белый список и всё будет нормально. Если вам не хочется следить за сервером, лучше не указывайте эти ограничения. Но спам они отсекают хорошо. Сюда попадают все завирусованные компьютеры и сервера без нормальных настроек dns (а их чаще всего и нет).
  • reject_unverified_sender — специально его закомментировал. Я тестировал этот параметр. В принципе, работает нормально, но есть, как обычно, нюансы. Поясню, что делает этот параметр. Когда вам кто-то шлет письмо, ваш сервер обращается к серверу отправителю и спрашивает его стандартной командой, есть ли на сервере такой отправитель. Если удаленный сервер отвечает, что есть, то никаких проблем — письмо принимается. Если удаленный сервер не отвечает или говорит, что такого адресата нет — письмо отклоняем. Очевидно, что такие проверки создают дополнительную постоянную нагрузку. Это нужно учитывать. К тому же, у вас почтовый лог постоянно будет забит этими проверками, особенно, если вам приходит много спама. На каждое спамовое письмо будет идти проверка, а сервера отправителя скорее всего либо нет, либо он неправильный, либо не отвечает и т.д. Все это будет постоянно проверяться и фиксироваться. В общем, я не использую.

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

soft_bounce = yes

Когда он включен, все ответы сервера с кодами ошибок 5XX, заменяются на 4ХХ. То есть постоянная ошибка, которая сразу отклоняет письмо, заменяется на временную, которая предлагает повторить отправку позже. Таким образом, вы увидите работу всех ограничений, но письма не будут отклонены навсегда. Сервер отправителя через некоторое время снова придет к вам с новой попыткой доставки почты. Письмо безвозвратно не отклоняется. Вы можете проанализировать работу фильтра и решить, ставить его на постоянную работу или с ним что-то не так.

Создадим теперь файлы с белыми и черными списками.

cd /etc/postfix/lists && touch white_client_ip black_client_ip white_client black_client white_helo block_dsl mx_access

Ниже пример содержания этих файлов. Вы можете менять по своему усмотрению.

# cat white_client_ip
195.28.34.162 OK
141.197.4.160 OK
# cat black_client_ip
205.201.130.163 REJECT You IP are blacklisted!
198.2.129.162 REJECT You IP are blacklisted!
# cat white_client
# Принимать всю почту с домена яндекс
yandex.ru OK
# Разрешить конкретный ящик
spammer@mail.ru OK
# cat black_client
# Блокировать всю почту с домена mail.ru
mail.ru REJECT You domain are blacklisted!
# Блокировать конкретный ящик
spam@rambler.ru REJECT You e-mail are blacklisted!
# cat white_helo
# Могут попадаться вот такие адреса, которые не пройдут наши проверки
ka-s-ex01.itk.local     OK
exchange.elcom.local    OK
# cat block_dsl
/^dsl.*\..*\..*/i                               553 AUTO_DSL spam
/dsl.*\..*\..*/i                                553 AUTO_DSL1 spam
/[ax]dsl.*\..*\..*/i                            553 AUTO_XDSL spam
/client.*\..*\..*/i                             553 AUTO_CLIENT spam
/cable.*\..*\..*/i                              553 AUTO_CABLE spam
/pool.*\..*\..*/i                               553 AUTO_POOL spam
/dial.*\..*\..*/i                               553 AUTO_DIAL spam
/ppp.*\..*\..*/i                                553 AUTO_PPP spam
/dslam.*\..*\..*/i                              553 AUTO_DSLAM spam
/node.*\..*\..*/i                               553 AUTO_NODE spam
/([0-9]*-){3}[0-9]*(\..*){2,}/i                 553 SPAM_ip-add-rr-ess_networks
/([0-9]*\.){4}(.*\.){3,}.*/i                    553 SPAM_ip-add-rr-ess_networks
/.*\.pppool\..*/i                               553 SPAM_POOL
/[0-9]*-[0-9]*-[0-9]*-[0-9]*-tami\.tami\.pl/i   553 SPAM_POOL
/pool-[0-9]*-[0-9]*-[0-9]*-[0-9]*\..*/i         553 SPAM_POOL
/.*-[0-9]*-[0-9]*-[0-9]*-[0-9]*\.gtel.net.mx/i  553 SPAM_POOL
/dhcp.*\..*\..*/i                               553 SPAM_DHCP
# cat mx_access
127.0.0.1      DUNNO 
127.0.0.2      550 Domains not registered properly
0.0.0.0/8      REJECT Domain MX in broadcast network 
10.0.0.0/8     REJECT Domain MX in RFC 1918 private network 
127.0.0.0/8    REJECT Domain MX in loopback network 
169.254.0.0/16 REJECT Domain MX in link local network 
172.16.0.0/12  REJECT Domain MX in RFC 1918 private network 
192.0.2.0/24   REJECT Domain MX in TEST-NET network 
192.168.0.0/16 REJECT Domain MX in RFC 1918 private network 
224.0.0.0/4    REJECT Domain MX in class D multicast network 
240.0.0.0/5    REJECT Domain MX in class E reserved network 
248.0.0.0/5    REJECT Domain MX in reserved network

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

После редактирования файлов обязательно выполняем команду на перестроение базы данных. Я перестрою сразу все файлы:

cd /etc/postfix/lists && postmap white_client_ip black_client_ip white_client black_client white_helo block_dsl mx_access

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

Приведу в завершении описания методов борьбы со спамом простой пример. Добавим в black_client почтовый адрес и отправим с него письмо.

# cat black_client
zeroxzed@gmail.com REJECT Your e-mail was banned!
# postmap black_client

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

# tail -f /var/log/mail.log
Feb 11 16:21:31 mail postfix/smtpd[20115]: connect from mail-ua1-f48.google.com[209.85.222.48]
Feb 11 16:21:31 mail postfix/smtpd[20115]: Anonymous TLS connection established from mail-ua1-f48.google.com[209.85.222.48]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)
Feb 11 16:21:32 mail postfix/smtpd[20115]: NOQUEUE: reject: RCPT from mail-ua1-f48.google.com[209.85.222.48]: 554 5.7.1 <zeroxzed@gmail.com>: Sender address rejected: Your e-mail was banned!; from=<zeroxzed@gmail.com> to=<root@kirushin-vladimir.ru> proto=ESMTP helo=
Feb 11 16:21:32 mail postfix/smtpd[20115]: disconnect from mail-ua1-f48.google.com[209.85.222.48] ehlo=2 starttls=1 mail=1 rcpt=0/1 data=0/1 quit=1 commands=5/7

Вот и результат. На этом по борьбе со спамом всё.

Заключение

Проверить настроенный почтовый сервер можно с помощью онлайн сервиса https://www.mail-tester.com. Не факт, что получите максимальный бал, но все недочеты будут указаны. Критичное нужно исправить (например, если обратная зона неправильная), некритичное можно пропустить (если dkim, к примеру, не настраивали).

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

Так же вам могут быть полезны мои материалы на тему postfix:

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

Углубленный онлайн-курс по MikroTik.

Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном онлайн-курcе по администрированию MikroTik. Автор курcа – сертифицированный тренер MikroTik Дмитрий Скоромнов. Более 40 лабораторных работ по которым дается обратная связь. В три раза больше информации, чем в MTCNA.

Помогла статья? Подписывайся на telegram канал автора

Анонсы всех статей, плюс много другой полезной и интересной информации, которая не попадает на сайт.

Автор Zerox

Владимир, системный администратор, автор сайта. Люблю настраивать сервера, изучать что-то новое, делиться знаниями, писать интересные и полезные статьи. Открыт к диалогу и сотрудничеству. Если вам интересно узнать обо мне побольше, то можете послушать интервью. Запись на моем канале - https://t.me/srv_admin/425 или на сайте в контактах.

254 комментария

  1. Алексей

    Добрый день!
    Дошел до проверки почты. 1
    При попытке посмотреть лог командой tail -f /var/log/mail.logпишет нет такого файла и каталога.
    2 при отправке почты возвращается письмо с отбивкой 554 5.7.1 relay access denied

    • Алексей

      в логе следующая информация
      2024-04-16T17:20:07.652878+03:00 mx postfix[1978]: Postfix is using backwards-compatible default settings
      2024-04-16T17:20:07.653054+03:00 mx postfix[1978]: See http://www.postfix.org/COMPATIBILITY_README.html for details
      2024-04-16T17:20:07.653119+03:00 mx postfix[1978]: To disable backwards compatibility use "postconf compatibility_level=3.6" and "postfix reload"
      2024-04-16T17:20:07.670709+03:00 mx postfix/postfix-script[1984]: stopping the Postfix mail system
      2024-04-16T17:20:07.672877+03:00 mx postfix/master[1601]: terminating on signal 15
      2024-04-16T17:20:07.771304+03:00 mx postfix[2039]: Postfix is using backwards-compatible default settings
      2024-04-16T17:20:07.771442+03:00 mx postfix[2039]: See http://www.postfix.org/COMPATIBILITY_README.html for details
      2024-04-16T17:20:07.771498+03:00 mx postfix[2039]: To disable backwards compatibility use "postconf compatibility_level=3.6" and "postfix reload"
      2024-04-16T17:20:08.025723+03:00 mx postfix/postfix-script[2269]: starting the Postfix mail system
      2024-04-16T17:20:08.031299+03:00 mx postfix/master[2271]: daemon started -- version 3.7.10, configuration /etc/postfix

      Прошу совета.

      • В логе нет ошибок. Вы просто остановили и запустили заново postfix.

        • Алексей

          Пытаюсь отправить почту внутри моей сети с одного ящика ка на другой. В логах получаю следующие ошибки. Письма не приходят.
          2024-04-17T11:44:19.665472+03:00 mx postfix/qmgr[5258]: 5FDE01C0E87: from=, size=719, nrcpt=3 (queue active)
          2024-04-17T11:44:19.683628+03:00 mx postfix/qmgr[5258]: warning: connect to transport private/dovecot: Connection refused
          2024-04-17T11:44:19.683695+03:00 mx postfix/qmgr[5258]: warning: connect to transport private/dovecot: Connection refused
          2024-04-17T11:44:19.704489+03:00 mx postfix/error[5554]: 5FDE01C0E87: to=, relay=none, delay=572, delays=572/0.03/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:44:19.709223+03:00 mx postfix/error[5555]: 5FDE01C0E87: to=, relay=none, delay=572, delays=572/0.04/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:44:19.713540+03:00 mx postfix/error[5554]: 5FDE01C0E87: to=, relay=none, delay=572, delays=572/0.04/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:46:32.542997+03:00 mx postfix/smtpd[5560]: connect from localhost[127.0.0.1]
          2024-04-17T11:46:32.567405+03:00 mx postfix/smtpd[5560]: 8A7E21C0E96: client=localhost[127.0.0.1]
          2024-04-17T11:46:32.570003+03:00 mx postfix/cleanup[5564]: 8A7E21C0E96: message-id=
          2024-04-17T11:46:32.577208+03:00 mx postfix/qmgr[5258]: 8A7E21C0E96: from=, size=564, nrcpt=3 (queue active)
          2024-04-17T11:46:32.578260+03:00 mx postfix/qmgr[5258]: warning: connect to transport private/dovecot: Connection refused
          2024-04-17T11:46:32.578307+03:00 mx postfix/qmgr[5258]: warning: connect to transport private/dovecot: Connection refused
          2024-04-17T11:46:32.579844+03:00 mx postfix/smtpd[5560]: disconnect from localhost[127.0.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
          2024-04-17T11:46:32.600374+03:00 mx postfix/error[5565]: 8A7E21C0E96: to=, relay=none, delay=0.04, delays=0.02/0.01/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:46:32.607101+03:00 mx postfix/error[5566]: 8A7E21C0E96: to=, relay=none, delay=0.05, delays=0.02/0.02/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:46:32.612033+03:00 mx postfix/error[5565]: 8A7E21C0E96: to=, relay=none, delay=0.05, delays=0.02/0.03/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:47:15.383053+03:00 mx postfix/smtpd[5560]: connect from amp-test04.amplituda.loc[192.168.0.35]
          2024-04-17T11:47:15.473377+03:00 mx postfix/smtpd[5560]: Anonymous TLS connection established from amp-test04.amplituda.loc[192.168.0.35]: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
          2024-04-17T11:47:15.511198+03:00 mx postfix/smtpd[5560]: 7CC121C0EA1: client=amp-test04.amplituda.loc[192.168.0.35], sasl_method=PLAIN, sasl_username=root@apiksin.ru
          2024-04-17T11:47:15.540678+03:00 mx postfix/cleanup[5564]: 7CC121C0EA1: message-id=
          2024-04-17T11:47:15.549033+03:00 mx postfix/qmgr[5258]: 7CC121C0EA1: from=, size=725, nrcpt=2 (queue active)
          2024-04-17T11:47:15.556612+03:00 mx postfix/error[5566]: 7CC121C0EA1: to=, relay=none, delay=0.05, delays=0.04/0/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:47:15.602744+03:00 mx postfix/smtp[5576]: connect to mail.apiksin.ru[195.16.59.211]:25: Connection refused
          2024-04-17T11:47:15.608444+03:00 mx postfix/smtp[5576]: 7CC121C0EA1: to=, relay=none, delay=0.1, delays=0.04/0.04/0.01/0, dsn=4.4.1, status=deferred (connect to mail.apiksin.ru[195.16.59.211]:25: Connection refused)
          2024-04-17T11:47:20.557541+03:00 mx postfix/smtpd[5560]: disconnect from amp-test04.amplituda.loc[192.168.0.35] ehlo=2 starttls=1 auth=1 mail=1 rcpt=1 data=1 quit=1 commands=8
          2024-04-17T11:49:19.697881+03:00 mx postfix/qmgr[5258]: 8E8AE1C0E4A: from=, size=727, nrcpt=2 (queue active)
          2024-04-17T11:49:19.713781+03:00 mx postfix/qmgr[5258]: warning: connect to transport private/dovecot: Connection refused
          2024-04-17T11:49:19.713843+03:00 mx postfix/qmgr[5258]: 8FA6B1C0E88: from=, size=3769, nrcpt=1 (queue active)
          2024-04-17T11:49:19.736736+03:00 mx postfix/error[5581]: 8E8AE1C0E4A: to=, relay=none, delay=956, delays=956/0.02/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)
          2024-04-17T11:49:19.743588+03:00 mx postfix/error[5582]: 8FA6B1C0E88: to=, relay=none, delay=955, delays=955/0.02/0/0.01, dsn=4.3.0, status=deferred (mail transport unavailable)

          Прошу помощи

          • Вот ошибка:

            connect to transport private/dovecot: Connection refused

            Что-то не так с настройкой Dovecot, либо он вообще не работает.

            • Алексей

              А что может обозначать такое предупреждение warning: database /etc/postfix/tls_policy_maps.db is older than source file /etc/postfix/tls_policy_maps?

              • Алексей

                С последним вопросом разобрался.
                При настройке master.cf и main.cf по Вашей инструкции надо было дописать в файл данные или очистить файл и дописать данные из инструкции?

                • Алексей

                  А если Dovecot настраивать в одном файле devecot.conf что делать с файлами по умолчанию?

  2. Спасибо за статью

    1. вы забыли добавить
    в /etc/default/opendkim
    SOCKET=inet:8891@localhost иначе вылазит ошибка Can't open PID file /run/opendkim/opendkim.pid (yet?) after start: No such file or directory

    2. момент
    подпись DKIM сделана по вашему образцу, но письма не подписываются в var/log/mail.log
    mail opendkim[982]: A128D246FB: no signature data

    отсюда вопрос если почтовый домен - mail.domen.ru, то при opendkim-genkey -D /etc/postfix/dkim/ -d DOMEN.ru (ИЛИ MAIL.DOMEN.ru) -s mail

  3. Максим

    Добрый день.

    Подскажите пожалуйста, чтобы сделать ротацию лога roundcube (в Вашем случае по пути /web/sites/webmail.rocky-linux.ru/www/logs/errors.log), достаточно такой конфигурации?

    /web/sites/webmail.rocky-linux.ru/www/logs/*.log {
    weekly
    rotate 3
    compress
    missingok
    notifempty
    create 0644 www-data www-data
    endscript
    }

    Или необходимо добавить systemctl restart restart php7.4-fpm

  4. Максим

    Добрый день.

    А не подскажите, почему права на папку и файлы для DKIM мы даем пользователю root, а не пользователю opendkim?

  5. Дмитрий

    при запуске postfix выдаются ошибки:

    postmulti[62156]: /usr/sbin/postconf: warning: open "mysql" configuration "/etc/postfix/mysql/relay_domains.cf": No such file or directo>
    ... несколько одинаковых сообщений
    configure-instance.sh[62075]: postconf: warning: open "mysql" configuration "/etc/postfix/mysql/relay_domains.cf": No such file or direc>
    ... несколько одинаковых сообщений

    при этом сервис стартуется
    20:10:57 systemd[1]: Finished postfix.service - Postfix Mail Transport Agent.
    20:10:57 systemd[1]: Starting postfix.service - Postfix Mail Transport Agent...
    20:10:57 systemd[1]: Started postfix@-.service - Postfix Mail Transport Agent (instance -).
    20:10:57 systemd[1]: Starting postfix@-.service - Postfix Mail Transport Agent (instance -)...
    20:10:47 systemd[1]: Stopped postfix@-.service - Postfix Mail Transport Agent (instance -).
    20:10:47 systemd[1]: postfix@-.service: Deactivated successfully.
    20:10:47 systemd[1]: Stopping postfix@-.service - Postfix Mail Transport Agent (instance -)...
    20:10:47 systemd[1]: Stopped postfix.service - Postfix Mail Transport Agent.
    20:10:47 systemd[1]: postfix.service: Deactivated successfully.
    20:08:52 systemd[1]: Finished postfix.service - Postfix Mail Transport Agent.
    20:08:52 systemd[1]: Starting postfix.service - Postfix Mail Transport Agent...
    20:08:52 systemd[1]: Started postfix@-.service - Postfix Mail Transport Agent (instance -).

    в директории этот файл существует

    ls -lah
    -rw-r--r-- 1 root root 157 Dec 15 15:32 realy_domains.cf
    -rw-r--r-- 1 root root 256 Dec 15 15:33 virtual_alias_domain_maps.cf
    -rw-r--r-- 1 root root 153 Dec 15 15:34 virtual_alias_maps.cf
    -rw-r--r-- 1 root root 174 Dec 15 15:34 virtual_mailbox_domains.cf
    -rw-r--r-- 1 root root 159 Dec 15 15:35 virtual_mailbox_maps.cf

    и в файле main.cf всё прописано правильно
    relay_domains = mysql:/etc/postfix/mysql/realy_domains.cf

    если переименовать realy_domains.cf в realy_domains.cf_
    то ошибка точно такая же, то есть - словно этого файла нет в этой директории
    но он есть

    • Чудес в Linux не бывает. Подобная ошибка - это либо опечатка где-то в пути или имени файла, или отсутствие прав у postfix на доступ к этим файлам. Проверяйте всё внимательно. Я уже много раз видел подобные сообщения и везде результат один - невнимательность.

      • Дмитрий

        проверял сто раз, всё совпадало

        в общем, переименовал директорию, преименовал файл,
        в конфигурационном файле тоже изменил
        и... заработало

        видимо, при копировании кода с сайта, добавлялись какие-то неправильные символы
        ====
        теперь проблема в другом
        нет подключения извне к 25 порту
        110 порт залетает на раз, 25 порт не работает снаружи
        даже при отключенном iptables

        куда смотреть?

        ss -lptun
        Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
        udp UNCONN 0 0 195.63.186.65:123 0.0.0.0:* users:(("ntpd",pid=399,fd=19))
        udp UNCONN 0 0 127.0.0.1:123 0.0.0.0:* users:(("ntpd",pid=399,fd=18))
        udp UNCONN 0 0 0.0.0.0:123 0.0.0.0:* users:(("ntpd",pid=399,fd=17))
        udp UNCONN 0 0 [fe10::2034:ff:fe12:3ea3]%eth0:123 [::]:* users:(("ntpd",pid=399,fd=22))
        udp UNCONN 0 0 [::1]:123 [::]:* users:(("ntpd",pid=399,fd=20))
        udp UNCONN 0 0 [::]:123 [::]:* users:(("ntpd",pid=399,fd=16))
        tcp LISTEN 0 100 0.0.0.0:465 0.0.0.0:* users:(("smtpd",pid=68666,fd=6),("smtpd",pid=68660,fd=6),("master",pid=67402,fd=111))
        tcp LISTEN 0 500 0.0.0.0:143 0.0.0.0:* users:(("dovecot",pid=60151,fd=39))
        tcp LISTEN 0 100 0.0.0.0:25 0.0.0.0:* users:(("master",pid=67402,fd=12))
        tcp LISTEN 0 100 0.0.0.0:110 0.0.0.0:* users:(("dovecot",pid=60151,fd=24))
        tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=59290,fd=5),("nginx",pid=59289,fd=5))
        tcp LISTEN 0 80 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=20005,fd=21))
        tcp LISTEN 0 100 0.0.0.0:995 0.0.0.0:* users:(("dovecot",pid=60151,fd=25))
        tcp LISTEN 0 500 0.0.0.0:993 0.0.0.0:* users:(("dovecot",pid=60151,fd=40))
        tcp LISTEN 0 128 0.0.0.0:22222 0.0.0.0:* users:(("sshd",pid=372,fd=3))
        tcp LISTEN 0 100 0.0.0.0:587 0.0.0.0:* users:(("master",pid=67402,fd=108))
        tcp LISTEN 0 128 [::]:22222 [::]:* users:(("sshd",pid=372,fd=4))

        вот такая рабочая таблица до отключения
        iptables -L -v -n
        Chain INPUT (policy DROP 140K packets, 30M bytes)
        pkts bytes target prot opt in out source destination
        765 68914 ACCEPT 0 -- lo * 0.0.0.0/0 0.0.0.0/0
        0 0 ACCEPT 1 -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 0
        4 240 ACCEPT 1 -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 3
        0 0 ACCEPT 1 -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 11
        32 1470 ACCEPT 1 -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
        14829 1211K ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
        18 935 DROP 0 -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID
        0 0 DROP 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x00
        0 0 DROP 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW
        5 260 ACCEPT 6 -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22222
        289 11672 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25
        5 272 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:465
        93 5428 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:110
        97 5784 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:995
        5 300 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:143
        2 120 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:993
        83 4468 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80

        Chain FORWARD (policy DROP 0 packets, 0 bytes)
        pkts bytes target prot opt in out source destination
        0 0 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
        0 0 DROP 0 -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID

        Chain OUTPUT (policy DROP 0 packets, 0 bytes)
        pkts bytes target prot opt in out source destination
        765 68914 ACCEPT 0 -- * lo 0.0.0.0/0 0.0.0.0/0
        39456 15M ACCEPT 0 -- * eth0 0.0.0.0/0 0.0.0.0/0
        0 0 ACCEPT 0 -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
        0 0 DROP 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW

  6. Добрый день.
    Дошел до авторизации в roundcube, после ввода логина и пароля от почты получаю ошибку:
    405 Not Allowed

  7. Добрый день.
    Не получается получить почту.
    в логе /var/log/mail.log есть только
    Dec 13 14:16:34 master: Warning: Killed with signal 15 (by pid=2375 uid=0 code=kill)
    Dec 13 14:16:35 log(1441): Warning: Killed with signal 15 (by pid=1 uid=0 code=kill)
    после перезагрузки сервера.
    почта без проблем уходит, порты проброшены успешно, куда еще можно посмотреть?

    • по 25 порту инфа ходит
      15:48:56.486497 IP forward103c.mail.yandex.net.54594 > 10.10.10.191.smtp: Flags [S], seq 2054743843, win 64240, options [mss 1380,sackOK,TS val 1905301022 ecr 0,nop,wscale 7], length 0
      15:48:56.486516 IP 10.10.10.191.smtp > forward103c.mail.yandex.net.54594: Flags [R.], seq 0, ack 2054743844, win 0, length 0
      15:48:56.608154 IP forward205c.mail.yandex.net.33308 > 10.10.10.191.smtp: Flags [S], seq 82508126, win 64240, options [mss 1380,sackOK,TS val 543906551 ecr 0,nop,wscale 7], length 0
      15:48:56.608168 IP 10.10.10.191.smtp > forward205c.mail.yandex.net.33308: Flags [R.], seq 0, ack 82508127, win 0, length 0
      15:49:10.425743 IP forward206c.mail.yandex.net.48906 > 10.10.10.191.smtp: Flags [S], seq 3894317582, win 64240, options [mss 1380,sackOK,TS val 3187865858 ecr 0,nop,wscale 7], length 0
      15:49:10.425773 IP 10.10.10.191.smtp > forward206c.mail.yandex.net.48906: Flags [R.], seq 0, ack 3894317583, win 0, length 0
      15:49:47.927876 IP forward204c.mail.yandex.net.38132 > 10.10.10.191.smtp: Flags [S], seq 3804235869, win 64240, options [mss 1380,sackOK,TS val 304591604 ecr 0,nop,wscale 7], length 0
      15:49:47.927905 IP 10.10.10.191.smtp > forward204c.mail.yandex.net.38132: Flags [R.], seq 0, ack 3804235870, win 0, length 0
      15:49:59.280793 IP forward203c.mail.yandex.net.58458 > 10.10.10.191.smtp: Flags [S], seq 2799687098, win 64240, options [mss 1380,sackOK,TS val 4158658136 ecr 0,nop,wscale 7], length 0
      15:49:59.280827 IP 10.10.10.191.smtp > forward203c.mail.yandex.net.58458: Flags [R.], seq 0, ack 2799687099, win 0, length 0

  8. Добрый день.
    Возможно упустил в инструкции, но какие порты надо прокидывать до сервера?

    • В зависимости от ваших настроек и потребностей. Посмотрите, какие порты используют postfix и dovecot и откройте их для клиентов.

      • для работы почты, сейчас при попытке проверить нет лога в /var/log/mail.log
        и почта с которой отправляю пишет что Host or domain name not found.

      • наверно дело даже не в портах
        при отправке письма на root получаю ошибку:
        : Host or domain name not found. Name service error for
        name=ms.rmaic18.ru.rmaic18.ru type=AAAA: Host not found
        на сервере:
        root@pochta01:~# dig rmaic18.ru mx

        ; <> DiG 9.18.19-1~deb12u1-Debian <> rmaic18.ru mx
        ;; global options: +cmd
        ;; Got answer:
        ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54693
        ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

        ;; OPT PSEUDOSECTION:
        ; EDNS: version: 0, flags:; udp: 512
        ;; QUESTION SECTION:
        ;rmaic18.ru. IN MX

        ;; ANSWER SECTION:
        rmaic18.ru. 3600 IN MX 10 ms.rmaic18.ru.rmaic18.ru.

        ;; Query time: 60 msec
        ;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
        ;; WHEN: Tue Dec 12 08:44:27 +04 2023
        ;; MSG SIZE rcvd: 69
        днс на домене
        Хост Тип Значение
        @ MX 20 mail.rmaic18.ru
        mail A 78.85.16.162

        • Вас ничего не смущает в домене, который вы используете - ms.rmaic18.ru.rmaic18.ru? По-моему тут ошибка :) Задвоилось имя в DNS записи.

  9. а нормально что при установки всех php так же ставиться apach и затем стартовое окно при проверке nginx выходит apach?

    • По идее нет, но всё течёт, всё меняется. Возможно какой-то пакет притащил в зависимостях apache. Можно его просто остановить или удалить. Это не проблема.

  10. Виталий

    Доброго! Не подскажите сбор почты как настроить с других ящиков?

  11. Дмитрий

    Здравствуйте, у Вас в Thunderbird для подключения по imap используется mail.rocky-linux.ru, а как сделать чтобы использовался imap.rocky-linux.ru ?
    Ну и аналогично для pop и smtp?

  12. Виталий

    Доброго! А есть инструкция по настройке Касперского для почтовых серверов на Debian ? Насколько я понял он управляетется через apache.

    • У Касперского есть своя инструкция по интеграции в Postfix. Я всегда по ней настраивал.

  13. Доброго! А есть инструкция по настройке АВ Касперского для почтовых серверов на Linux? Насколько я понял касперский администрируется через apache.

  14. Владимир

    Уважаемые соратники, подскажите где почитать или расскажите как!
    Облазил много интернета, но так и не смог найти рабочий вариант.

    Исходные данные: все настроено по статье и работает с апреля месяца, 900+ адресов и все замечательно.

    ЗАДАЧА: есть алиас - all@domain.ru - нужно запретить из-вне присылать на него почту, т.е. с любого адреса *@domain.ru письма приходят на этот алиас, а с, допустим, help@gmail.com на адрес all@domain.ru отправитель получит reject

    • Это можно настроить с помощью стандартных restrictions, которые есть у postfix. У меня нет готового решения именно этого случая. Подскажу только, что смотреть надо в сторону smtpd_recipient_restrictions и smtpd_sender_restrictions.

  15. Аноним

    При выборе пункта проверка почты. не приходит письмо из вне!. Я не вижу не в одном каталоге mnt/mail. Никакой mail.log файл не создается. dovecot и postfix работают, ошибок нет! Подскажите где искать причину

    • Для начала нужно всё-таки найти лог почтовой системы. Он должен быть в /var/log/mail.log Если его нет, значит у вас не запущен или не установлен postfix. В логе будет либо видно ошибку, либо, если там совсем не будет записей о входящих письмах, письма вообще не доходят до почтового сервера. Тогда надо разбираться, почему не доходят.

  16. Александр

    Errors (MUST be fixed)
    ⛔Database connection string : mysql:host=localhost;dbname=postfix;charset=UTF8
    ⛔Problem connecting to database, check database configuration ($CONF['database_*'] entries in config.local.php)
    ⛔SQLSTATE[HY000] [1698] Access denied for user 'postfix'@'localhost'
    Database Update
    Something went wrong while trying to connect to the database. A message should be logged - check PHP's error_log ()

    \n
    Could not connect to database to perform updates; check PHP error log.

  17. Александр

    "В базе данных Mysql необходимо создать указанные выше в конфигурации пользователя и базу postfix. Если устанавливали phpmyadmin, то можете это сделать там."

    Можно написать как сделать в phpmyadmin?

  18. Александр

    эта статья под 12 Debian не подходит?

    • Под 12-й подходит, но работает только с версии 12.1, в 12.0 - косяков много. Ставил на 12.0 - проблемы пошли с попытки установки MariaDB - не ставится. На 12.1 и выше - все работает.

  19. Доброго дня! для такой связки как у Вас какие нужны ресурсы сервера? для нормальной ( + запас на будущее) работы

    • Ничего особенного не нужно. Можно всё запустить на виртуальной машине с 1 CPU и 2G Ram и диск по потребностям от 20G. Потом добавить ресурсов, если надо будет.

  20. Руслан

    Добрый день, делаю пошагово по инструкции. Первая проблема на этаме после установки и конфигурации nginx. При вводе ip адреса в браузер, открывается страничка Apache2 Ubuntu Default Page
    Второй после настройки phpMyAdmin , не могу авторизоваться рутом на странице Добро пожаловать в phpMyAdmin. Ошибка Невозможно подключиться к серверу MySQL mysqli_real_connect(): (HY000/1698): Access denied for user 'root'@'localhost'
    Подскажите пожалуйста, где и менно и какие действия сделать. В Линуксовых ДБ не силен

  21. Андрей

    Выяснил, что между ящиками, созданными на сервере почта отправляется и получается, а снаружи не приходит.

  22. Андрей

    Добрый день! 1. Почта из ящика root@...com уходит, но в него ничего не поступает. В логах пишет только то, что отправилось. 2. При переходе по адресу http://webmail.rocky-linux.ru/installer/ говорит, что страница не найдена. Куда и где копать?

  23. PORT STATE SERVICE
    25/tcp open smtp
    53/tcp open domain
    80/tcp open http
    143/tcp open imap
    443/tcp open https
    465/tcp open smtps
    587/tcp open submission
    993/tcp open imaps
    8080/tcp open http-proxy

    в дополнение к предыдущему вопросу, по портам вот так (это nmap на domain.tld)

  24. Настроил по вашей инструкции. Почта ходит. С почтового адреса main@domain.tld на test@new-domain.tld ходит. Обратно тоже ходит
    А вот когда отправляю с сайта domain.tld (laravel) через php artisan tinker получаю такое

    > Mail::raw('Hello World!', function($msg) {$msg->to('test@new-domain.tld')->subject('Test Email'); });

    Symfony\Component\Mailer\Exception\TransportException Expected response code "250/251/252" but got code "554", with message "554 5.7.1 : Relay access denied".

    Настройки .env и config/mail.php

    MAIL_MAILER=smtp
    MAIL_HOST=mail.domain.tld
    MAIL_PORT=25
    MAIL_USERNAME=info@domain.tld
    MAIL_PASSWORD=*************
    MAIL_ENCRYPTION=tls
    MAIL_FROM_ADDRESS=info@domain.tld
    MAIL_FROM_NAME="${APP_NAME}"

    'mailers' => [
    'smtp' => [
    'transport' => 'smtp',
    'host' => env('MAIL_HOST', 'mail.domain.tld'),
    'port' => env('MAIL_PORT', 25),
    'encryption' => env('MAIL_ENCRYPTION', 'tls'),
    'username' => env('info@domain.tld'),
    'password' => env('**************'),
    'timeout' => null,
    'auth_mode' => tsl
    ]
    ]

    Нет идей? Порты пробовал разные (25, 587, 465) это не решает. Ошибка та же (почтовые домены тестовые указаны)

    • Ошибка "Relay access denied" говорит о том, что отправка проходит без аутентификации, и почтовый сервер её отклоняет, заявляя, что он запрещает пересылку сообщений через себя.

  25. A можно его tls ( 1.0 and 1.1) не безопасных версий вообще отключить?

    map --script ssl-enum-ciphers -p 465 mailserver ─╯
    Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-22 12:48 PDT
    Nmap scan report
    Host is up (0.041s latency).

    PORT STATE SERVICE
    465/tcp open smtps
    | ssl-enum-ciphers:
    | TLSv1.0:
    | ciphers:
    | TLS_DH_anon_WITH_AES_128_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_AES_256_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_SEED_CBC_SHA (dh 2048) - F
    | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
    | TLS_ECDH_anon_WITH_AES_128_CBC_SHA (secp256r1) - F
    | TLS_ECDH_anon_WITH_AES_256_CBC_SHA (secp256r1) - F
    | compressors:
    | NULL
    | cipher preference: client
    | warnings:
    | Anonymous key exchange, score capped at F
    | Key exchange (secp256r1) of lower strength than certificate key
    | TLSv1.1:
    | ciphers:
    | TLS_DH_anon_WITH_AES_128_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_AES_256_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_SEED_CBC_SHA (dh 2048) - F
    | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
    | TLS_ECDH_anon_WITH_AES_128_CBC_SHA (secp256r1) - F
    | TLS_ECDH_anon_WITH_AES_256_CBC_SHA (secp256r1) - F
    | compressors:
    | NULL
    | cipher preference: client
    | warnings:
    | Anonymous key exchange, score capped at F
    | Key exchange (secp256r1) of lower strength than certificate key
    | TLSv1.2:
    | ciphers:
    | TLS_DH_anon_WITH_AES_128_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_AES_128_CBC_SHA256 (dh 2048) - F
    | TLS_DH_anon_WITH_AES_128_GCM_SHA256 (dh 2048) - F
    | TLS_DH_anon_WITH_AES_256_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_AES_256_CBC_SHA256 (dh 2048) - F
    | TLS_DH_anon_WITH_AES_256_GCM_SHA384 (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - F
    | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 (dh 2048) - F
    | TLS_DH_anon_WITH_SEED_CBC_SHA (dh 2048) - F
    | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_128_CCM (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_256_CCM (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 (secp256r1) - A
    | TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
    | TLS_ECDH_anon_WITH_AES_128_CBC_SHA (secp256r1) - F
    | TLS_ECDH_anon_WITH_AES_256_CBC_SHA (secp256r1) - F
    | compressors:
    | NULL
    | cipher preference: client
    | warnings:
    | Anonymous key exchange, score capped at F
    | Key exchange (secp256r1) of lower strength than certificate key
    |_ least strength: F

    • Можно, в статье есть пример настроек postfix:

      smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3
      smtp_tls_mandatory_protocols = !SSLv2,!SSLv3

      Добавьте туда !TLSv1, !TLSv1.1. Только учтите, что почтовые сервера очень консервативные системы. И какие-то более устаревшие версии серверов, а их много, не смогут вам отправить почту.

  26. Спасибо за статью.
    Осталось несколько вопросов.
    1) В конфигурациях указывать свой пароль или все таки слово "password" как написано?
    2)Лог файла для проверки почты, по пути /var/log/mail.log не существует, в какой момент он создается?

  27. Спасибо большое за статью

    Вот таое в логах . Почта не доходит . Что сделал не так ?
    Jul 21 12:15:15 mail postfix/smtpd[7154]: connect from mail-pf1-f172.google.com[209.85.210.172]
    Jul 21 12:15:15 mail postfix/smtpd[7154]: warning: SASL: Connect to private/dovecot-auth failed: No such file or directory
    Jul 21 12:15:15 mail postfix/smtpd[7154]: fatal: no SASL authentication mechanisms
    Jul 21 12:15:16 mail postfix/master[6851]: warning: process /usr/lib/postfix/sbin/smtpd pid 7154 exit status 1
    Jul 21 12:15:16 mail postfix/master[6851]: warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling
    Jul 21 12:16:17 mail postfix/smtpd[7158]: connect from mail-oa1-f51.google.com[209.85.160.51]
    Jul 21 12:16:17 mail postfix/smtpd[7158]: warning: SASL: Connect to private/dovecot-auth failed: No such file or directory
    Jul 21 12:16:17 mail postfix/smtpd[7158]: fatal: no SASL authentication mechanisms
    Jul 21 12:16:18 mail postfix/master[6851]: warning: process /usr/lib/postfix/sbin/smtpd pid 7158 exit status 1
    Jul 21 12:16:18 mail postfix/master[6851]: warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling
    Jul 21 12:17:58 mail postfix/anvil[7156]: statistics: max connection rate 1/60s for (smtp:209.85.210.172) at Jul 21 12:15:15
    Jul 21 12:17:58 mail postfix/anvil[7156]: statistics: max connection count 1 for (smtp:209.85.210.172) at Jul 21 12:15:15
    Jul 21 12:17:58 mail postfix/anvil[7156]: statistics: max cache size 1 at Jul 21 12:15:15

  28. Здравствуйте! Могу я использовать wildcard сертификат купленный для домена вместо let`s encrypt?

    • Да, конечно.

    • Спасибо за отличную статью! Потихоньку настроил на виртуалке и тренируюсь, почта работает, но споткнулся на шаге настройки Roundcube:
      Создаём конфигурацию виртуального хоста для roundcube.
      Сохраняем конфигурацию nginx в файл /etc/nginx/sites-available/webmail.rocky-linux.ru.conf и делаем символьную ссылку с него в /etc/nginx/sites-enabled
      Пытаюсь зайти на http://mail.localtest.com/installer/ - выдает:
      CONFIGURATION ERROR
      config.inc.php was not found

      В логе /web/sites/mail.localtest.com/www/logs/errors.log :

      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/skins/elastic/deps/bootstrap.min.css?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/skins/elastic/styles/styles.min.css?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/skins/elastic/styles/styles.min.css?s=1688483928)
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/skins/elastic/deps/bootstrap.min.css?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/plugins/jqueryui/themes/elastic/jquery-ui.min.css?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/program/js/jquery.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/plugins/jqueryui/themes/elastic/jquery-ui.min.css?s=1688483928)
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/program/js/jquery.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/program/js/common.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/program/js/app.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/program/js/common.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/program/js/app.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/plugins/jqueryui/js/jquery-ui.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/plugins/jqueryui/js/jquery-ui.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/plugins/jqueryui/js/i18n/jquery.ui.datepicker-ru.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/skins/elastic/ui.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/skins/elastic/deps/bootstrap.bundle.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/skins/elastic/ui.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/skins/elastic/deps/bootstrap.bundle.min.js?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/skins/elastic/images/logo.svg?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/skins/elastic/images/logo.svg?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost' in /web/sites/mail.localtest.com/www/program/lib/Roundcube/rcube_db.php on line 194 (GET /Installer/skins/elastic/images/favicon.ico?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329
      [04-Jul-2023 19:48:12 +0300]: PHP Error: config.inc.php was not found. (GET /Installer/skins/elastic/images/favicon.ico?s=1688483928)
      [04-Jul-2023 19:48:12 Europe/Kyiv] PHP Deprecated: preg_replace(): Passing null to parameter #3 ($subject) of type array|string is deprecated in /web/sites/mail.localtest.com/www/program/lib/Roundcube/bootstrap.php on line 329

      Я так понимаю, не хватает какого то файла конфигурации, но я вроде не пропустил ничего по инструкции.

      • У вас ошибка доступа к базе данных:
        DB Error: SQLSTATE[HY000] [1698] Access denied for user 'roundcube'@'localhost'
        Вторая ошибка:
        PHP Error: config.inc.php was not found.
        Нет доступа к конфигу. Первая скорее всего проистекает из второй. Либо с исходниками и конфигами что-то напутали, либо у веб сервера нет прав доступа к файлу config.inc.php.

        • Исходник скопировал в папку /web/sites/mail.localtest.com/www
          cp -R roundcubemail-1.5.3/* /web/sites/mail.localtest.com/www

          В том то и дело, что не могу найти, где мы создаем и настраиваем этот config.inc.php. У меня есть только /web/sites/mail.localtest.com/www/config/config.inc.php.sample.

          И базу для раундкуба мы вроде по инструкции до этого шага не создавали...только для postfix

          • Вдруг кому-то пригодится
            Решилось тем, что /web/sites/ДОМЕН/config.inc.php.sample скопировал в config.inc.php и указал там:
            $config['db_dsnw'] = 'mysql://roundcube:roundcube@localhost/roundcubemail';
            $config['enable_installer'] = true;
            $config['drafts_mbox'] = 'Drafts';
            $config['junk_mbox'] = 'Junk';
            $config['sent_mbox'] = 'Sent';
            $config['trash_mbox'] = 'Trash';
            $config['create_default_folders'] = true;

            Этого нет в инструкции, но может это очевидно для остальных. Для меня было не очевидно)

            и так же в инструкции создаем базу, когда нас уже пустило в меню Инсталлера Roundcube, но у меня была вышеописанная ошибка, пока не создал базу вручную:
            > CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
            > GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'roundcube';

  29. Степан

    Очень грамотно написана статья. Автору респект. Вопрос - а можно nginx заменить apache? У меня стоит веб сервер и хочу добавить почту. Надо что то поменять в етом описание? Извините об плохом язике я из болгарии.

    • Конечно можно. Вы можете использовать любой веб сервер, который умеете настаивать. Нет разницы Nginx или Apache.

      • Степан

        У меня стоит Ubuntu 22.04. Есть какая то разница или все относится 1:1?

        • Могут быть незначительные отличия в каких-то путях или названиях пакетов. А может и вообще не будет. Я не проверял на Ubuntu, но обычно с Debian там минимальные отличия.

  30. Сегрей

    Здравствуйте.
    Огромное спасибо за подробную статью. Все получилось. Хочу добавить свои пять копеек.

    1. Делал на php 8.1. У php 7.4 кончился цикл поддержки. Никаких дополнительных действий не требуется, просто везде в статье меняем php7.4 на php8.1 и все.
    2. Параметр postfix (main.cf): smtpd_client_connection_limit_exceptions устарел. Начиная с postfix v2.2 используется smtpd_client_event_limit_exceptions. Собственно в Вашем конфиге он также указан.
    3. В opendkim.conf: параметр KeyFile - не нужен, если используется KeyTable (в ней перечисляются все виртуальные домены построчно).
    4. А вот это замечание важное! В инструкции по установке roundcube https://github.com/roundcube/roundcubemail/wiki/Installation#protect-your-installation четко прописано требование по ограничению доступа к каталогам:
    /config
    /temp
    /logs
    Roundcube для этого ограничения использует файл .htaccess, но это файл apache, nginx с ним не работает. Чтобы в nginx ограничить доступ к этим каталогам, нужно в /etc/nginx/sites-available/webmail.rocky-linux.ru.conf добавить такое ограничение (можно в самый конец конфига):
    location ~ /(config/|temp/|logs/) {
    deny all;
    return 404;
    }
    Ну и:
    sudo nginx -s reload
    Для проверки работы ограничения можно к примеру попробовать скачать errors.log из каталога logs:
    http://webmail.rocky-linux.ru/logs/errors.log
    Если стачивается, то значит ограничение не работает и кулхацкеры могут копаться в этих каталогах.

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

    warning: mysql:/etc/postfix/mysql_virtual_alias_maps.cf: query failed: Illegal mix of collations (latin1_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for operation '='

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

      • Аноним

        Понял спасибо

        • В названии ящика напечатали русскую букву... У меня это еще в рассылку с 1с ушло, и повешивало каждые 5 минут почтовый сервер... На будущее перевел таблицы БД в utf8mb4_general_ci.

          • А какая кодировка была? Сейчас чаще всего по умолчанию utf8mb4_general_ci и используется.

  32. Тренируюсь на виртуалке, поднял ubuntu 20 и вымышленный домен mail.com, не могу добиться чтобы почта хранилась в формате /var/mail/mail.com/user, она все равно создает каталог /var/mail/mail.com/user@mail.com
    В postfix прописано
    $CONF['domain_path'] = 'YES';
    $CONF['domain_in_mailbox'] = 'NO';
    В dovecot прописано
    mail_location = maildir:/var/mail/%d/%u
    В базе данных postfix при заведении почты создается запись maildir - mail.com/user, local_part - user
    Отправляю с консоли письмо на эту почту "echo "Test text" | mail -s "Test title" user@mail.com (перед отправкой каталог user еще не создан) и создается mail.com/user@mail.com.
    Параметры YES и NO пробовал и так и так выставлять, ничего не получается.
    Если подключать почту через клиент Thunderbird она все равно создается в формате mail.com/user@mail.com
    Могли бы помочь?

    • Не знаю, чем помочь. Я сам всегда использую директории для ящиков вида user@mail.com. Но когда тестировал только имя user, у меня получалось. Я видел чужие сервера с работающей настройкой такого именования.

      • Спасибо за быстрый ответ, с форматом mail.com/user я так и не разобрался, перешел к установке roundcubemail сделал все по статье, инициировал базу, вошел в ящик, входящие есть, отправить с него ничего не могу, при отправке "SMTP ошибка (-1): Сбой соединения с сервером". Все было по статье с портом 24, localhost и нужными пунктами.
        В конфиге /var/www/html/roundcubemail/config/config.inc.php
        $config['default_host'] = 'localhost';
        $config['smtp_port'] = 25;
        $config['support_url'] = '';
        в логе roundcubemail/log/errors.log
        05-Jun-2023 16:29:07 +0300]: PHP Error: Connection refused (POST /roundcubemail/?_task=mail&_unlock=loading1685971736081&_framed=1&_action=send)
        [05-Jun-2023 16:29:07 +0300]: PHP Error: Failed to connect socket: Connection refused (POST /roundcubemail/?_task=mail&_unlock=loading1685971736081&_framed=1&_action=send)
        [05-Jun-2023 16:29:07 +0300]: SMTP Error: Connection failed: Failed to connect socket: Connection refused in /var/www/html/roundcubemail/program/lib/Roundcube/rcube.php on line 1778 (POST /roundcubemail/?_task=mail&_unlock=loading1685971736081&_framed=1&_action=send)
        Через Thunderbird с авторизацией по TLS письма приходят и отправляются.

        • Скорее всего скрипт php не может подключиться к smtp серверу для отправки. Ошибка "SMTP ошибка (-1): Сбой соединения с сервером" намекает на это. По какой причине, не знаю. Попробуйте вместо localhost указать тот же IP адрес, по которому работает в Thunderbird.

  33. Кто столкнулся такой проблемой
    SASL: Connect to private/dovecot-auth failed: No such file or directory
    fatal: no SASL authentication mechanisms

    меняем в конфигах dovecot и postfix значение private/dovecot-auth на private/auth

  34. Владимир

    Автор подскажите пожалуйста.
    Как говорил ранее, сервер по Вашей инструкции настроил за несколько часов, все замечательно.
    Теперь возникла необходимость поменять ip-адрес сервера и при смене перестает работать отправка писем.
    Пересмотрел все конфигурационные файлы, ни где не привязаны ip-адреса, все по именам и записям в DNS.

    Может я чего не понимаю? Посоветуйте в какую сторону копать

  35. Помогите разобраться, автор подскажи что за IP адреса
    93.175.56.122 none
    77.221.87.91 encrypt protocols=TLSv1

    Желательно подробнее, я видел выше отвечали но как-то не совсем понятно, какие адресу тут указывать.
    В зорание спасибо.

    • Это необязательная настройка. Данные ip адреса приведены для примера. Тут указано, что для конкретных ip адресов можно использовать разные версии tls протокола, либо вообще не использовать. Если не понимаете, о чём тут речь, то можете пропустить этот параметр и ничего не настраивать. Файл можно оставить пустым или вообще закомментировать его в файле настроек.

  36. Огромное спасибо! Все завелось несмотря на то, что из всей связки знал только Nginx и DNS :)))
    Словил пару ошибок только потому, что пути и Nginx другой использовал, но эт сам виноват.

    • Отлично, спасибо за информацию. А то тут полно людей с ошибками, которых быть не должно. Если аккуратно повторить по статье, то всё получится.

  37. Здравствуйте!
    Возможно, вы мне подскажете как сделать. Развернул почтовый и веб серверы в виртуалках, всё настроил, всё работает. Остались детали, но это уже потом. Не могу сообразить как настроить сбор почты в postfixadmin, если почтовый сервер (где postfix, dovecot и пользователь vmail) и веб-сервер (апач + пхп + postfixadmin). Серверы имеют разные локальные адреса. Можно, конечно, просто на почтовом настроить fetchmail, но это не интересно, хочется через postfixadmin :-)

    • А в чём конкретно проблема и задача? Я не понял из описания. Сбор почты откуда нужен? И почему важно, что у серверов разные локальные адреса.

  38. С таким конфигом на CentOS 7 при запуске сервиса ругается

    Apr 26 15:45:53 mail postfix[9367]: fatal: chdir(/usr/lib/postfix/sbin): No such file or directory

    сервис не старует

    • Изменили на daemon_directory /usr/libexec/postfix
      сервис запустился
      При попытке авторизоватся почтовым клиентом в логе

      Apr 26 16:30:40 mail dovecot: imap-login: Login: user=, method=PLAIN, rip=92.39.XXX.XX, lip=10X.7X.1X4.38, mpid=10759, TLS, session=
      Apr 26 16:30:40 mail dovecot: imap(username@xxxx.it): Error: Mail access for users with UID 1100 not permitted (see first_valid_uid in config file, uid from userdb lookup).
      Apr 26 16:30:40 mail dovecot: imap(username@xxxx.it): Error: Invalid user settings. Refer to server log for more information.

      В каком месте ошибка настройки может быть?

  39. Андрей

    Добрый день. Настроил на одном сервере 20 доменов и около 200 ящиков (общее количество). Делал всё разом. Иногда происходит подвисание подключения к серверу, минут на 5. Потом опять всё хорошо работает. В момент подвисания захожу на сервер и смотрю htop. Никаких "запредельных" нагрузок нет. С чем это может быть связано?

    • Подвисание кого именно и в какой момент? Подключение к самому почтовому серверу через почтовый клиент, или подвисание веб клиента в момент создания там ящиков? Связно это может быть с чем угодно, начиная от сетевых проблем, вообще не связанных с сервером и заканчивая какими-то встроенными лимитами на подключения на самом сервере. Надо начинать с просмотра логов участвующих сервисов.

      • Андрей

        Подвисание (долгое подключение) к самому почтовому серверу через почтовый клиент, либо в web морде. Несколько раз подловил, что подвисание распространяется как на почтовый клиент, так и на web морду, одновременно. Сервер виртуальный, другие виртуалки такой проблемой не страдают. В /var/log/php8.1-fpm.log нашел записи (сыпались каждые 20-30 мин):

        WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

        Подправил файл /etc/php/8.1/fpm/pool.d/www.conf (использовал калькулятор https://spot13.com/pmcalculator/) и теперь этих WARNING не вижу. Почта стала вроде как стабильней, подвисаний меньше гораздо, но всё же наблюдаются. Не могу найти в логах ошибки, куча записей в /var/log/mail.log

        • Дело не в php-fpm. Приведённый лог это не ошибка. Раз одновременно подвисают подключения по imap и http, значит проблема не в конкретных сервисах, а либо в сети, либо в самой системе или виртуальной машине. Неплохо бы постоянный мониторинг настроить, тогда будет более предметный анализ. А так это гадание на кофейной гуще. Нужно настраивать мониторинг гипервизора и всех виртуальных машин. Тогда можно будет более точно диагностировать проблему. А сейчас это всё пальцем в небо. У вас дисковая подсистема какая? Подобные тормоза похожи на то, что в определённое время диски подтупливают и всё тормозит. У вас там не zfs случайно?

  40. Здравствуйте, проблема с DKIM. Настройка по инструкции, на сайте dkimcore.org ошибка "This doesn't seem to be a valid RSA public key: RSA.xs:178: OpenSSL error: bad base64 decode at blib/lib/Crypt/OpenSSL/RSA.pm (autosplit into blib/lib/auto/Crypt/OpenSSL/RSA/new_public_key.al) line 91. "

    • Собственно, в тексте ошибки всё написано. То, что вы скопировали, не является RSA public key. Так как я не вижу, что именно вы копировали, подсказать нечего. Но утилита DKIM генерирует рабочие ключи. Так что проверяйте внимательнее то, что вы копируете в DNS.

      • Аноним

        v=DKIM1; h=sha256; k=rsa;
        p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvA7mFyckkLePm1YHu+5F5RZ89X19FWHC7JGPH4RtDeFqx6UaNWBuvNAwq/qRx0dtXPOp00cVlQWUb1P/pDrXr5G4/OJJUxlD2t4XGah0u5LPDMj9V5PQifj5ybnrKLUq2Z/EJs1zU+hnoGQ3AtIntDOQWTsRs2wbJFPrKVc4xIuVZr1w3OhxV/O52Jn2oQRXh59iqCicL2fRhC

      • Аноним

        mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
        "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvA7mFyckkLePm1YHu+5F5RZ89X19FWHC7JGPH4RtDeFqx6UaNWBuvNAwq/qRx0dtXPOp00cVlQWUb1P/pDrXr5G4/OJJUxlD2t4XGah0u5LPDMj9V5PQifj5ybnrKLUq2Z/EJs1zU+hnoGQ3AtIntDOQWTsRs2wbJFPrKVc4xIuVZr1w3OhxV/O52Jn2oQRXh59iqCicL2fRhC"

      • Ниже на писал что выводит и что я в txt домена добавляю

  41. Владимир

    Добрый день. Настраивал переход с яндекс почты на свой почтовый сервер по этой инструкции. Все делал по шагам, ошибок не показывалось, менял только на свои имена.
    Пытаюсь через thunderbird добавить ящик, а он очень долго крутит и пишет снизу "отправка регистрационной информации...". После чего в логе /var/log/dovecot/info.log появляется:

    Apr 17 16:10:23 imap-login: Info: Disconnected (auth service reported temporary failure): user=, method=PLAIN, rip=127.0.0.1, lip=127.0.0.1, secured, session=
    Apr 17 16:20:48 imap-login: Info: Disconnected: Inactivity during authentication (auth failed, 2 attempts in 180 secs): user=, method=LOGIN, rip=195.191.166.63, lip=195.191.166.125, TLS, session=

    Еще при попытке отправить письмо, на этот ящик в логе /var/log/mail.log пишется

    Apr 17 16:44:31 pochta postfix/smtpd[6171]: connect from mxout1.rambler.ru[81.19.78.100]
    Apr 17 16:44:31 pochta postfix/smtpd[6171]: Anonymous TLS connection established from mxout1.rambler.ru[81.19.78.100]: TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)
    Apr 17 16:44:31 pochta postfix/smtpd[6171]: DCA838743D6C: client=mxout1.rambler.ru[81.19.78.100]
    Apr 17 16:44:31 pochta postfix/cleanup[6175]: DCA838743D6C: message-id=
    Apr 17 16:44:31 pochta opendkim[678]: DCA838743D6C: mxout1.rambler.ru [81.19.78.100] not internal
    Apr 17 16:44:31 pochta opendkim[678]: DCA838743D6C: not authenticated
    Apr 17 16:44:31 pochta opendkim[678]: DCA838743D6C: DKIM verification successful
    Apr 17 16:44:31 pochta opendkim[678]: DCA838743D6C: s=mail d=rambler.ru a=rsa-sha256 SSL
    Apr 17 16:44:32 pochta postfix/qmgr[5385]: DCA838743D6C: from=, size=2898, nrcpt=2 (queue active)
    Apr 17 16:44:32 pochta postfix/smtpd[6171]: disconnect from mxout1.rambler.ru[81.19.78.100] ehlo=2 starttls=1 mail=1 rcpt=1 data=1 quit=1 commands=7

    И в папке /mnt/mail не создается папка для почтового ящика. Что может быть не так?

    • Я так сходу не скажу, в чём ошибка, но вы явно наошибались, и не раз. Тут ошибка и в dovecot, который отвечает за клиентов, и в postfix, который отвечает за приём почты. Явные ошибки и там, и там, причём на первый взгляд не связанные друг с другом.

      • Владимир

        Делал по инструкции все. Все конфиги перепроверил по 3 раза,не понимаю,где может быть ошибка. Сам постфикс работает,учётки создаются. В базе видны они.

    • Владимир

      Решил проблему. При создании БД я указывал свои пароли, а не password. И даже заменив их везде, почта не работала. Вернул на password и почта сразу заработала.

  42. Василий

    Здравствуйте. При настройке roundcube столкнулся со следующей ошибкой

    "nginx -t && nginx -s reload
    nginx: [emerg] unknown log format "full" in /etc/nginx/sites-enabled/webmail.site.ru.conf:7
    nginx: configuration file /etc/nginx/nginx.conf test failed
    "

    погуглил, понял что ругается на формат записи access_log , но так и не понял как выводить полное логирование?

    • Уберите это слово full из конфигурации. Поправлю статью. Это из моего конфига взято, где я отдельно добавляю полный формат лога, которого нет в изначальной установке nginx.

  43. Алексей

    Добрый день. Настроил по Вашей статье, напоролся на несколько штанг. Например: почтовый клиент не подключается к учеткам, он находит конфигурацию , но логин/пароль не принимает. В различных вариантах и со STARTLS и с обычным паролем. При этом почта на ящик прошла, это видно по файлу почты. Так-же roundcube не получает учетные записи почты (таблица users в бд пустая) - это куда копнуть ?

    • Я не знаю. Если делать чётко по статье, то всё получится. Десятки людей уже настроили по ней. За почтовые клиенты отвечает dovecot. Где-то в его настройках ошибка.

      • Алексей

        Тут я уже разобрался - виноват был микротик :)

        • Алексей

          Однако - настроив по статье и проверив по mail-checker (получил оценку 6,9/10, без SPF) столкнулся с таким моментом:

          pr 15 14:28:32 mail postfix/smtp[9870]: Anonymous TLS connection established to ***.ru[xx.xx.xx.xx]:25: TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)
          Apr 15 14:28:33 mail postfix/smtp[9870]: E23AFE1F23: to=, relay=***.ru[xx.xx.xx.xx]:25, delay=1.5, delays=0.03/0/0.39/1.1, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 628C920003)
          Apr 15 14:28:33 mail postfix/qmgr[5833]: E23AFE1F23: removed

          То есть письмо входящее сразу удаляется. На стороне отправляющего такое видно:

          This is the mail system at host ***.ru.

          I'm sorry to have to inform you that your message could not
          be delivered to one or more recipients. It's attached below.

          For further assistance, please send mail to postmaster.

          If you do so, please include this problem report. You can
          delete your own text from the attached returned message.

          The mail system

          : unknown user: "user"

          То есть странная ситуация
          От меня с этого ящика почта ходит - меил-тестер и другие мои ящики это подтверждают
          но на этот ящик почта не ходит с ошибкой - неизвестный пользователь - это вообще как так ? :( Не могу сообразить, может ли это быть проблема с mydomains ?

  44. Константин

    Добрый день, спасибо за статью, очень актуально сейчас. Я все настроил, но не могу понять почему почта создается с адресом user@localhost в профиле roundcube, при таком адресе по умолчанию почта не отправляется, если вручную в настройках поменять на user@mydomen.ru все работает.

  45. Алексей

    Владимир, здравствуйте! Подскажите как настроить второй почтовый домен на этой связке?

    • Через postfixadmin добавляете ещё один домен и всё. Больше ничего делать не надо, кроме добавления ещё одного домена в dkim. Там по аналогии с первым доменом создаются ключи и добавляется ещё одна строка с новым доменом в файл с настройкой.

      • Алексей

        В DNS зоне этого домена записи указывающие на IP адрес сервера прописать? В opendkim.conf закомментировать строку KeyFile?

        • Алексей

          Всё заработало. KeyFile закомментировал, в DNS зоне нужные параметры прописал. Благодарю за отличную статью!

  46. подскажите пожалуйста, как сделать алиас all@domain.ru -->> "все ящики@domain.ru"

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

      • спасибо

      • Здравствуйте тёзка!
        я таки нашел способ создать адиас all@my.domain ::
        1. в postfixadmin выдернул CSV списка всех ящиков
        2. в exel откусил список самих адресов
        3. создал алиас all@ и скопипастил туда весь этот список
        3.1 Есть одна хитрость/баг! При добавлении этого списка ящиков в алиас, если имя ящика слишком длинное, нужно само окно в postfixadmin растянуть пошире(там есть такая возможность), что бы все адреса влезли построчно.

        Извращение конечно. нужно не забывать добавлять новые ящики, но работает :)

  47. Андрей

    Добрый день. Статья просто класс! Но возникла проблема:
    До настройки DKIM в web почте в настройках профиля была указана почта вида user@site.ru. А после DKIM пользователь стал user@localhost. Но почта отправляется, однако письмо от него приходит с именем отправителя user@localhost.
    Сайт https://dkimcore.org/ говорит "This is a valid DKIM key record"
    Но на Gmail нет пункта DKIM у входящего письма и в mail.log есть записи:
    email opendkim[713434]: 1383A7C012A: no signing table match for 'user@localhost'
    email opendkim[713434]: 1383A7C012A: no signature data

    • Андрей

      Кстати, символ CR отсутствует.
      root@email:/etc/postfix/dkim# cat -A signingtable
      *@site.ru mail._domainkey.site.ru$
      Доменное имя у меня mail.site.ru, а сервер в локальной сети под названием email.

      • Андрей

        Проверка дает следующий результат:
        root@email:/etc/postfix/dkim# opendkim-testkey -vvv -d site.ru -s mail -k /etc/postfix/dkim/mail.site.ru.private opendkim-testkey: using default configfile /etc/opendkim.conf
        opendkim-testkey: /etc/postfix/dkim/mail.site.ru.private: WARNING: unsafe permissions
        opendkim-testkey: key loaded from /etc/postfix/dkim/mail.site.ru.private
        opendkim-testkey: checking key 'mail._domainkey.site.ru'
        opendkim-testkey: key not secure
        opendkim-testkey: key OK

    • Андрей

      Gmail:
      Исходное сообщение
      Идентификатор сообщения
      Создано: 6 апреля 2023 г. в 13:43 (доставлено через 1 секунду)
      От: user
      Кому: GoogleUser
      Тема: MailTest
      SPF: NEUTRAL с IP-адресом 91.109.201.210

      • Андрей

        Удалились данные в угловых скобках, заменил на кавычки одинарные.
        Исходное сообщение
        Идентификатор сообщения 'aa8307db452e8d7804d2130ce3@mail.site.ru'
        Создано: 6 апреля 2023 г. в 13:43 (доставлено через 1 секунду)
        От: user 'user@localhost'
        Кому: GoogleUser 'googleuser@gmail.com'
        Тема: MailTest
        SPF: NEUTRAL с IP-адресом 91.109.201.210

    • Андрей

      Прошу прощения. Всё хорошо. Я логинился в почте не по user@site.ru, а просто user. Мой косяк.
      А как убрать данный доступ? Что бы логиниться в почте только по имени пользователя было невозможно?

  48. Доброго времени суток!
    Автору спасибо за мануал!
    В связи со сроком до 17.04.23 по яндексу и его платными ящиками, сегодня поднял свой сервер за 4 часа с нуля.

    ЗЫ: нашел ошибку в конфиге приведенном для настройки roundcube. Мне он не нужен, но для посмотреть поставил.
    в конфигурационном файле для ngnix приведены пути для логов:
    access_log /web/sites/webmail.rocky-linux.ru/logs/access.log full;
    error_log /web/sites/webmail.rocky-linux.ru/logs/error.log;

    перед /logs/ не хватает /www
    это если следовать строго статье.

  49. В статье указан Proxmox Mail Gateway, хотелось бы увидеть реальный опыт использования и настройки. Тк в интернете очень мало информации как его скрестить с Postfix (и тд). Сейчас Mail Gateway крутится на виртуалке, если я прокидываю 25 порт на Proxmox(а с почтового сервера снимаю), он получает письмо и ничего с ним не делает, как его заставить пересылать на почтовый сервер? Опять же, если 25 порт снят с самой почты, то и письма не уходят. Замкнутый круг, поделитесь опытом!

    За статью спасибо, все поднялось на ура.

    • Логика с Proxmox Mail Gateway очень простая. Вы настраиваете приём почты на него, а он всю почту пересылает на ваш почтовый сервер. Вот и всё. Там есть такая настройка. Сам почтовый сервер трогать вообще не надо. Отправлять почту можно напрямую с почтового сервера мимо Proxmox Mail Gateway. То есть PMG только принимает и фильтрует входящую почту.

      • PMG получает письмо, но дальше оно никуда не идет: (192.168.0.63 это PMG)
        Apr 5 22:36:34 srv-email postfix/smtpd[13229]: NOQUEUE: reject: RCPT from unknown[192.168.0.63]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.0.63]; from= to= proto=ESMTP helo=
        Apr 5 22:36:34 srv-email postfix/smtpd[13229]: disconnect from unknown[192.168.0.63] ehlo=1 mail=1 rcpt=0/1 data=0/1 rset=1 quit=1 commands=4/6

        Ничего понять не могу.

  50. Если устанавливать rounbcube в стандартную директорию /var/www/htm, то на него уже будет действовать правила lnginx (двойная аунтификация). Это не слишком удобно для пользователей, вопрос в следующем - как поменять конфиг, что бы исключить только rounbcube.

    server {
    listen 80 default_server;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html index.php;
    server_name _;

    auth_basic "Administrator’s Area";
    auth_basic_user_file /etc/nginx/.htpasswd;

    Я пробовал добавить дальше:

    location /var/www/html/webmail {
    auth_basic off;
    }

    Но это не помогло, все равно выскакивает двойная аунтификация. Как правильно поправить конфиг? спасибо

    • Директива auth_basic может работать как на весь сервер сразу, так и на отдельные location. Соответственно, перенесите auth_basic в тот location, где она нужна. И тогда она будет действовать только там.

  51. Николай

    Подскажите, а как заполнить файты sender_bcc_maps и recipient_bcc_maps, если почтовый сервер обслуживает несколько доменов?

    • Не очень понял вопрос. Пример заполнения есть в статье. Если доменов несколько, то просто по одной строчке для каждого домена.
      @domain1.ru admin@domain1.ru
      @domain2.ru admin@domain2.ru
      и т.д.

      • Николай

        Спасибо за ответ.
        Пока сделал проще, добавил в main.cf
        always_bcc = all@example.ru
        Неудобно только что вход и выход валит в одну почту.

  52. Владимир, здравствуйте. Небольшой вопрос по спам фильтрам, ваш список многолетней калькуляция, вставлять надо в main.cf? В самый конец?

  53. Приветствую! Почта заработала на ура :) сейчас в процессе установки roundcubemail. Немного не понятно, дошел до команды cp -R roundcubemail-1.5.3/* /web/sites/webmail.тут мой домен.ru/www и мне пишет - cp: указанная цель '/web/sites/webmail.тут мой домен.ru/www' не является каталогом, если я убираю звездочку /*, то пишет - cp: невозможно создать каталог '/web/sites/webmail.тут мой домен.ru/www': Нет такого файла или каталога.
    Если не сложно, проясните этот момент.

    • Я так понимаю стандартная установка идет /var/www/html/rounbcube?

      • Николай

        Создайте отдельный каталог для roundcube и отдельную конфигурацию в nginx
        Дефолтная конфигурация обращается в /var/www/html/, этого делать не нужно

  54. Евгений

    Добрый вечер!
    Подскажите плиз. Есть сервер с IredMail все работает отлично. Есть фирма у нее почта была у яндекс бизнес её перенесли на biz.mail, но сервер с iredmail пытается отправлять на яндекс письма

    • Почтовый сервер отправляет письма туда, где указан MX сервер в DNS. Так что проверяйте DNS записи. Возможно, они ещё не обновились для сервера iredmail, поэтому он отправляет по старым записям.

  55. Андрей

    Добрый день! не подскажите по ошибкам, куда копать:
    postfix/submission/smtpd[4742]: warning: connect #10 to subsystem private/proxymap: Connection refused
    postfix/master[4728]: warning: process /usr/lib/postfix/sbin/smtpd pid 4742 exit status 1
    warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling

    • Судя по ошибке, проблема с proxymap, но я её не использую в своей конфигурации. Вы уверены, что всё настроили по этой статье?

      • Андрей

        Да, делал все по статье. Только ставил все на ubuntu, если не получится победить, то попробую тоже самое с Debian.

      • Андрей

        Переставил на Дебиан, теперь такая ошибка:

        Apr 2 00:18:59 srv-email postfix/smtpd[26014]: fatal: no SASL authentication mechanisms
        Apr 2 00:18:59 srv-email postfix/smtpd[26012]: connect from mail-yb1-f180.google.com[209.85.219.180]
        Apr 2 00:18:59 srv-email postfix/smtpd[26012]: warning: SASL: Connect to private/dovecot-auth failed: No such file or directory
        Apr 2 00:18:59 srv-email postfix/smtpd[26012]: fatal: no SASL authentication mechanisms
        Apr 2 00:19:00 srv-email postfix/master[25821]: warning: process /usr/lib/postfix/sbin/smtpd pid 26010 exit status 1
        Apr 2 00:19:00 srv-email postfix/master[25821]: warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling
        Apr 2 00:19:00 srv-email postfix/master[25821]: warning: process /usr/lib/postfix/sbin/smtpd pid 26011 exit status 1
        Apr 2 00:19:00 srv-email postfix/master[25821]: warning: process /usr/lib/postfix/sbin/smtpd pid 26013 exit status 1
        Apr 2 00:19:00 srv-email postfix/master[25821]: warning: process /usr/lib/postfix/sbin/smtpd pid 26014 exit status 1
        Apr 2 00:19:00 srv-email postfix/master[25821]: warning: process /usr/lib/postfix/sbin/smtpd pid 26012 exit status 1
        Apr 2 00:20:00 srv-email postfix/smtpd[26032]: connect from unknown[46.148.40.164]

        • Андрей

          Не знаю почему, но у меня нету папок dovecot-auth и dovecot-lmtp в директории /var/spool/postfix/private.
          Можно ли их самому создать?

          • Андрей

            Вроде как сам разобрался. еще такой вопрос - Это нормально что в логах постоянно такая фигня? И не останавливается.

            Apr 2 04:04:06 srv-email postfix/smtpd[1173]: warning: hostname net6-ip229.linkbg.com does not resolve to address 87.246.7.229: Name or service not known
            Apr 2 04:04:06 srv-email postfix/smtpd[1173]: connect from unknown[87.246.7.229]
            Apr 2 04:04:06 srv-email postfix/smtpd[1174]: warning: unknown[46.148.40.164]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
            Apr 2 04:04:06 srv-email postfix/smtpd[1174]: disconnect from unknown[46.148.40.164] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:07 srv-email postfix/smtpd[1209]: warning: unknown[87.246.7.229]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
            Apr 2 04:04:07 srv-email postfix/smtpd[1209]: disconnect from unknown[87.246.7.229] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:08 srv-email postfix/smtpd[1191]: connect from unknown[46.148.40.164]
            Apr 2 04:04:10 srv-email postfix/smtpd[1165]: warning: unknown[80.94.95.205]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
            Apr 2 04:04:11 srv-email postfix/smtpd[1165]: disconnect from unknown[80.94.95.205] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:15 srv-email postfix/smtpd[1174]: connect from unknown[80.94.95.205]
            Apr 2 04:04:19 srv-email postfix/smtpd[1173]: warning: unknown[87.246.7.229]: SASL LOGIN authentication failed: Connection lost to authentication server
            Apr 2 04:04:19 srv-email postfix/smtpd[1209]: warning: hostname net6-ip229.linkbg.com does not resolve to address 87.246.7.229: Name or service not known
            Apr 2 04:04:19 srv-email postfix/smtpd[1209]: connect from unknown[87.246.7.229]
            Apr 2 04:04:19 srv-email postfix/smtpd[1173]: disconnect from unknown[87.246.7.229] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:20 srv-email postfix/smtpd[1191]: warning: unknown[46.148.40.164]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
            Apr 2 04:04:20 srv-email postfix/smtpd[1191]: disconnect from unknown[46.148.40.164] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:22 srv-email postfix/smtpd[1165]: connect from unknown[46.148.40.164]
            Apr 2 04:04:22 srv-email postfix/smtpd[1173]: connect from unknown[141.98.10.151]
            Apr 2 04:04:23 srv-email postfix/smtpd[1174]: warning: unknown[80.94.95.205]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
            Apr 2 04:04:23 srv-email postfix/smtpd[1174]: disconnect from unknown[80.94.95.205] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:25 srv-email postfix/smtpd[1173]: warning: unknown[141.98.10.151]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
            Apr 2 04:04:25 srv-email postfix/smtpd[1173]: disconnect from unknown[141.98.10.151] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:26 srv-email postfix/smtpd[1209]: warning: unknown[87.246.7.229]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
            Apr 2 04:04:27 srv-email postfix/smtpd[1209]: disconnect from unknown[87.246.7.229] ehlo=1 auth=0/1 rset=1 quit=1 commands=3/4
            Apr 2 04:04:28 srv-email postfix/smtpd[1191]: connect from unknown[80.94.95.205]

          • Эдвард

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

  56. сергей

    Упустил несколько строк!

    MariaDB [(none)]> CREATE USER 'postfixadmin'@'localhost' IDENTIFIED BY 'Strong_Password';
    MariaDB [(none)]> CREATE DATABASE postfixadmin;
    MariaDB [(none)]> GRANT ALL PRIVILEGES ON postfixadmin.* TO 'postfixadmin'@'localhost';
    MariaDB [(none)]> FLUSH PRIVILEGES;
    MariaDB [(none)]> \q

  57. Доброго времени суток!

    Возможно кто-то реализовывал такую задачу, нужно на одном почтовом сервере создать условно 20 доменов, с разным объемом дисковой квоты.

    Основным видится такой вариант, что для каждого домена будет свой диск, вопрос только в том как это реализовать в postfix?

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

    • В описанном в статье решении есть возможность задавать дисковые квоты для ящиков. Или нужно именно для всего домена в сумме, без привязки к ящикам?

      • Василий

        из статьи непонятно, как включить квоты для ящиков, там написано только что dovecot это умеет

    • если брать адресацию статьи - то мб монтировать каждый диск к своему домену?
      mount /dev/sdX /mnt/mail/domain1.ru
      mount /dev/sdY /mnt/mail/domain2.ru
      mount /dev/sdZ /mnt/mail/domain3.ru
      ну и тд

  58. Есть варианты без обратной зоны?
    От провайдера приходит такая хрень: ppp91-122-37-217.pppoe.avangarddsl.ru и менять не собирается, т.к. я физик. Максимум белый айпишник выдал.

    • Это не вариант. Такую ptr запись большая часть почтовиков будет либо сразу отбрасывать и не принимать почту, либо помечать, как спам. Это признак домашних сетей с динамическими ip адресами. Для почтового севера это не подходит.

      • А как добавить к такой связке внешние почтовики в виде VPS с правильными ptr записями, чтобы почта курсировала как входящая так и исходящая, отправляясь и принимаясь этими VPS. Клиенты же обоих доменов логинились на почтовый сервер с просто белым IP и кривой ptr записью. С какой стороны к этому подступиться?

        • Проще всего на VPS поднять postfix с простой конфигурацией, которая всю входящую посту будет пересылать на ваш основной почтовый сервер. А на основном почтовом сервере настроить сервер на VPS в качестве релея отправки. Между двумя почтовыми серверами можно настроить VPN, чтобы они общались друг с другом по ней.

  59. Добрый день.

    Спасибо за статью. Часто использую ваши наработки, т.к. мало собственного опыта.
    Есть два вопроса не связанных напрямую с настройкой почтового сервера:
    1. Какие порты нужно пробросить, если мой почтовый сервер находится за роутером и у него локальный ip
    2. Если сайт с доменным именем http://www.primer.ru находится у провайдера за другим ip, то после добавления мх записей не отвалится ли сайт?
    3. Когда идёт речь о настройке полного доменного имени у сервера почты имеется в веду http://www.primer.ru или доменное имя AD?

    • 1. Для работы почтового сервера как минимум необходимо открыть 25-й порт. По нему почтовые сервера общаются между собой. А вот все остальные порты зависят от того, где находятся пользователи и по каким протоколам они будут работать с почтовым сервером. Если пользователи все в локальной сети, то для работы почтового сервера достаточно будет только 25-го порта.
      2. Работа сайта от MX записей вообще никак не зависит. Если не будете трогать A запись самого сайта, то с ним ничего не случится.
      3. Имеется ввиду fqdn имя, то есть, например, mail.primer.ru, без http.

  60. Владимир, приветствую!
    Отличная статья, очень помогла в настройке.
    Есть одна проблема - не работают фильтры managesieve. Добавляю фильтр через веб морду roundcube, все сохраняется без ошибок. Сам фильтр добавляется в путь_к_ящику/.sieve/managesieve.sieve. При получении писем, к которым должен применяться фильтр, этого не происходит. Ошибок в логах dovecot нет, кроме такой -
    managesieve(xxxx@xxxxx.ru): Error: stat(/mnt/mail/xxxxx.ru/xxxx@xxxxx.ru/.dovecot.sieve/tmp) failed: Not a directory
    Как я понял, это не принципиальная ошибка, dovecot хочет передать файл символьную ссылку на .sieve/manage.sieve
    Подскажите пжл. куда копать?

    • По идее ошибки быть не должно. Наверное из-за неё и не работает. Я никогда не сталкивался с тем, что фильтр не работает. Настраиваю, как описано. Сразу проверяю. Фильтр работает. В том числе на сервере, по которой делалась эта статья. Он остался в работе.

    • Проблема работы фильтров решилась после изменения параметра sieve_dir в конфиге dovecot.
      Поменял значение на sieve_dir = /mnt/mail/%d/%u/.sieve/, перезапустил dovecot, фильтры заработали.

  61. Владимир

    Добрый день. Сейчас рассматриваю вариант установки почтового сервера на сторонний сервис (впс или дедик лучше?). Подскажите, сколько потребуется места на сервере для 80-100 сотрудников, чтобы не пришлось чистить папки от писем?

    • Это напрямую зависит от того, что пользователи будут пересылать. Предсказать заранее невозможно. Вы лучше своих пользователей знаете, вот и прикиньте, сколько места у них в почте занято. Одни люди только текстом переписываются, им минимум надо. А другие постоянно презентации и макеты перекидывают друг другу по 10-20 штук за день. Первым 10 Гб на 5 лет хватит, а вторые за год уже 50 Гб займут. На 80-100 сотрудников я бы планировал 3-4ТБ под почту. VPS таких нет, нужно будет дедик брать. Хватит обычных HDD, не обязательно SSD.

  62. Добрый день.
    Подскажите, пожалуйста-) Все делал по статье до пункта, где проверяем почту с помощью клиента Thunderbird.
    DNS-записи для сервера созданы(A, MX), все резолвится, все конфиги проверил, коннекты к базе postfix проходят (в MariaDB права выданы), работает phpmyadmin, postfixadmin работает, конфиги postfix и dovecot проверены, статус systemctl status обеих служб проверен, все запущено.
    Доступность портов со внешки проверена, все порты открыты (110, 143, 465, 587, 993, 995).

    Но:
    1) При отправке почты на сервер, почта никуда не приходит. В конфиге при просмотре командой tail -f /var/log/mail.log при отправке письма со стороннего сервиса появляется такое:
    error: open /etc/postfix/mysql/relay_domains.cf: No such file or directory
    Mar 11 18:15:39 server1 postfix/smtpd[51207]: connect from 3be35768.tidalcoinage.internet-measurement.com[188.166.26.88]
    Mar 11 18:15:39 server1 postfix/smtpd[51207]: warning: SASL: Connect to smtpd failed: No such file or directory
    Mar 11 18:15:39 server1 postfix/smtpd[51207]: fatal: no SASL authentication mechanisms
    Mar 11 18:15:40 server1 postfix/master[51203]: warning: process /usr/lib/postfix/sbin/smtpd pid 51207 exit status 1
    Mar 11 18:15:40 server1 postfix/master[51203]: warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling

    При этом файл на который он ругается,что его якобы нет(relay_domains.cf), создан. (и все остальные файлы тоже там):

    # ls -lah /etc/postfix/mysql/
    -rw-r--r-- 1 root root 145 мар 10 16:26 relay_domain.cf
    -rw-r--r-- 1 root root 245 мар 10 16:28 virtual_alias_domain_maps.cf
    -rw-r--r-- 1 root root 141 мар 10 16:29 virtual_alias_maps.cf
    -rw-r--r-- 1 root root 163 мар 10 16:44 virtual_mailbox_domains.cf
    -rw-r--r-- 1 root root 147 мар 10 16:50 virtual_mailbox_maps.cf

    2) При попытке подключиться Thunderbird-ом выдает сообщение о недоверенном сертификате на порту IMAP 143. Но после этого подвисает, а потом пишет -не могу войти на сервер.
    В логах при этом:

    Mar 11 18:37:20 server1 dovecot: imap-login: Disconnected: Connection closed: SSL_accept() failed: error:0A000412:SSL routines::sslv3 alert bad certificate: SSL alert number 42 (no auth attempts in 0 secs)

    3) также вопрос по пункту статьи, где мы создаем файл /etc/postfix/tls_policy_maps. У вас в статье там следубщее содержимое:
    93.175.56.122 none
    77.221.87.91 encrypt protocols=TLSv1
    Не могу понять, что нужно туда вписывать. Подскажите, пожалуйста, что это за адреса у вас вписаны в конфиг)

    Спасибо)

    • 1. Чудес в настройке Linux не бывает. Если пишет:
      error: open /etc/postfix/mysql/relay_domains.cf: No such file or directory
      Значит либо ошибка в пути или имени файла, либо нет прав доступа на чтение этого файла. У вас в логе relay_domains.cf, а в выводе ls relay_domain.cf Имена разные.

      2. С сертификатом какие-то проблемы. Какие, не знаю. Если статью повторить без ошибок, то всё заработает.

      3. Это ip адреса серверов, для которых сделаны настройки.

  63. Zerox, спасибо за статью!

  64. Владимир

    Здравствуйте.
    Подскажите пытаюсь настроить DKIM все сделал как вы писали но при попытки настроить запись в DNS выдайтся следующие сообщение
    "Один из текстовых блоков в TXT-записи пуст или длиннее 255 символов RFC 1035"

    • Скорее всего не в то поле вводите dkim ключ. Мне тут нечем помочь. Вы явно что-то делаете неправильно. Но не видя, что именно вы делаете, мне нечего посоветовать.

      • Владимир

        Все делаю как по вашей инструкции. Далее выполняю следующие.
        cat /etc/postfix/dkim/mail.expertiza-omsk.ru.txt
        mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
        "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxl/NqJcj8yoAqoDPsjWgAMzVH3dncbRtZalhyIxik8srYMSi2laqzIRkrgptAZ4hoOKj95lJyODvzSfH0PeVV
        IQsacmZYoKoYXq5Nb0l1oTzKZujgXXF4GJZBOQRy/dmfjTBfiQz265F3CD95YC/8ch7w2Ypvk+QORNrx8QgoJ3UVc6XVzcgnETiOT2p4wVbxr2i1eCU8izpK8"
        "ld+rM+oyPv5cD96XRDlsdTuko14fGWA9pB+qPYoquf6FTUnCgKTfzySQUWgMDtVVgXmu9skxlgFUS+757EeN2GOnyOCR8YQSsKYEe1VASQvpypFn9jpgLophwfRvWyM//4F
        j7gZwIDAQAB" ) ; ----- DKIM key mail for expertiza-omsk.ru

        Получаю вот такой вот вывод. Потом иду в редактор DNS создаю TXT строку и пишу следующие
        v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxl/NqJcj8yoAqoDPsjWgAMzVH3dncbRtZalhyIxik8srYMSi2laqzIRkrgptAZ4hoOKj95lJyODvzSfH0PeVVIQsacmZYoKoYXq5Nb0l1oTzKZujgXXF4GJZBOQRy/dmfjTBfiQz265F3CD95YC/8ch7w2Ypvk+QORNrx8QgoJ3UVc6XVzcgnETiOT2p4wVbxr2i1eCU8izpK8ld+rM+oyPv5cD96XRDlsdTuko14fGWA9pB+qPYoquf6FTUnCgKTfzySQUWgMDtVVgXmu9skxlgFUS+757EeN2GOnyOCR8YQSsKYEe1VASQvpypFn9jpgLophwfRvWyM//4Fj7gZwIDAQAB

        А в ответ мне выдаётся выше указанная ошибка.

        • Редактор DNS где находится? RFC 1035 указывает, что имя DNS записи должно быть не более 255 символов. Вы, судя по всему, ключ dkim копируете в поле с именем, а должны в поле со значением. А имя должно быть mail._domainkey.

          • Владимир

            Да. Я все копирую как нужно. Это не первый мой почтовый сервер. Я по вашей инструкции настроил их уже больше 10 наверно. Но все они были на CentOS. Редактор DNS находится на nic.ru. Жаль что нельзя скрины приложить.

  65. Николай

    А как быть с отправкой больших файлов?
    По примеру допустим mailru и яндекса, когда размер письма превышает 20 мегабайт, то файлы загружаются на облако и приходят в виде ссылок.
    Есть какие то мысли?

    • Автоматического решения, как в Яндекс или Mail.ru я не знаю. Используйте любое доступное облако, можно у себя развернуть Nextcloud. Загружайте файлы туда и прикладывайте ссылки. Всё-таки почта это не средство для обмена большими файлами и никогда ею не была. Крупные компании реализовали этот функционал на базе связки своих сервисов.

  66. Сергей

    Здравствуйте.
    В статье Вы используете php7.4, а не php8.x. Это вызвано какими-то специфичными требованиями используемого комбайна (Postfix,Dovecot, плагины)? Ведь php7.4 уже не поддерживается (EOL). Я попробую развернуть на php8.1, но хотелось бы услышать Ваше мнение.
    Заранее, спасибо.

    • Это версия php, которая устанавливается по умолчанию из базовых репозиториев Debian. Если есть желание, можно использовать любую другую. Сейчас на подходе Debian 12, там уже будут другие версии php. Это не имеет принципиального значения в данной сборке. Главное, чтобы версию php поддерживал postfixadmin, который обновляется не так часто.

  67. Спасибо Zerox! Давно хотел настроить, и опаньки - не мог этого сделать. Тут получилось, по Вашей статье. Установка на домашний localhost васянский, хостовая система centos 8, lxc-container debian 11. Весть этот праздник с блэкджеком в итоге занял 1.4 Гб vm и 240 Mb .txz.
    У меня всегда был пунктик - васян без собcтвенной почты - не васян, а так. Очень благодарен, снял я этот чекпойнт галочкой, и теперь тоже васян всамделишный, настоящий.

  68. Подскажите как добавить favicon к письму??? Все хотят видеть красивое письмо с логотипом фирмы, как это сделать???

    • Это невозможно сделать на стороне почтового сервера. Данный функционал вообще не относится к почтовому протоколу. Функционал аватарок к отправителям и получателям популярные веб сервисы реализуют в веб интерфейсе своими разработками. Я их не видел в открытом доступе.

    • Поищите по ключнвому слову BIMI. Там достаточно простая настройка. Но этот функционал поддерживают очень немногие серверы

  69. Добрый день!
    Супер статья. Я уже второй почтовой сервер настроил по этой инструкции. Спасибо Вам!
    У меня вопрос интеграции Proxmox Mail Gateway в эту почтовой сервер. Не могу понять как будет DKIM, SFP, SSL сертификаты

    • DKIM и SPF относятся только к отправке почты, что к PMG никакого отношения не имеют, так как он только принимает почту. SSL сертификаты, я так понимаю, которые используют пользователи при подключении к почтовому серверу. Это тоже к PMG отношения не имеет, так как он с пользователями не работает. Он только принимает почту от других почтовых серверов. Так что особых настроек на самом почтовом сервере делать не надо. Просто ставим вперёд PMG и пересылаем всю почту с него на основной сервер.

      • Галымжан

        У меня схема такая Internet => Firewall(PfSense NAT порты 143, 587, 80, 443, 25, 110, 465, 993, 995) => MailServer(Postfix, Dovecot) локальный ip.

        Если интегрировать PMG тогда будет файрволе два нат будет
        Internet => Firewall(PfSense NAT порты 25) => PMG (локальный ip порт 25, 587, 465) => MailServer(Postfix порт 25, 587, 465) локальный ip.
        Internet => Firewall(PfSense NAT порты 143, 80, 443, 110, 993, 995) => MailServer(Dovecot порт 143, 80, 443, 110, 993, 995) локальный ip.
        Правильно я понимаю?

        • Для PMG нужно будет пробросить только 25 порт. Всё остальное менять не нужно. Серверы между собой обмениваются по 25 порту.

  70. Сергей

    Спасибо! Не понимаю как все это можно изучить. Снимаю шляпу!
    В конфигурации nginx для webmail есть такая строка
    access_log /web/sites/webmail.rocky-linux.ru/logs/access.log full;
    С full проверку не проходит, без - работает вроде.

    • Насчёт full может быть кусок конфига из моих настроек приехал. Я часто использую свой формат лога для nginx. Но сходу мне показалось, что это дефолтное значение одного из встроенных форматов. Может ошибся.

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

  71. Николай

    Здравствуйте
    Если поменять в dovecot.conf
    mail_location = maildir:/mnt/mail/%d/%u/
    на
    mail_location = maildir:/mnt/mail/%d/%u/:UTF-8
    то папки на почтовом сервере будут создаваться в кодировке UTF8, а не UTF7 и станут более читабельными

    • А с клиентами проблем не будет? Мне почему-то кажется, что будут.

      • Николай

        Я уже пару лет как добавил эту поддержку, никто не жаловался. В качестве клиентов outlook, Thunderbird, webmail.
        Что настраивал еще точно не помню, но вроде вот еще что правил
        mail_plugins = $mail_plugins mailbox_alias
        plugin {
        mailbox_alias_old = Sent
        mailbox_alias_new = "Отправленные"
        mailbox_alias_old2 = Junk
        mailbox_alias_new2 = "Нежелательная почта"
        mailbox_alias_old3 = Trash
        mailbox_alias_new3 = "Удаленные"
        }

        namespace inbox {

        mailbox Drafts {
        special_use = \Drafts
        auto = subscribe
        }
        mailbox Черновики {
        special_use = \Drafts
        auto = create
        }

        mailbox Junk {
        special_use = \Junk
        auto = subscribe
        }
        mailbox "Нежелательная почта" {
        special_use = \Junk
        auto = create
        }
        mailbox Trash {
        special_use = \Trash
        auto = subscribe
        }
        mailbox Удаленные {
        special_use = \Trash
        auto = create
        }
        mailbox Sent {
        special_use = \Sent
        auto = subscribe
        }
        mailbox "Sent Messages" {
        special_use = \Sent
        }
        mailbox Отправленные {
        special_use = \Sent
        auto = create
        }

        Может быть не все из этого надо делать, но у меня все нормально работает. Единственный момент, насколько я помню, старые папки придется пересоздать, а новые создаются нормально.

  72. Отличная статья, автору безмерная благодарность) Подскажите какие основные изменения в настройке для сервера на несколько доменов? И правильно ли я понимаю, что в идеале использовать несколько белых ip адресов? Спасибо

    • Никаких изменений не будет. Этот сервер настроен для любого количества доменов. Нужно будет только выпустить dkim ключи для всех доменов и аккуратно их прописать во все конфиги по аналогии с уже существующей записью.

      IP адрес нужен только один. Сам почтовый сервер не привязан к именам почтовых доменов, которые он обслуживает. Если вы хотите, чтобы каждый почтовый домен отправлял почту с сервера с именем из этого домена, то настроить такое будет очень непросто. И на практике так никто не делает. Во всех крупных почтовых сервисах имена почтовых серверов никак не привязаны к самим почтовым доменам. Это и не требуется.

  73. Здравствуйте, сделал все по данной статье, но при отправке сообщений получаю ошибку Action: failed Status: 5.4.6 Diagnostic-Code: X-Postfix; mail for yandex.ru loops back to myself. Подскажите пожалуйста где ошибся?

  74. Здравствуйте, Спасибо большое за статью. Подскажите пожалуйста где мог ошибиться mail postfix/smtpd: warning: unknown SASL LOGIN authentication failed: Connection lost to authentication server

  75. Андрей

    Добрый вечер. Столкнулся с любопытной проблемой.
    При проверки отправки писем из posftfıxadmın письма корректно уходят и доставляются адресату. Получение писем в roundcube тоже происходит корректно. А вот при попытке отправить письмо из roundcube ошибка SMTP () сбой соединения с сервером.
    В /var/log/mail.log следующая информация:
    Jan 23 23:14:49 mail postfix/submission/smtpd[1539]: connect from mail.rocky-linux.ru[111.101.101.2]
    Jan 23 23:14:49 mail postfix/submission/smtpd[1539]: SSL_accept error from mail.rocky-linux.ru[111.101.101.2]: -1
    Jan 23 23:14:49 mail postfix/submission/smtpd[1539]: warning: TLS library problem: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:../ssl/record/rec_layer_s3.c:1543:SSL alert number 48:
    Jan 23 23:14:49 mail postfix/submission/smtpd[1539]: lost connection after STARTTLS from mail.rocky-linux.ru[111.101.101.2]
    Jan 23 23:14:49 mail postfix/submission/smtpd[1539]: disconnect from mail.rocky-linux.ru[111.101.101.2] ehlo=1 starttls=0/1 commands=1/2
    Понимаю что проблема с SSL-Авторизацией, но не могу понять где... уже весь мозг сломал.

    • Суть ошибки ясна. Ключевое тут: unknown ca. Дело не с авторизацией. У вас используется самоподписанный сертификат. Клиент подключается к серверу по tls соединению. И тут то ли клиент, то ли сервер отвечает, что не может проверить сертификат, потому что выпустил его недоверенный CA. Если некритично, то настройте подключение между roundcube и postfix без tls. Либо где-то надо явно прописать корневой CA, которому нужно доверять, и через кого выписывались остальные сертификаты.

      • Аноним

        Добрый день!
        Огромное спасибо за статью! Ушли с яндекса! Уже какой день не могу понять в чем дело. На клиентах пока отключено шифрование.
        Такая же ошибка в thunderbird при отправке письме. Сам клиент говорит "Неизвестный центр сертификации". На сервере в логе
        Apr 28 07:56:06 * postfix/smtpd[272396]: connect from unknown[192.168.17.193]
        Apr 28 07:56:06 * postfix/smtpd[272396]: SSL_accept error from unknown[192.168.17.193]: -1
        Apr 28 07:56:06 * postfix/smtpd[272396]: warning: TLS library problem: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:../ssl/record/rec_layer_s3.c:1543:SSL alert number 48:
        Apr 28 07:56:06 * postfix/smtpd[272396]: lost connection after STARTTLS from unknown[192.168.17.193]
        Apr 28 07:56:06 * postfix/smtpd[272396]: disconnect from unknown[192.168.17.193] ehlo=1 starttls=0/1 commands=1/2
        Сертификат купил alphassl. Добавил цепочку вышестоящих сертификатов в доверенные на сервере. Все равно эта же ошибка. Еще заметил что openssl verify у сертификата проходит только с опцией -CAfile.
        Возможно глупый вопрос, так и должно быть? И может подскажете, пожалуйста, куда смотреть дальше?

        • Дмитрий

          нажал по привычке ctl+Enter. С входящими с этим сертификатом проблем не было.

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

      • Александр

        В моём случае с такой же ошибкой всё было забавнее:
        Roundcube отказывался принимать подписанный сертификат из-за несовпадения CN с хостом SMTP. В настройках smtp я прямо прописал локальные ip-адреса, а сертификат выдал на FQDN.
        Решение проблемы - поправить конфиг rouncube/config/defaults.inc.php:

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

        Если раскомментировать строку с параметром verify_peer - то, по идее, не будет проверяться CA. allow_self_signed - разрешит самоподписанные сертификаты.

  76. Сергей

    Здравствуйте.
    У Вас в файле mx_access затроены проверки:
    127.0.0.1 DUNNO
    127.0.0.2 550 Domains not registered properly
    127.0.0.0/8 REJECT Domain MX in loopback network

    Достаточно только третей (127.0.0.0/8). Ненужные накладные расходы...

  77. Алексей

    По логам все вроде ок, но при попытке соединиться по 25, 465 и 587 портам (то есть к postfix) получаю Connection refuson.... В том числе и с localhost'а. Где мог наворочать?

    • А службы то запущены на этих портах? Как проверяете подключение?

      • Алексей

        Спасибо за ответ. Проверяю телнетом, в том числе и с localhosta. Postfix запущен, в логах ошибок нет, но не слушает эти порты... Что-то накосячил с конфигурацией, но не пойму где именно... Подскажите, куда копать. В настройке почты на linux новичок. Файрволл точно не виноват, проверял с отключеннным и включенным.

        • Алексей

          dovecot по телнету работает ок, если это будет полезной информацией

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

  78. Добрый день!
    Спасибо за статью. Статья супер.
    Ранее уже настраивал для интереса мультидоменый почтовый сервер, чисто для уведомлений, помню возился долго.
    Здесь настроил с первого раза. При тестировании на mail-tester получил 10/10.
    Пока настраивал нашел два недочета, если не ошибаюсь:
    1. лишние галочки (знак <) при указании путей к сертификатам в конфиге dovecot:
    ssl_cert = </etc/postfix/certs/cert.pem
    ssl_key = </etc/postfix/certs/key.pem
    У меня не работала доставка почты, после того как удалил глочки доставка заработала.
    2. в конфиге opendkim указано не то имя файла, что создавали ранее: KeyFile /etc/postfix/dkim/mail.kirushin-vladimir.ru.private. Должно быть mail.rocky-linux.ru.private.

    • Спасибо за замечания. Это судя по всему помарки с прошлой версии статьи. Там домен другой был для теста.

    • Символ "<" важен. Он указывает, что переменная содержит содержимое файла, а не путь к нему. Неуказание этого символа приведет к ошибке.

  79. mail-tester показывает 10/10, на все известные почтовые домены разосланные письма попадают во входящие, а если писать на gmail то в спам...=(

    • У gmail свои алгоритмы определения спама. Я с этим тоже много раз сталкивался. Что тут делать - не знаю.

      • Некоторые спам-фильтры, а именно antispam.lotte.net и spamhaus добавляют мой домен в чёрные списки, несмотря на то, что всё настроено на ура! Юрок 08.01.2023 в 01:37. Задал вопрос на ЛОРе, там чувак ответил что gmail требует настройки политики MTA-STS на почтовом сервере. Начал гуглить, оказалось что инфы по этому поводу о-о-очень мало. Понятно что придётся по-кусочкам собирать инфу и реализовывать у себя. Так что Володя, это идея для твоего следующего поста ;=)

        • В спам фильтр обычно попадают не из-за настроек, а из-за того, что кто-то незаметно рассылает спам. Много раз с этим сталкивался. Надо внимательнее смотреть на то, что отправляет сервер.

          • Spamhaus рекомендует закрыть 25 порт, но передовая практика требует STARTTLS и для соединения через порт 25 и при закрытии исходящего трафика на 25 порту, письма не уходят, а собираются в mailq. Как правильно настроить Postfix, чтобы почта уходила с 465 порта...?

            • 465 порт это порт для подключения клиентов. Сами почтовые сервера общаются между собой по 25 порту. Он должен быть открыт для исходящих соединений.

  80. Спасибо за отличное руководство!
    Автор, подскажите пожалуйста, а можно ли подобный сервер подконнектить по LDAP к Active Direcory. Чтобы созданные учетки с указанными почтовыми адресами в AD, подгружались на mail сервер. Возможно существуют отдельные компоненты?

    • Да, можно. Но сам я не настраивал. По моим представлениям для небольших структур, условно, до 300 ящиков, в этом нет большого смысла. Создать новый ящик человеку раз в неделю не занимает много времени, зато почта полностью автономна и не зависит от внешних сервисов.

      • Статья классная!!! Странно почему не начался холивар по поводу почтовика для домена rocky-linux.ru работающего на Debian)

        • Когда Rockylinux появился, я возлагал на него большие надежды. А потом понял, что новым Centos он уже не станет. В итоге перешёл на Debian, а домен остался.

  81. Аднрей

    при конфиге с

    myhostname = mail.rocky-linux.ru
    mydomain = rocky-linux.ru
    myorigin = $myhostname

    не приходит почта от демона crontab. он пытается отправить на адрес root@mail.rocky-linux.ru, что является неверным адресом. добился корректной отправки только исправив с myhostname = mail.rocky-linux.ru на myhostname = rocky-linux.ru

    • В данном случае это особенность локального cron. Сервер можно было не трогать, а сделать локальный алиас для root, указав конкретный ящик root@rocky-linux.ru. Либо добавить почтовый домен mail.rocky-linux.ru. Всё-таки у почтового сервера имя mail.rocky-linux.ru.

      • Андрей

        "Либо добавить почтовый домен mail.rocky-linux.ru"
        извиняюсь за тупость - куда добавить? с локальными алиасами разобрался: добавил root@rocky-linux.ru в /etc/aliases --> newaliases
        и ещё вопрос: имя сервера же может быть произвольным? в /etc/hosts и /etc/hostname --> 192.168.1.5 srv0001

        • Да, имя сервера может быть любым. Почтовый сервер не привязывается к системному имени. Он использует то, что указано в настройках postfix. Добавить почтовый домен я имел ввиду прямо в postfixadmin. Раз cron хочет именно этот домен и ящик, то можно добавить домен mail.rocky-linux.ru и сделать ящик root@mail.rocky-linux.ru. Ну и читать почту уже в нём. Можно даже DNS не настраивать для него. Локальная почта и так работать будет.

  82. Спасибо.
    З.ы. Если хочется быстро и сразу - mailcow

    • Да, я видел. Там примерно то же самое можно получить. Но мне не нравится идея использовать докер для почтового сервера. Это упрощает разработку и установку, но не эксплуатацию. Появляются лишние связи и сущности.

  83. Здравствуйте.
    Попробовал развернуть iRedMail на meil.example1.ru, все заработало, но подскажите как добавить другой домен example2.ru? В панели админа прописал,как должна выглядеть mx запись? и что ещё необходимо? необходимо только чтобы вид ящика был test@example2.ru
    Спасибо.

    • Эта статья не про iRedMail. Я сам его не ставил лет 5-6. Не помню, как там всё настраивается.

  84. Александр

    Спасибо за статью, резко стало актуально.

  85. Дмитрий

    Ggkfuby Expire выпилен из Dovecot.
    https://doc.dovecot.org/settings/plugin/expire-plugin/

  86. Спасибо за полезную статью.
    Но как будет идти установка postfixadmin если предварительно не создана база postfix и не задан для этой базы пользователь и пароль postfix/password?

    З.ы. Глянул в офф. сайте (github) инструкцию по установке postfixadmin там это указанно.

    • Не понял, почему не создана? А кто мешает её создать? Я же в статье об этом пишу и даже phpmyadmin ставлю, чтобы было удобно это сделать.

      • Да вы правы, эт я слепой (изначально статью читал с телефона), сейчас перечитал с компьютера и увидел что действительно об этом сказано.
        Приношу свои извинения, был не прав.

      • Алексей

        Можно как-то заставить почтовик большие файлы высылать как ссылки, не впихивая в в сообщение весь файл?

        • Нет, автоматически почтовый сервер это делать не умеет. Да и куда он должен девать файлы и на что давать ссылки? Это можете сделать только вы, загрузив куда-то файл.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить комментарий" Я даю согласие на обработку персональных данных.
Используешь Telegram? Подпишись на канал автора →
This is default text for notification bar