Установка и настройка почтового сервера Postfix с виртуальными доменами, системой управления Dovecot, веб-доступом Roundcube на CentOS 8, 9
После установки на сервер CentOS 8 (Minimal) (x86_64) 8Gb RAM, 4 CPU, 50Gb SSD, приступаем к подготовке сервера.
В данной инструкции выполнена настройка полноценного почтового сервера. Список всех особенностей и возможностей:
- Почтовая система на базе Postfix;
- Поддержка виртуальных доменов;
- Хранение почты на сервере;
- Подключение к почтовым ящикам по POP3 и IMAP (Dovecot);
- Поддержка шифрования;
- Хранение части настроек в MariaDB;
- Защита от СПАМа и вирусов;
- Доступ к почте с помощью веб-интерфейса (Roundcube);
- Возможность управления почтовыми ящиками с помощью PostfixAdmin.
1. Подготовка системы
Общие настройки.
Задаем правильное имя серверу — это важный шаг, так как большинство антиспам систем выполняют проверки, обращаясь к серверу по имени в ожидании ответа.
hostnamectl set-hostname mail.putyato.ru
- необходимо указать FQDN-имя, которое будет доступно из глобальной сети. В данном примере указано mail.putyato.ru.
Устанавливаем служебные пакеты (они понадобятся в процессе настройки сервера):
dnf -y install chrony wget tar nano
где:
chrony — для возможности синхронизировать время на сервере;
wget — клиент для загрузки файлов.
tar — распаковка архивов.
nano - текстовый редактор.
Задаем временную зону (в данном примере московское время):
timedatectl set-timezone Europe/Moscow
- в данном примере мы установим московское время. Чтобы получить список всех возможных зон, вводим timedatectl list-timezones.
Запускаем сервис для обновления времени:
systemctl enable chronyd --now
Обновляем систему:
dnf update -y
Настройка безопасности.
Заранее открываем порты на брандмауэре с помощью firewalld:
firewall-cmd --permanent --add-port=25/tcp --add-port=80/tcp --add-port=110/tcp --add-port=143/tcp --add-port=443/tcp --add-port=465/tcp --add-port=587/tcp --add-port=993/tcp --add-port=995/tcp firewall-cmd --reload
Где мы откроем следующие порты:
- 25 — стандартный SMTP через STARTTLS;
- 80 — HTTP для порталов Postfixadmin и Roundcube;
- 110 — стандартный POP3 через STARTTLS;
- 143 — стандартный IMAP через STARTTLS;
- 443 — защищенный HTTPS для порталов Postfixadmin и Roundcube;
- 465 — защищенный SMTP через SSL/TLS;
- 587 — защищенный SMTP через STARTTLS;
- 993 — защищенный IMAP через SSL/TLS;
- 995 — защищенный POP3 через SSL/TLS.
Отключение SELinux.
Для отключения дополнительного компонента безопасности вводим 2 команды:
setenforce 0 sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
2. Настройка веб-сервера: NGINX + PHP + MariaDB
Система управления PostfixAdmin работает как веб-приложение, разработанное на PHP, а информацию хранит в базе данных. В нашем примере будет использоваться веб-сервер на NGINX, а база данных — MariaDB.
Установка NGINX.
Для установки самой свежей стабильной версии nginx создаем конфиг:
nano /etc/yum.repos.d/nginx.repo
Есть 2 версии nginx. Stable version (Стабильная) и Mainline version (Основная). Основная версия — это последняя версия nginx с новыми функционалом. Стабильная версия — это версия, которая нацелена на стабильность и безопасность. Новый функционал не добавляется.
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/8/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/8/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
Можно прописать в файл все два репозитория. Если нужна стабильная версия, тогда ее нужно указать программе dnf, что бы она использовала репозиторий стабильной версии.
dnf config-manager --set-enabled nginx-stable
Устанавливаем NGINX:
dnf install nginx -y
Внесем небольшую корректировку в файл nginx.conf:
nano /etc/nginx/nginx.conf
http { ... server_names_hash_bucket_size 64; .... }
* на практике, может встретиться ошибка could not build server_names_hash, you should increase server_names_hash_bucket_size: 32. Она возникает при большом количестве виртуальных серверов или если один из них будет иметь длинное название. Данная строка в конфиге исправит ситуацию.
Разрешаем автозапуск сервиса и запустим его:
systemctl enable nginx --now
Проверим, что веб-сервер работает. Для этого открываем браузер на другом компьютере, который находится в одной сети и вводим в адресной строке IP-адрес сервера. В итоге мы должны увидеть заголовок «Welcome to nginx!»:
* обратите внимание, что данное приветствие может иметь и другой вид.
PHP + PHP-FPM + NGINX.
Устанавливаем php и php-fpm. Мы будем использовать репозиторий remi, так как в репозитории CentOS отсутствует нужный нам php-imap.
И так, устанавливаем EPEL и REMI:
dnf -y install epel-release dnf -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
Теперь вы можете перечислить модули PHP и посмотреть, был ли добавлен PHP 8.2
dnf module list php
После этого теперь вы можете сбросить модуль и включить PHP 8.2:
dnf module reset php dnf module install php:remi-8.2 dnf module enable php:remi-8.2
И устанавливаем php и PHP-FPM версии 8.2:
dnf install php php-fpm -y
Проверяем:
php -r "phpinfo();" | grep "PHP Version"
Настраиваем NGINX:
nano /etc/nginx/nginx.conf
В разделах http - server добавляем настройку для обработки запросов php:
server { listen 80 default_server; ... location ~ \.php$ { set $root_path /usr/share/nginx/html; fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name; include fastcgi_params; fastcgi_param DOCUMENT_ROOT $root_path; } }
* где /usr/share/nginx/html — каталог для размещения данных nginx по умолчанию.
Запускаем сервисы:
systemctl enable php-fpm --now systemctl restart nginx
Для проверки создаем index.php в каталоге сайта по умолчанию со следующим содержимым:
nano /usr/share/nginx/html/index.php
<?php phpinfo(); ?>
Открываем в браузере IP-адрес нашего сервера. Теперь мы должны увидеть сводную информацию по PHP и его настройкам, например:
MariaDB.
Подключение актуального репозитория: В примерах выше мы установили СУБД из репозиториев операционных систем. А значит — нет гарантии, что будет установлена последняя версия MariaDB. Для решения задачи мы можем подключить официальный репозиторий самого разработчика.
Генерируем репозиторий mariadb.repo.
Скачиваем скрипт из оф.сайта для генерации репозитория mariadb.repo и даем ему право на выполнение.
cd ~ wget https://downloads.mariadb.com/MariaDB/mariadb_repo_setup chmod +x mariadb_repo_setup
После предоставления необходимых прав, нужно запустить этот скрипт и он уже сгенерирует репозиторий.
./mariadb_repo_setup
Итак, после выполнения скрипта файл mariadb.repo будет сгенерирован в директории /etc/yum.repos.d.
Заходим и смотрим, что он там намутил...
nano /etc/yum.repos.d/mariadb.repo
После генерации репозитория теперь запускаем установку самой MariaDB:
dnf install mariadb mariadb-server --allowerasing
Чтобы, проверить какие пакеты установились нужно использовать команду:
yum list installed | grep mariadb
Разрешаем автозапуск и запускаем СУБД:
systemctl enable mariadb --now
Проверьте состояние службы MariaDB, выполнив следующую команду.
systemctl status mariadb
Сразу создаем пароль для учетной записи root:
mysqladmin -u root password
Защита сервера MariaDB на CentOS 8
В качестве последнего шага нам нужно запустить безопасный сценарий установки MariaDB. Этот скрипт позаботится о пароле root, установки привилегий, удалении тестовых баз данных, запрете входа в систему с root правами.
mysql_secure_installation
Далее вводим пароль который создавали на предыдущем шаге и везде отвечаем: Y
[root@webserver ~]# mysql_secure_installation NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and you haven't set the root password yet, the password will be blank, so you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MariaDB root user without the proper authorisation. You already have a root password set, so you can safely answer 'n'. Change the root password? [Y/n] n ... skipping. By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] Y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] Y ... Success! By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] Y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] Y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB!
3. Установка и настройка PostfixAdmin
Устанавливаем дополнительные компоненты для PHP:
dnf install php-{mysqli,mbstring,imap} -y
Для применения установленных пакетов, перезапускаем обработчик скриптов:
systemctl restart php-fpm
Скачиваем PostfixAdmin:
wget https://sourceforge.net/projects/postfixadmin/files/latest/download -O postfixadmin.tar.gz
В директории сайтов nginx создаем каталог для postfixadmin и распаковываем в него архив:
mkdir /usr/share/nginx/html/postfixadmin tar -C /usr/share/nginx/html/postfixadmin -xvf postfixadmin.tar.gz --strip-components 1
Создаем каталог templates_c внутри папки портала (без него не запустится установка):
mkdir /usr/share/nginx/html/postfixadmin/templates_c
Задаем права на каталог:
chown -R apache:apache /usr/share/nginx/html/postfixadmin
* несмотря на то, что мы используем веб-сервер nginx, php-fpm по умолчанию, запускается от пользователя apache.
Создаем базу данных postfix и учетную запись в mariadb:
mysql -u root -p > CREATE DATABASE postfix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
* где postfix — имя базы.
> GRANT ALL ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'postfix12345';
* где postfix — имя учетной записи; postfix12345 — пароль; localhost разрешает подключение только с локального сервера.
Выходим из командной оболочки MariaDB:
> \q
Создаем конфигурационный файл postfixadmin:
nano /usr/share/nginx/html/postfixadmin/config.local.php
* в предыдущих версиях использовался файл config.inc.php. В новых версиях его не рекомендуется править, а использовать config.local.php, который переопределяет настройки.
И добавляем следующее:
<?php $CONF['configured'] = true; $CONF['default_language'] = 'ru'; $CONF['database_password'] = 'postfix12345'; $CONF['emailcheck_resolve_domain']='NO'; ?>
* где configured говорит приложению, что администратор закончил его конфигурирование; default_language — используемый язык по умолчанию; database_password — пароль для базы данных, который мы задали на предыдущем шаге; emailcheck_resolve_domain — задает необходимость проверки домена при создании ящиков и псевдонимов.
Запускаем браузер и вводим адрес http://<IP-адрес сервера>/postfixadmin/public/setup.php
Начнется процесс проверки конфигурации и установки портала PostfixAdmin. После ее окончания мы увидим окно с результатами — проверяем, чтобы не было ошибок и предупреждений:
... после чего, вводим дважды пароль и генерируем хэш, кликнув по Generate password hash:
После перезагрузки страницы копируем хэш:
Открываем конфигурационный файл:
nano /usr/share/nginx/html/postfixadmin/config.local.php
И добавляем строчку:
... $CONF['setup_password'] = '7a8e14...c26';
* где '7a8e14...c26' — скопированный хэш.
После, на той же странице, где показан хэш, добавляем суперпользователя PostfixAdmin:
* где Setup password — пароль, который мы ввели на предыдущей странице; Пароль — новый пароль для создаваемой учетной записи.
В итоге мы увидим следующее:
И переходим в браузере на страницу http://<IP-адрес сервера>/postfixadmin/public/
Вводим логин и пароль для созданного пользователя. Мы должны войти в postfix.admin:
Готово.
4. Установка и настройка Postfix
Установка Postfix в CentOS 8 выполняется командой:
dnf -y install postfix postfix-mysql
* помимо самого postfix, мы также установили postfix-mysql для возможности работы с СУБД.
После создаем учетную запись, от которой мы будем работать с каталогом виртуальных почтовых ящиков:
groupadd -g 1024 vmail useradd -d /home/mail -g 1024 -u 1024 vmail -m
* сначала мы создаем группу vmail и guid 1024, после — пользователя vmail с uid 1024 и домашней директорией /home/mail — в ней у нас будет храниться почта. Обратите внимание, что в некоторых системах идентификатор группы и пользователя 1024 может быть занят. В таком случае необходимо создать другой, а в данной инструкции ниже заменить все 1024 на альтернативный.
Если директория для почты ранее уже была создана, то необходимо задать в качестве владельца нашего созданного пользователя:
chown vmail:vmail /home/mail
Теперь открываем на редактирование конфигурационный файл почтового сервера:
nano /etc/postfix/main.cf
И редактируем следующие строки:
myorigin = $mydomain ... mydestination = localhost.$mydomain, localhost, localhost.localdomain ... local_recipient_maps = unix:passwd.byname $alias_maps ... mynetworks = 127.0.0.0/8 ... inet_interfaces = all ... inet_protocols = ipv4 ... smtpd_tls_cert_file = /etc/ssl/mail/public.pem ... smtpd_tls_key_file = /etc/ssl/mail/private.key
* где:
- myorigin — указывает, какой домен подставлять отправителю, если он не указан в заголовке FROM.
- mydestination — указываем, для каких доменов принимаем входящую почту.
- local_recipient_maps — указываем, откуда брать список локальных пользователей.
- mynetworks — разрешаем отправлять сообщения локальному серверу.
- inet_interfaces — необходимо убедиться, что postfix будет слушать на всех необходимых интерфейсах, в данном случае, на всех (all). Также можно задать варианты loopback-only (127.0.0.1) или конкретный IP-адрес интерфейса.
- inet_protocols — данный параметр задаст протокол для работы postfix. В данном примере на всех (all). Также можно задать значения ipv4 или ipv6.
- smtpd_tls_cert_file — полный путь до публичного сертификата.
- smtpd_tls_key_file — полный путь до приватного сертификата.
Если имя сервера отличается от имени, по которому сервер будет зарегистрирован в DNS, задаем опцию:
myhostname = mx01.putyato.ru
Теперь в конец конфигурационного файла допишем следующее:
virtual_mailbox_base = /home/mail virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf virtual_minimum_uid = 1024 virtual_uid_maps = static:1024 virtual_gid_maps = static:1024 virtual_transport = dovecot dovecot_destination_recipient_limit = 1 smtpd_sasl_auth_enable = yes smtpd_sasl_exceptions_networks = $mynetworks smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtp_use_tls = yes smtpd_use_tls = yes smtpd_tls_auth_only = yes smtpd_helo_required = yes
* где:
- virtual_mailbox_base — базовый путь хранения почтовых ящиков в системе UNIX.
- virtual_alias_maps — формат и путь хранения алиасов для виртуальных пользователей.
- virtual_mailbox_domains — формат и путь хранения доменов виртуальных пользователей.
- virtual_mailbox_maps — формат и путь хранения почтовых ящиков для виртуальных пользователей.
- virtual_minimum_uid — с какого номера присваивать идентификаторы пользователям.
- virtual_uid_maps — идентификатор пользователя, от которого записываются сообщения.
- virtual_gid_maps — идентификатор группы, от которой записываются сообщения.
- virtual_transport — задает доставщика сообщений.
- dovecot_destination_recipient_limit — передача сообщений от Postfix в Dovecot выполняется по заданному количеству (в нашем примере, по 1 шт.).
- smtpd_sasl_auth_enable — разрешает sasl аутентификацию.
- smtpd_sasl_exceptions_networks — исключение сетей от использования шифрования.
- smtpd_sasl_security_options — дополнительные опции настройки sasl.
- broken_sasl_auth_clients — эту опцию прописываем для клиентов MS Outlook.
- smtpd_sasl_type — указывает тип аутентификации.
- smtpd_sasl_path — путь до временных файлов обмена информацией с Dovecot. Указывается либо абсолютный путь, либо относительный queue_directory (по умолчанию /var/spool/postfix). Итого, полный путь — /var/spool/postfix/private/auth.
- smtp_use_tls — по возможности, нужно ли передавать сообщения по защищенному каналу.
- smtpd_use_tls — указывает клиентам на наличие поддержки TLS.
- smtpd_tls_auth_only — использовать только TLS.
- smtpd_helo_required — требовать начинать сессию с приветствия.
Создаем файл с настройками обращения к базе с алиасами:
nano /etc/postfix/mysql_virtual_alias_maps.cf
user = postfix password = postfix12345 hosts = localhost dbname = postfix query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
* где user и password — логин и пароль для подключения к MySQL; hosts — имя сервера баз данных (в нашем случае, локальный сервер); dbname — имя базы данных; query — шаблон запроса к данным.
Создаем файл с инструкцией получения данных по виртуальным доменам:
nano /etc/postfix/mysql_virtual_domains_maps.cf
user = postfix password = postfix12345 hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%u'
И файл с почтовыми ящиками:
nano /etc/postfix/mysql_virtual_mailbox_maps.cf
user = postfix password = postfix12345 hosts = localhost dbname = postfix query = SELECT CONCAT(domain,'/',maildir) FROM mailbox WHERE username='%s' AND active = '1'
Открываем файл master.cf и дописываем в самый конец:
nano /etc/postfix/master.cf
submission inet n - n - - smtpd -o smtpd_tls_security_level=may -o smtpd_sasl_auth_enable=yes -o smtpd_sasl_type=dovecot -o smtpd_sasl_path=/var/spool/postfix/private/auth -o smtpd_sasl_security_options=noanonymous -o smtpd_sasl_local_domain=$myhostname smtps inet n - n - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -d ${recipient}
* необходимо убедиться, что в содержимом файла нет других раскомментированных опций для submission, smtps и dovecot (по умолчанию, их нет). В данном случае, мы настроили работу postfix на портах 25, 465 и 587. В файле master.cf мы настраиваем работу вспомогательных сервисов для Postfix. Описание каждого сервиса начинается с новой строки без отступа. Затем идут настройки для сервиса и параметры запуска. Для примера, рассмотрим первую добавленную строку — submission inet n - n - - smtpd:
- submission — имя сервиса. Возможно использование заранее определенных в postfix служб или создание своих. В данном примере submission для подключения MUA по порту 587 при отправке почты.
- inet — тип обслуживания. Возможны варианты inet (сокет TCP/IP), unix (потоковый сокет), unix-dgram (сокет дейтаграммы), fifo (именованный канал очереди), pass (потоковый сокет UNIX-домена).
- первый "n" — является ли сервис частным и должен быть ограниченным. Возможны варианты y или n. Для типа обслуживания inet может быть только n.
- первый "-" — работает ли служба с правами root. Возможны варианты y, n и -. Прочерк означает неприменимость данного параметра к конкретному сервису.
- второй "n" — должна ли служба работать в окружении chroot. Возможны варианты y или n.
- второй "-" — через какое время в секундах пробудить службу, если она неактивна.
- третий "-" — максимальное количество одновременно выполняемых процессов, которые может запустить данный сервис.
- smtpd — выполняемая команда.
* после команды идут аргументы ее запуска. Они могут переопределять параметры, заданные в main.cf. Каждый аргумент записывается с новой строки и начинается с двух пробелов. В данном примере мы используем следующие аргументы:
- smtpd_tls_security_level — задает уровень безопасности с применением TLS. В данном примере may говорит о возможности его использования.
- smtpd_sasl_auth_enable — разрешает sasl аутентификацию.
- smtpd_sasl_type — указывает тип аутентификации.
- smtpd_sasl_path — путь до временных файлов обмена информацией с сервером хранения почты (в нашем случае Dovecot). Указывается либо абсолютный путь, либо относительный queue_directory.
- smtpd_sasl_security_options — дополнительные опции настройки sasl.
- smtpd_sasl_local_domain — добавить домен для пользователей, которые проходят smtp-аутентификацию.
- syslog_name — префикс названия службы при занесении ее в системный журнал.
- smtpd_tls_wrappermode — запускать ли службу в нестандартном режиме (для поддержки TLS).
- smtpd_client_restrictions — настройки ограничения клиентских соединений. В данном примере разрешить только авторизованных.
Генерируем сертификаты безопасности. Для этого создаем каталог, в котором их разместим:
mkdir -p /etc/ssl/mail
И сгенерируем их следующей командой:
openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/mail/public.pem -keyout /etc/ssl/mail/private.key -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=mail.putyato.ru"
* сертификат сгенерирован на 1461 день, ключи subj могут быть произвольными, CN необходимо указать в соответствии с именем сервера, по которому мы будем подключаться к почте. * если мы хотим использовать сертификат, который будет проходить все проверки безопасности, его нужно купить или запросить у Let's Encrypt.
Разрешаем запуск postfix:
systemctl enable postfix --now
5. Настройка Dovecot
Устанавливаем Dovecot с компонентом для работы с СУБД:
dnf -y install dovecot dovecot-mysql
Настраиваем способ хранения сообщений:
nano /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:/home/mail/%d/%u/
* в данном примере сообщения будут храниться в продвинутом формате maildir в каталоге /home/mail/<почтовый домен>/<логин пользователя>.
Настраиваем слушателя для аутентификации:
nano /etc/dovecot/conf.d/10-master.conf
service auth { unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } unix_listener auth-userdb { mode = 0600 user = vmail group = vmail } }
* в данном примере мы настраиваем сервис для аутентификации и создаем два прослушивателя: /var/spool/postfix/private/auth — для возможности постфиксом использовать авторизацию через Dovecot (обращаем внимание, что /var/spool/postfix/private/auth — это тот же private/auth, который был прописан нами в postfix); auth-userdb — сокет для авторизации через dovecot-lda. Опция mode задает права на сокет, например, 666 позволит любому пользователю к нему подключиться; user и group задает пользователя и группу владельцев на сокет.
А также в этом файле добавим строки:
service stats { unix_listener stats-reader { user = vmail group = vmail mode = 0660 } unix_listener stats-writer { user = vmail group = vmail mode = 0660 } }
* в противном случае, мы увидим в логе ошибку error net_connect_unix(/var/run/dovecot/stats-writer) failed permission denied, так как у пользователя vmail не будет прав.
Настраиваем аутентификацию в Dovecot:
nano /etc/dovecot/conf.d/10-auth.conf
#!include auth-system.conf.ext !include auth-sql.conf.ext
* в данном случае мы просто комментируем обычную аутентификацию и снимаем комментарий для использования sql-аутентификации.
Настраиваем использование шифрования:
nano /etc/dovecot/conf.d/10-ssl.conf
ssl = required ssl_cert = </etc/ssl/mail/public.pem ssl_key = </etc/ssl/mail/private.key
* ssl = required укажет dovecot требовать от клиентов использования шифрования; ssl_cert — путь до открытого сертификата (также нами указывался в postfix); ssl_key — путь к закрытому ключу.
Настроим автоматическое создание каталогов при первом подключении пользователя к ящику:
nano /etc/dovecot/conf.d/15-lda.conf
lda_mailbox_autocreate = yes
Настраиваем подключение к нашей базе данных:
nano /etc/dovecot/conf.d/auth-sql.conf.ext
passdb { … args = /etc/dovecot/dovecot-sql.conf.ext } userdb { … args = /etc/dovecot/dovecot-sql.conf.ext }
* в данном примере мы указали на файл, в котором будут находиться настройки для получения пользователей и паролей из базы данных. Данная настройка является настройкой по умолчанию и, в большинстве случаев, ее не нужно менять без необходимости указать свой путь.
Создаем файл с настройками работы с mysql:
nano /etc/dovecot/dovecot-sql.conf.ext
driver = mysql connect = host=localhost dbname=postfix user=postfix password=postfix12345 default_pass_scheme = MD5-CRYPT password_query = SELECT password FROM mailbox WHERE username = '%u' user_query = SELECT maildir, 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u' user_query = SELECT CONCAT('/home/mail/',LCASE(`domain`),'/',LCASE(`maildir`)), 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '%u'
* в данном примере мы настроили запрос на получение данных из базы mysql (mariadb). password_query — запрос на получение пароля из таблицы mailbox; user_query — запрос на получение данных пользователя (домашняя почтовая директория, идентификатор 1024 (идентификатор созданного нами ранее пользователя vmail).
И, напоследок, настраиваем интерфейс, на котором будет слушать dovecot:
nano /etc/dovecot/dovecot.conf
listen = *
* по умолчанию, dovecot слушает также на ipv6 (listen = *, ::). Если на сервере не используется 6-я версия протокола TCP/IP, в логах dovecot появятся ошибки:
master: Error: service(imap-login): listen(::, 143) failed: Address family not supported by protocol
master: Error: service(imap-login): listen(::, 993) failed: Address family not supported by protocol
Запускаем dovecot:
systemctl enable dovecot --now
6. Создаем первый почтовый ящик и проверяем работу сервера
В браузере вводим в адресной строке путь до Postfixadmin — http://<IP-адрес сервера>/postfixadmin/public/.
Вводим логин и пароль от административной учетной записи, которую мы создали на шаге 3. Перед нами появится страница управления учетными записями.
Переходим в Список доменов - Новый домен:
Заполняем формы и нажимаем по Добавить домен:
Теперь переходим в Обзор - Создать ящик:
Вводим данные нового пользователя и нажимаем по Создать ящик:
Теперь можно подключиться к серверу с помощью любой почтовой программы, например, Mozilla Thunderbird.
Параметры для подключения:
- Сервер: имя сервера или его IP-адрес (не желательно, так как сертификат выдается по доменному имени).
- IMAP: 143 STARTTLS или 993 SSL/TLS
- POP3: 110 STARTTLS или 995 SSL/TLS
- SMTP: 25 STARTTLS или 465 SSL/TLS или 587 STARTTLS
* для корректной работы сервера на портах 993, 995, 465 (SSL/TLS) необходим правильный сертификат (для нашего домена и выпущенный доверенным центром сертификации).
7. Устанавливаем и настраиваем Roundcube Webmail
В данной инструкции мы разберем использование веб-клиента Roundcube. При необходимости, можно установить другой, например, WebMail Lite или несколько одновременно.
На официальном сайте заходим на страницу загрузки Roundcube - https://roundcube.net/download/. Смотрим ссылку на версию продукта с длительной поддержкой (LTS):
Используем ссылку, чтобы загрузить архив программы:
wget https://github.com/roundcube/roundcubemail/releases/download/1.5.4/roundcubemail-1.5.4-complete.tar.gz
Создаем каталог, где будут размещаться файлы портала:
mkdir /usr/share/nginx/html/webmail
И распаковываем скачанный архив:
tar -C /usr/share/nginx/html/webmail -xvf roundcubemail-*.tar.gz --strip-components 1
Копируем шаблон конфига:
cp /usr/share/nginx/html/webmail/config/config.inc.php.sample /usr/share/nginx/html/webmail/config/config.inc.php
И открываем его на редактирование:
nano /usr/share/nginx/html/webmail/config/config.inc.php
$config['db_dsnw'] = 'mysql://roundcube:roundcube123@localhost/roundcubemail'; $config['enable_installer'] = true;
* первую строку мы редактируем, а вторую добавляем. В первой строке roundcube:roundcube123 — логин и пароль для доступа к базе данных; localhost — сервер базы данных; roundcubemail — имя базы данных. Вторая строка разрешает установку портала.
Редактируем:
... $config['smtp_pass'] = '';
* в данном случае мы просто оставляем значение для переменной $config['smtp_pass'] пустым. В противном случае, веб-интерфейс будет выдавать ошибку авторизации при отправке сообщения.
Также дописываем в конфигурационный файл следующее:
$config['drafts_mbox'] = 'Drafts'; $config['junk_mbox'] = 'Junk'; $config['sent_mbox'] = 'Sent'; $config['trash_mbox'] = 'Trash'; $config['create_default_folders'] = true;
* настройка $config['create_default_folders'] = true создает папки по умолчанию, если их нет:
- Drafts — Черновики.
- Junk — СПАМ.
- Sent — Отправленные.
- Trash — Корзина.
* Без данной настройки, если не создавались папки другим клиентом, веб-клиент будет выдавать ошибки при перемещении писем, например, при их удалении.
Задаем владельца apache на папку портала:
chown -R apache:apache /usr/share/nginx/html/webmail
Создаем в MariaDB базу для roundcubemail:
mysql -uroot -p
> CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; > GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'roundcube123'; > quit
И загружаем в созданную базу данные:
mysql -uroot -p roundcubemail < /usr/share/nginx/html/webmail/SQL/mysql.initial.sql
Устанавливаем компоненты, необходимые для работы Roundcube:
dnf install php-pear php-mcrypt php-intl php-ldap php-pear-Net-SMTP php-gd php-zip -y
Установим ImageMagick:
dnf install ImageMagick ImageMagick-devel -y
После устанавливаем пакеты, необходимые для сборки imagick:
dnf install php-devel php-pear make
Собираем imagick:
pecl install imagick
Создаем файл с расширением php:
nano /etc/php.d/20-imagick.ini
extension=imagick.so
Перезапускаем php-fpm или apache:
systemctl restart php-fpm
Настроим php:
nano /etc/php.ini
date.timezone = "Europe/Moscow" ... post_max_size = 30M ... upload_max_filesize = 30M
* в данном примере мы задаем московское время и возможность загружать файл размером в 30 Мб (это будет максимальным объемом вложений, которые можно отправлять через веб-интерфейс).
Перезагружаем php-fpm:
systemctl restart php-fpm
Настроим nginx:
nano /etc/nginx/nginx.conf
Добавим строку в раздел http:
http { ... client_max_body_size 30M; ...
* данной настройкой мы также разрешим загрузку файлов размером 30 Мб.
Перезапустим nginx для применения настройки:
systemctl restart nginx
Теперь открываем браузер и переходим по адресу http://<IP-адрес сервера>/webmail/installer/. В самом низу нажимаем по кнопке Next. Если кнопка будет неактивна, проверяем, что нет ошибок (NOT OK).
На следующей странице проверяем, что все пункты находятся в состоянии OK. Установка выполнена.
Открываем конфигурационный файл roundcube:
nano /usr/share/nginx/html/webmail/config/config.inc.php
Запрещаем установку портала:
$config['enable_installer'] = false;
После удаляем папку с установочными скриптами:
rm -rf /usr/share/nginx/html/webmail/installer
И заходим в браузере по адресу http://<IP-адрес сервера>/webmail/. Вводим в качестве логина адрес почты созданного пользователя и его пароль.
8. Защищаемся от вирусов и СПАМа
Антивирус требует много ресурсов. Будьте готовы, что после его запуска сервер начнет работать медленнее и понадобится добавить ресурсы.
Установка и настройка Clamav + Amavisd
Устанавливаем необходимые для работы антивируса и антиспама компоненты:
dnf install amavisd-new clamd perl-Digest-SHA1 clamav-update
Открываем конфигурационный файл amavis:
nano /etc/amavisd/amavisd.conf
Редактируем следующие параметры:
$mydomain = 'putyato.ru'; ... $myhostname = 'mail.putyato.ru';
* данные опции не обязательны, но они определяют сообщения в заголовках. $mydomain — домен, в котором находится сервер; $myhostname — имя сервера.
... а также добавим:
$allowed_header_tests{'multiple'} = 0; $allowed_header_tests{'missing'} = 0;
* данные опции позволят программе Outlook без ошибок отправлять тестовое сообщение.
Открываем конфигурационный файл clamd:
nano /etc/clamd.d/scan.conf
Снимаем комментарий для опции TCPSocket:
TCPSocket 3310
Обновляем антивирусную базу командой:
freshclam
Если мы получим ошибку:
... ERROR: Database update process failed: Forbidden; Blocked by CDN ERROR: Update failed.
Открываем файл:
nano /etc/freshclam.conf
Комментируем строку:
##DatabaseMirror database.clamav.net
И добавляем:
PrivateMirror https://packages.microsoft.com/clamav/
Удаляем старую информацию об обновлениях:
rm -f /var/lib/clamav/freshclam.dat
Запускаем обновление:
freshclam
Теперь разрешаем запуск антивируса и amavis:
systemctl enable clamd@scan --now systemctl enable amavisd --now
Настройка Postfix
Добавляем в postfix:
nano /etc/postfix/main.cf
content_filter = scan:[127.0.0.1]:10024 receive_override_options = no_address_mappings
* где content_filter указывает на приложение, которое будет сканировать сообщения; receive_override_options позволяет увидеть оригинальные email адреса писем с вирусами.
Теперь редактируем master.cf:
nano /etc/postfix/master.cf
Дописываем следующее:
scan unix - - n - 16 smtp -o smtp_send_xforward_command=yes -o smtp_enforce_tls=no 127.0.0.1:10025 inet n - n - 16 smtpd -o content_filter= -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks -o smtpd_helo_restrictions= -o smtpd_client_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks_style=host -o smtpd_authorized_xforward_hosts=127.0.0.0/8
* итак, данной настройкой мы создадим два вспомогательных сервиса scan и 127.0.0.1:10025 (сервис без имени, он просто будет слушать на порту 10025 — это порт по умолчанию, на который отправляет сообщение amavis после выполнения проверки). Также, мы используем следующие опции:
- smtp_send_xforward_command — передавать ли в сканирование сообщение с исходными именем клиента и IP-адресом. В данном примере, да.
- smtp_enforce_tls — требовать ли TLS.
- content_filter — приложение для сканирования. В данном примере сканирование отключено.
- receive_override_options переопределяет опции в main.cf. В нашем случае, no_unknown_recipient_checks отключает попытки выяснить, является ли получатель неизвестным; no_header_body_checks отключает проверки заголовков и тала писем.
- пустые значения для smtpd_helo_restrictions, smtpd_client_restrictions, smtpd_sender_restrictions отключают ограничения для данных опций.
- smtpd_recipient_restrictions — контролирует ответ Postfix на SMTP-команду RCPT TO. Здесь мы разрешаем только соединения от узлов, перечисленных в mynetworks.
- mynetworks_style=host указывает postfix, что он должен пересылать почту только с локального компьютера.
- smtpd_authorized_xforward_hosts укажет, какие удаленные клиенты могут использовать XFORWARD. В данном случае локальный компьютер.
Перезапускаем postfix:
systemctl restart postfix
Настройка обновлений антивируса и amavis
Обновляем вручную антивирусную базу командой:
freshclam
Для обновления базы антиспама:
sa-update --nogpg --verbose
Для настройки автоматического обновления, редактируем cron:
crontab -e
15 3 * * * /bin/freshclam 30 3 * * * /bin/sa-update
* в данном примере, каждый день в 03:15 будет запускаться процесс обновления clamav, а в 03:30 — антиспама.
Проверка
Для проверки антивируса отправляем сообщение со следующим содержимым:
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
Письмо не должно дойти, а в логе (/var/log/maillog) мы увидим строку:
... amavis[17688]: (17688-04) '''Blocked INFECTED''' (Eicar-Signature) {DiscardedOutbound,Quarantined}, MYNETS LOCAL ... ... relay=127.0.0.1[127.0.0.1]:10024, delay=0.25, delays=0.19/0/0/0.06, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=17688-04 - '''INFECTED: Eicar-Signature''')
Для проверки работы контентного антиспама, отправляем письмо со следующим содержимым:
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
В итоге, письмо не должно прийти, а в логах мы увидим:
... amavis[17689]: (17689-04) '''Blocked SPAM''' {DiscardedOutbound,Quarantined}, MYNETS LOCAL ... ... status=sent (250 2.7.0 Ok, '''discarded, id=17689-04 - spam''')
Пересылка СПАМа и вирусов на другой ящик
Все письма со спамом и вирусами будут перемещаться в карантин. Если мы хотим перенаправлять все подобные сообщения на специальный ящик, то необходимо настроить amavis.
Открываем конфигурационный файл:
nano /etc/amavisd/amavisd.conf
Добавляем такие опции:
$spam_quarantine_to = "spam\@putyato.ru"; ... $virus_quarantine_to = "virus\@putyato.ru";
* где $spam_quarantine_to указываем на адрес для перенаправления СПАМ-писем; $virus_quarantine_to — почта для писем с обнаруженными вирусами.
После перезагрузим amavisd:
systemctl restart amavisd
Пробуем отправить сообщения с тестовыми сигнатурами на СПАМ и вирус — письма должны быть перенаправлены на указанные адреса.
Сохранения СПАМа в папку SPAM пользователя
Выше мы рассмотрели возможность перенаправления всех нежелательных писем на другой почтовый ящик. Данный способ удобен, что пользователи не видят ненужные сообщения, но накладывает дополнительную обязанность на администратора по поиску писем, которые ложно были определены как СПАМ. В данном подразделе мы рассмотрим альтернативу — сохранение нежелательных сообщений в специальной папке.
Устанавливаем пакет dovecot-pigeonhole:
dnf install dovecot-pigeonhole -y
Открываем на редактирование файл:
nano /etc/dovecot/conf.d/90-sieve.conf
Комментируем и добавляем строки:
#sieve = file:~/sieve;active=~/.dovecot.sieve sieve = /etc/dovecot/sieve/default.sieve
* закомментированная строка указывала, что файл с настройками находится в домашней директории каждого пользователя. Мы же будем делать централизованный конфиг в файле /etc/dovecot/sieve/default.sieve.
Открываем файл /etc/dovecot/conf.d/15-lda.conf и редактируем:
nano /etc/dovecot/conf.d/15-lda.conf
protocol lda { ... mail_plugins = $mail_plugins sieve }
* в данном примере мы добавили плагин sieve. Также необходимо со строки снять комментарий, если он был.
Открываем файл /etc/dovecot/conf.d/20-lmtp.conf и редактируем:
nano /etc/dovecot/conf.d/20-lmtp.conf
protocol lmtp { ... mail_plugins = $mail_plugins sieve }
* также мы добавили плагин sieve + необходимо со строки снять комментарий, если он есть.
Создаем каталог и файл с настройками sieve:
mkdir /etc/dovecot/sieve
nano /etc/dovecot/sieve/default.sieve
require "fileinto"; if header :contains "X-Spam-Flag" "YES" { fileinto "Junk"; }
* в данном примере мы ищем в заголовках X-Spam-Flag и отправляем такие письма в папку Junk.
Задаем владельца для созданных каталога и файла:
chown -R vmail:vmail /etc/dovecot/sieve
Перезапускаем dovecot:
systemctl restart dovecot
Открываем конфиг amavis:
nano /etc/amavisd/amavisd.conf
Редактируем строку:
$final_spam_destiny = D_PASS;
* по умолчанию стоит значение D_DISCARD, что означает, что сообщения будут отклонятся. Нам же нужно D_PASS — пропускать.
Перезапускаем amavisd:
systemctl restart amavisd
Обучение антиспама
Мы установили amavis, который проверяет почту на СПАМ средствами spamassassin. Последний без обучения, практически, бесполезен. Синтаксис команды для обучения следующий:
sa-learn --spam <папка с нежелательными письмами> sa-learn --ham <папка письмами, которые ошибочно определены как СПАМ>
Таким образом, первая команда укажет spamassassin какие письма являются нежелательными, а вторая — не несущими рекламный характер.
Хорошей практикой будет договориться с пользователями о ручном помещении нежелательной почты из входящих в папку СПАМ. Тогда мы сможем пройтись скриптом по всем ящиками на сервере и обучать антиспам. Например, такой командой:
sa-learn --spam /home/mail/dmosk.local/*/{.\&BCEEPwQwBDw-,.Spam,.Junk\ E-mail,.Junk}/cur
* в данном примере мы сказали spamassassin найти в каталогах пользователей папки Спам, Spam, Junk, Junk E-mail (данные каталоги являются типичными для помещения СПАМа) и провести обучение.
Чтобы минимизировать количество ложных срабатываний, необходимо проводить обучение с ключом --ham. В нашем примере мы отправляем все нежелательные письма на ящик spam. В таком случае, необходимо вручную находить ложные срабатывания и переносить их в специальную папку, например Ham. Тогда команда для обучения будет такой:
sa-learn --ham /home/mail/putyato.local/spam\@putyato.local/.Ham/cur
Статистику обучения можно посмотреть командой:
sa-learn --dump magic
Черные и белые списки
В настройках amavis мы можем переопределять СПАМ-бал для конкретного отправителя или всего домена. Для этого открываем файл:
nano /etc/amavisd/amavisd.conf
Находим строки:
# read_hash("/var/amavis/sender_scores_sitewide"), { ... }
Внутри фигурных скобок можно создавать новые строки с описанием поведения антиспама.
a) для добавления в белый список.
Присваиваем минусовое значение для бала, например:
{ ... 'example@mail.ru' => -10.0, 'putyato.ru' => -5.0, }
* в данном примере все письма от домена putyato.ru будут получать минус 5 баллов. Таким образом, шансов попасть в СПАМ будет меньше. У всех писем от email example@mail.ru будет отниматься 10 баллов.
b) для добавления в черный список.
В данном случае, мы задаем положительное значение для балла:
{ ... 'putyato.ru' => 5.0, }
После того, как мы внесли правки в наш файл, перезапускаем amavis:
systemctl restart amavisd
9. Антиспам средствами Postfix
Рассмотрим в отдельном разделе защиту от СПАМа средствами самого MTA Postfix.
1. Заголовки
В MTA Postfix встроен свой механизм проверки заголовков входящих сообщений. Правила размещаются в 7 секций, обработка которых выполняется в следующем порядке:
client -> helo -> sender -> relay -> recipient -> data -> end_of_data
Чтобы лучше понять принцип, мы должны знать SMTP-команды при выполнении отправки почты. И так, порядок, следующий:
1. Соединение с сервером.
2. Команда HELO. Приветствие, в котором отправитель называет свое имя, по которому можно проверить, соответствует ли оно правилам именования и своему IP-адресу.
3. MAIL FROM — указывает адрес отправителя. Выполняется для sender и relay.
4. RCPT TO — кому отправляем письмо.
5. DATA — команда сообщает о готовности отправить письмо с заголовками и текстом.
6. END-OF-DATA — отправка письма.
И так, для настройки антиспама в конфигурационный файл main.cf добавляем:
nano /etc/postfix/main.cf
smtpd_client_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_pipelining permit smtpd_helo_restrictions = permit smtpd_sender_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_sender reject_unknown_sender_domain permit smtpd_relay_restrictions = permit smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_non_fqdn_recipient reject_unauth_destination reject_unknown_recipient_domain reject_unverified_recipient permit smtpd_data_restrictions = permit smtpd_end_of_data_restrictions = permit
* где параметры:
1. smtpd_client_restrictions — настройки ограничений при осуществлении клиентских соединений с почтовым сервером.
2. smtpd_helo_restrictions — ограничения в контексте клиентской команды HELO.
3. smtpd_sender_restrictions — ограничения будут применяться во время выполнения клиентской команды MAIL FROM.
4. smtpd_relay_restrictions — ограничения пересылки почты в контексте клиентской команды RCPT TO.
5. smtpd_recipient_restrictions — ограничения в контексте клиентской команды RCPT TO после пересылки (smtpd_relay_restrictions).
6. smtpd_data_restrictions — ограничения будут применяться во время выполнения команды DATA.
7. smtpd_end_of_data_restrictions — ограничения во вреся выполнения команды END-OF-DATA.
... и значения для них:
- permit_mynetworks — разрешает все адреса, перечисленные в настройке mynetworks.
- permit_sasl_authenticated — разрешает запросы всех успешно авторизованных клиентов.
- reject_unauth_pipelining — запрещает отправку писем, которые отправляются заранее (пропуская правильную цепочку сессии SMTP).
- reject_non_fqdn_sender — отклонить соединение, если адрес отправителя указан неправильно (согласно RFC).
- reject_unknown_sender_domain — запрещает запрос, если Postfix не является конечным пунктом назначения для адреса отправителя, а домен MAIL FROM не имеет 1) DNS-записи MX и DNS-записи A или 2) искаженной MX-записи, такой как запись с MX-именем хоста нулевой длины.
- reject_non_fqdn_recipient — запретить соединение, если адрес получателя указан неправильно (согласно RFC).
- reject_unauth_destination — отклонить соединение, если письмо не пересылается согласно правилу relay_domains или сервер не является адресом назначения. Другими словами, запрещает использование нашего сервера в качестве open relay.
- reject_unknown_recipient_domain — отклонить запрос, если Postfix не является конечным пунктом назначения для домена получателя, а домен RCPT TO не имеет 1) DNS-записи MX и DNS-записи A или 2) неверно сформированной MX-записи, такой как запись с именем хоста MX нулевой длины.
- reject_unverified_recipient — отклонить запрос, если известно, что почта на адрес RCPT TO отклоняется или когда адрес получателя не доступен.
- permit — разрешает соединение. Ставим в конец каждого блока ограничений (если ограничения не сработали, то разрешаем).
* это более или менее мягкие правила. Их можно использовать первое время, пока тестируем сервер.
Для усиления защиты добавляем:
smtpd_recipient_restrictions = ... reject_unknown_client_hostname reject_invalid_helo_hostname reject_non_fqdn_helo_hostname reject_unknown_helo_hostname reject_rbl_client bl.spamcop.net reject_rbl_client cbl.abuseat.org reject_rbl_client dul.ru reject_rbl_client dnsbl.abuse.ch permit
* где:
- reject_unknown_client_hostname — проверяет наличие PRT-записи отправителя и наличие рабочей А-записи в соответствие PTR.
- reject_invalid_helo_hostname — проверяет синтаксис HELO-приветствия.
- reject_non_fqdn_helo_hostname — требует правильного FQDN-имени во время HELO-приветствия.
- reject_unknown_helo_hostname — запрещает представляться именами, для которых нет А-записи или MX.
- reject_rbl_client — проверяет наличие отправителя в черных списках.
* более подробное описание опций для защиты можно найти на странице postfix.org/postconf.5.html.
После внесения всех правок, необходима перезагрузка Postfix:
systemctl restart postfix
2. Проверка SPF
Проверка SPF позволит отбрасывать все попытки отправить сообщения от доменов, которые не прошли валидацию по SPF.
Устанавливаем пакет:
dnf install pypolicyd-spf -y
Открываем конфигурационный файл postfix:
nano /etc/postfix/main.cf
Добавляем опции:
policy-spf_time_limit = 3600s ... smtpd_recipient_restrictions = ... check_policy_service unix:private/policy-spf permit
* где:
- policy-spf_time_limit — устанавливает максимальное количество времени, которое почтовый сервер будет затрачивать на проверку SPF-записи.
- check_policy_service — выполнение дополнительной проверки при приеме почты. В данном примере, политика проверки выполняется в файле private/policy-spf.
Открываем файл:
nano /etc/postfix/master.cf
Добавим строки:
policy-spf unix - n n - - spawn user=nobody argv=/usr/libexec/postfix/policyd-spf
Перезапускаем постфикс:
systemctl restart postfix
По умолчанию, политика блокирует письма, только если владелец домена указал жесткую блокировку (использовал -all, вместо ~all). Если мы хотим указать более жесткую политику, открываем файл:
nano /etc/python-policyd-spf/policyd-spf.conf
Задаем значения для опций HELO_reject и Mail_From_reject:
... HELO_reject = Fail Mail_From_reject = Softfail
* в данном примере мы будем блокировать письма:
- HELO_reject — для приветствий, если администратор домена указал -all.
- Mail_From_reject — для поля From, если администратор домена указал ~all или -all. Это более жесткая политика.
Подробнее информацию об опциях конфигурационного файла policyd-spf.conf можно узнать командой:
man policyd-spf.conf
3. Защита от СПАМа «от себя к себе»
Часто можно наблюдать ситуацию, когда приходит спам от своих же ящиков (или ящиков своего домена, хотя таких почтовых адресов у нас не существует).
Это происходит из-за возможности в поле FROM подставить любой адрес. А адрес от своей организации может внушить доверие, что побудит пользователя откликнуться на нежелательное сообщение.
Для решения проблемы в Postfix нужно добавить простое правило:
nano /etc/postfix/main.cf
smtpd_sender_restrictions = ... check_sender_access hash:/etc/postfix/sender_access permit
Создадим сам файл:
nano /etc/postfix/sender_access
putyato.ru REJECT Relay from putyato.ru are denied
* в данном примере мы будет отклонять все попытки отправить почту с чужих серверов от нашего домена putyato.ru.
Создаем карту:
postmap /etc/postfix/sender_access
Перезапускаем постфикс:
systemctl restart postfix
10. Отправка почты наружу
Для отправки почты на другие почтовые серверы необходимо правильно сконфигурировать сервер, чтобы письма не попадали в СПАМ. Чтобы это сделать, выполняем инструкции ниже.
Настройки DNS для сервера
Многие почтовые серверы делают запросы в систему доменных имен для проверки легитимности почтового сервера, отправляющего почту. При настройке MTA очень важно правильно добавить необходимые записи в DNS.
1. rDNS. Обратная зона используется для проверки соответствия имени сервера в приветствии с именем, которое возвращает NS сервер при запросе по PTR-записи.
И так, для создания записи в обратной зоне, необходимо написать письмо Интернет провайдеру, к сети которого подключен сервер или хостеру, если почтовый сервер настроен на VPS. IP-адрес нашего сервера должен вести на имя, которым приветствуется наш postfix — можно посмотреть командой:
postconf -n smtpd_banner
Если мы получим пустой ответ, то вводим:
postconf -n myhostname
Если и в этот вариант не вернет ответ, вводим:
hostname
2. А-запись. Также необходимо, чтобы имя сервера, которым представляется почтовый сервер разрешалось в IP-адрес.
Для этого заходим в консоль управления зоной нашего домена и создаем запись типа А для сопоставления имени сервера с IP-адресом, на котором слушает запросы данный сервер.
Настройки DNS для домена
Для каждого домена, для которого будем отправлять почту создаем записи:
1. SPF.
SPF-запись - специальная TXT-запись в DNS, в которой указано с каких почтовых серверов может быть отправлена почта для домена. С ее помощью можно снизить общее количество СПАМа, уменьшить вероятность того, что домен будет скомпрометирован и защититься от СПАМа, который использует поле обратного адреса. Расшифровывается как Sender Policy Framework или инфраструктура политики отправителя.
Синтаксис SPF-записи, примерно, следующий:
putyato.ru. IN TXT "v=spf1 +a +mx -all"
* где putyato.ru — домен, для которого настраивается запись; v=spf1 — указатель на то, что эта TXT-запись является SPF версии 1; a разрешает или запрещает отправку от IP-адреса, которому соответствует А-запись самого домена (в данном примере, putyato.ru); mx разрешает или нет отправку от IP-адресов записей MX для нашего домена; -all запрещает отправку писем для всех, кто не прошел проверку (если записать ~all разрешать отправку или нет будет на выбор почтовой системы). знак «+» разрешает (может быть упущен при записи); знак «-» указывает на запрет.
Еще один пример записи:
putyato.ru. IN TXT "v=spf1 ip4:95.95.95.95 include:_spf.mailsystem.net ~all"
* здесь мы прямо указали IP-адрес, с которого можно отправлять почту (ip4), а также все, что включены в запись _spf.mailsystem.net.
2. DMARC.
DMARC-запись - политика обработки почтовых сообщений на основе SPF и DKIM. С помощью нее администратор почты может самостоятельно определять, что делать с письмами, которые не прошли доменную проверку на чужих серверах. Таким образом, не почтовая система делает выбор, как поступить с «плохими» сообщениями, а владелец домена. Настраивается путем создания TXT-записи в DNS. Расшифровывается как Domain-based Message Authentication, Reporting and Conformance.
Работает это так: письмо проверяется по SPF и DKIM. Если оно не проходит по одному из критериев проверки, применяется политика DMARC.
Пример простой DMARC политики следующий:
_dmarc.putyato.ru. 3600 IN TXT "v=DMARC1; p=quarantine; sp=none; pct=100; fo=0; rua=mailto:postmaster@putyato.ru"
- _dmarc.putyato.ru — dmarc запись для домена putyato.ru.
- v=DMARC1 идет как обозначение, что txt-запись относится к DMARC.
- p — политика на домен. Принимаются следующие варианты: none — ничего не делать; quarantine — отправить письмо в СПАМ; reject — отвергнуть письмо.
- sp — политика на субдомены домена. Имеет такие же значения, что и p.
- pct — какой процент сообщений пойдет под правила.
- fo — в каких случаях отправлять отчет. 0 — всегда если не пройден ни один критерий проверки; 1 — если не пройден хотя бы один критерий; d — не пройдена проверка DKIM; s — не пройден SPF.
- rua — почтовый адрес для отчетов.
Так как настройка выполняется только на сервере NS, не имеет значения, для какого почтового сервера ее настраивать. DMARC работает для Postfix, Exim, Exchange и многих других почтовых систем. Бесплатные почтовые сервисы от Mail RU Group, Яндекс, Google и так далее также поддерживают политики DMARC, обрабатывая сообщения в соответствии с настройками.
Подробнейшая инструкция по работе с DMARC на datatracker.ietf.org. Для проверки правильности настройки политики, можно воспользоваться сторонними сервисами, например, mxtoolbox.com.
3. DKIM
Описание как настроить, будет ниже.
Для проверки корректности настройки сервера, воспользуемся ресурсами:
11. Настройка DKIM
Подпись писем не является обязательной, но помогает не попадать в СПАМ. DKIM настраивается для каждого домена, а также должна создаваться специальная запись в DNS. Рассмотрим создание и настройку DKIM в amavisd.
Для удобства, создаем переменную с нашим почтовым доменом, для которого будем создавать подпись dkim:
DOMAIN=putyato.ru
Создаем каталог для хранения ключей:
mkdir -p /var/lib/dkim
Генерируем последовательность для нашего домена:
amavisd genrsa /var/lib/dkim/${DOMAIN}.pem 1024
Задаем права на созданный файл:
chown amavis:amavis /var/lib/dkim/*.pem chmod 0400 /var/lib/dkim/*.pem
Открываем конфигурационный файл amavisd:
nano /etc/amavisd/amavisd.conf
Редактируем запись:
#$inet_socket_port = 10024; $inet_socket_port = [10024,10026];
* в данном примере мы закомментировали первую строку и раскомментировали вторую. Это укажет amavis, что он должен запускаться и работать на двух портах.
Добавляем записи:
dkim_key('putyato.ru', "dkim", "/var/lib/dkim/putyato.ru.pem"); @dkim_signature_options_bysender_maps = ( { "putyato.ru" => { d => "putyato.ru", a => 'rsa-sha256', ttl => 10*24*3600 }, });
* где putyato.ru — домен, для которого мы настраиваем dkim; /var/lib/dkim/dmosk.ru.pem — путь до сгенерированного файла с последовательностью.
Проверяем, чтобы значение данных переменных было 1:
$enable_dkim_verification = 1; $enable_dkim_signing = 1;
Перезапускаем amavisd:
systemctl restart amavisd
Посмотреть DKIM последовательность для нового домена можно командой:
amavisd -c /etc/amavisd/amavisd.conf showkeys
Мы должны увидеть что-то на подобие:
; key#1 1024 bits, i=dkim, d=putyato.ru, /var/lib/dkim/putyato.ru.pem dkim._domainkey.putyato.ru. 3600 TXT ( "v=DKIM1; p=" "MIGfMA0SDFqGSIb3DQEBAQUAA4GNADCBiQKBgQC44iOK+99mYBxsnIl1Co8n/Oeg" "4+x90sxqWzoGW42d/GCP4wiYqVqncc37a2S5Berv0OdoCGcmkDkKWh4CHhFD4blk" "x6eMYXsp1unAdo2mk/OVK7M2ApraIkh1jVbGBZrREVZYTE+uPOwtAbXEeRLG/Vz5" "zyQuIpwY2Nx3IgEMgwIDAQAB")
Теперь нам нужно на основе данного вывода создать в DNS запись TXT. В данном примере, нужно создать запись c именем dkim._domainkey в зоне dmosk.ru и значением "v=DKIM1; p=MIGfMA0SD...wIDAQAB".
Проверить корректность настройки DKIM можно командой:
amavisd -c /etc/amavisd/amavisd.conf testkeys
Переходим к настройке Postfix. Мы должны добавить отправку всех исходящих писем на проверку в amavis на порт 10026 и принимать обратно письма на порт 10027.
Открываем файл:
nano /etc/postfix/master.cf
Отредактируем submission и smtps, добавив content_filter:
smtp inet n - n - - smtpd -o content_filter=scan:[127.0.0.1]:10026 submission inet n - n - - smtpd -o content_filter=scan:[127.0.0.1]:10026 ... smtps inet n - n - - smtpd -o content_filter=scan:[127.0.0.1]:10026 ...
И добавим:
127.0.0.1:10027 inet n - n - 16 smtpd -o content_filter= -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks -o smtpd_helo_restrictions= -o smtpd_client_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks_style=host -o smtpd_authorized_xforward_hosts=127.0.0.0/8
Перезапускаем postfix:
systemctl restart postfix
Настраиваем Roundcube:
nano /usr/share/nginx/html/webmail/config/config.inc.php
Находим строки:
$config['smtp_server'] = ''; ... $config['smtp_port'] = 25;
... и меняем ее на:
$config['smtp_server'] = 'tls://localhost'; ... $config['smtp_port'] = 587;
* в данном примере мы указали, что соединение для отправки почты должно быть защищенным. Это важно для нашей настройки DKIM.
Пробуем отправить письмо — в заголовках мы должны увидеть:
dkim=pass header.d=putyato.ru
12. Автоматическая настройка почтовых клиентов
Для автоматического конфигурирования почтовых клиентов необходимо настроить сервис autodiscover. Для этого настраиваем веб-сервер, который будет возвращать почтовые настройки для домена. Описание даноого процесса по настройки будет отдельно.
13. Папки на русском в Outlook
По умолчанию, все почтовые клиенты, кроме Outlook распознают служебные папки IMAP:
- Drafts — черновики.
- Junk — СПАМ.
- Sent — отправленные.
- Trash — удаленные.
Данные каталоги переводятся на русский язык и корректно отображаются в клиенте. В Outlook эти папки отображаются как есть — на английском языке.
Для решения проблемы мы должны открыть файл:
nano /etc/dovecot/conf.d/15-mailboxes.conf
Найти блок настроек namespace inbox. Для каждого из служебного каталога настроить следующее:
namespace inbox { ... mailbox Черновики { auto = subscribe special_use = \Drafts } mailbox Drafts { auto = no special_use = \Drafts } mailbox Спам { auto = subscribe special_use = \Junk } mailbox Junk { auto = no special_use = \Junk } mailbox Spam { auto = no special_use = \Junk } mailbox "Junk E-mail" { auto = no special_use = \Junk } mailbox Удаленные { auto = subscribe special_use = \Trash } mailbox Trash { auto = no special_use = \Trash } mailbox "Deleted Messages" { auto = no special_use = \Trash } mailbox Отправленные { auto = subscribe special_use = \Sent } mailbox Sent { auto = no special_use = \Sent } mailbox "Sent Messages" { auto = no special_use = \Sent } mailbox "Sent Items" { auto = no special_use = \Sent } .. }
* и так, мы задали несколько вариантов служебных каталогов:
- Черновики — на сервере могут быть папки Черновики и Drafts. По умолчанию отображается и создается Черновики.
- Спам — на сервере Спам, Junk, Spam, Junk E-mail.
- Удаленные — на сервере Удаленные, Trash, Deleted Messages.
- Отправленные — на сервере Отправленные, Sent, Sent Messages, Sent Items.
Для применения настроек перезапускаем dovecot:
systemctl restart dovecot
Теперь нам нужно отредактировать roundcube:
nano /usr/share/nginx/html/webmail/config/config.inc.php
//$config['drafts_mbox'] = 'Drafts'; //$config['junk_mbox'] = 'Junk'; //$config['sent_mbox'] = 'Sent'; //$config['trash_mbox'] = 'Trash'; //$config['create_default_folders'] = true;
* необходимо закомментировать или удалить эти опции. В противном случае, при первом входе в roundcube он создаст каталоги на английском, что приведет к проблемам в Outlook.
14. Разное
Рассмотрим дополнительные настройки для нашего сервера.
Настройка ограничений
Также важно настроить некоторые ограничения, например:
- максимальный размер вложения.
- количество сообщений, которое можно отправить за определенный период времени.
- настройка очереди (время хранения писем).
- таймауты отправки.
Подробнее, информацию можно найти ниже.
Изменения делаем в конфигурационном файле:
nano /etc/postfix/main.cf
1. Размер почтового ящика
Для установки квоты на почтовые ящики редактируем следующее:
mailbox_size_limit = 209715200 virtual_mailbox_limit = 209715200
* значение указывается в байтах. В данном примере установлены квоты для почтовых ящиков и виртуальных почтовых ящиков в 200 мб. Для удобства, воспользуйтесь конвертером мегабайт.
Чтобы снять ограничения, можно выставить значения в 0:
mailbox_size_limit = 0 virtual_mailbox_limit = 0
2. Размер отправляемого сообщения
Открываем конфигурационный файл, находим и правим следующее (если строки нет, создаем):
message_size_limit = 73400320
* в данном примере установлено ограничение на размер письма в 70 мб.
Необходимо, чтобы данный размер не превышал размер почтового ящика (mailbox_size_limit и virtual_mailbox_limit, которые по умолчанию имеют значения 51200000 или 50 мб), в противном случае, в логе мы увидим ошибку fatal: main.cf configuration error: mailbox_size_limit is smaller than message_size_limit.
Для этого можно либо задать значения равные (или больше) message_size_limit:
message_size_limit = 73400320 mailbox_size_limit = 73400320 virtual_mailbox_limit = 73400320
... либо отключить ограничения:
message_size_limit = 73400320 mailbox_size_limit = 0 virtual_mailbox_limit = 0
3. Количество сообщений и одновременных подключений
В конфигурационном файле добавляем такие строки:
anvil_rate_time_unit = 60s smtpd_client_message_rate_limit = 200 smtpd_client_recipient_rate_limit = 60 smtpd_client_connection_count_limit = 20 smtpd_client_connection_rate_limit = 40
* в данном примере мы установили следующие ограничения на количество отправляемых писем:
- anvil_rate_time_unit — параметр расчетного времени. Именно от него будут вести отчет другие значения. По умолчанию также равен 60s.
- smtpd_client_message_rate_limit — сколько клиенту можно отправлять сообщений за anvil_rate_time_unit. По умолчанию 0, то есть, ограничений нет.
- smtpd_client_recipient_rate_limit — максимальное количество получателей за anvil_rate_time_unit. По умолчанию 0, то есть, ограничений нет.
- smtpd_client_connection_count_limit — количество одновременно разрешенных подключений для клиента. По умолчанию 50.
- smtpd_client_connection_rate_limit — максимальное количество коннектов, разрешенных для клиента за anvil_rate_time_unit. По умолчанию 0, то есть, ограничений нет.
4. Очередь сообщений
queue_run_delay = 5m minimal_backoff_time = 10m maximal_backoff_time = 15m maximal_queue_lifetime = 1d
* где queue_run_delay задает время, как часто сообщения из очереди будут отправляться повторно; minimal_backoff_time устанавливает время, на которое будет отложена отправка сообщений, которые не были отправлены по причине временных неисправностей (например, принимающий сервер не отвечает или просит повторить запрос позже), но не позднее maximal_backoff_time; параметр maximal_queue_lifetime установит, через какой период перестать делать попытки при отправке сообщения и вернуть его отправителю с ошибкой.
5. Таймаут на отправку сообщений
smtp_data_done_timeout = 600s smtp_data_init_timeout = 120s smtp_data_xfer_timeout = 180s
* где smtp_data_done_timeout — ограничение времени для отправки сообщения; smtp_data_init_timeout — ограничение времени для отправки команды SMTP DATA и для получения ответа удаленного SMTP-сервера; smtp_data_xfer_timeout — ограничение времени для отправки содержимого сообщений.
6. Отправка сообщений об ошибках (4xx or 5xx)
smtpd_error_sleep_time = 3s smtpd_soft_error_limit = 5 smtpd_hard_error_limit = 10
* где:
- smtpd_error_sleep_time — задержка перед отправкой сообщения об ошибке (4xx or 5xx). По умолчанию 1s.
- smtpd_soft_error_limit — количество ошибок, которые должны быть сделаны, прежде чем наш сервер начнет замедлять ответы. По умолчанию 10.
- smtpd_hard_error_limit — максимальное количество ошибок, которые может сделать удаленный сервер SMTP. После с ним будет разорвана сессия. По умолчанию 20.
552 5.3.4 message size exceeds fixed limit
Если сталкиваемся с сообщением «552 5.3.4 message size exceeds fixed limit» (переводится как «Размер сообщения превышает установленные ограничения»), значит отправляемое письмо не вписывается в установленные лимиты. Чтобы исправить ситуацию, уменьшаем размер сообщения или редактируем лимиты (пункты 1 и 2).
То есть, размер message_size_limit не должен превышать mailbox_size_limit и virtual_mailbox_limit.
Смена email адреса
Предположим, мы сделали ошибку в написании адреса электронной почты, но не хотим удалять учетную запись и создавать ее по новой. Рассмотрим смену email-адреса на примере sekretar@putyato.ru -> secretar@putyato.ru.
Нам нужно внести изменения в базу данных — для этого заходим в оболочку sql:
mysql -uroot -p
Вводим пароль, который создавали после установки СУБД.
Используем базу postfix:
> use postfix
Редактируем алиасы командой:
> UPDATE alias SET `address`='secretar@putyato.ru', `goto`=REPLACE(`goto`, 'sekretar@putyato.ru', 'secretar@putyato.ru') WHERE `address`='sekretar@putyato.ru';
Редактируем почтовый ящик:
> UPDATE mailbox SET `username`='secretar@putyato.ru', `local_part`='secretar', `maildir`=REPLACE(`maildir`, '/sekretar/', '/secretar/') WHERE `username`='sekretar@putyato.ru';
И квоту:
> UPDATE quota2 SET `username`='secretar@putyato.ru' WHERE `username`='sekretar@putyato.ru';
С базой данных закончили — выходим из sql:
> quit
Переходим в каталог с почтовыми ящиками пользователей для нашего домена:
cd /home/mail/putyato.ru/
Перемещаем папку с почтой старого ящика в новый:
mv sekretar@dmosk.ru secretar@putyato.ru
Проверяем работу через веб-интерфейс. Если используем почтовый клиент, меняем настройки для использования нового email-адреса.
15. Возможные проблемы
Рассмотрим некоторые проблемы, с которыми столкнулся я.
1. Не подключиться к серверу по IMAP в Outlook на старых системах Windows
При попытке подключиться к серверу мы можем увидеть ошибку «Невозможно установить безопасное соединение с сервером «IMAP».
Причина: в старых системах используется по умолчанию TLS 1.0, поддержка которого уже отсутствует.
Решение: необходимо выполнить 3 действия.
1. Устанавливаем обновление KB3140245. (https://www.catalog.update.microsoft.com/search.aspx?q=kb3140245)
2. Создаем две ветки реестра:
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\TLS 1.1\Client
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\TLS 1.2\Client
Это можно выполнить вручную в утилите regedit или ввести команды:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\TLS 1.1\Client" reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\TLS 1.2\Client"
* командную строку необходимо открыть от администратора.
В этих ветках создаем параметр DisabledByDefault с типом DWORD (32 бита) и значением 0. Это можно выполнить командами:
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\TLS 1.1\Client" /v DisabledByDefault /t REG_DWORD /d 0 reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\Schannel\Protocols\TLS 1.2\Client" /v DisabledByDefault /t REG_DWORD /d 0
3. Перезагружаем компьютер.
2. Roundcube authentification failed
При попытке отправки письма программа выдает ошибку аутентификации.
Причина: ошибка при передаче пароля самой программой Roundcube. Это происходит, если последний установлен на сервере, который указан в настройках mynetworks сервиса postfix. Проблема в том, что узлы mynetworks проходят аутентификацию без пароля, а если принудительно передать пароль, MTA выдаст ошибку.
Решение: необходимо отредактировать конфигурационный файл Roundcube.
Открываем файл:
nano /var/www/html/webmail/config/config.inc.php
Находим опцию:
$config['smtp_pass'] = '%p';
И приводим к виду:
$config['smtp_pass'] = '';
3. Couldn't create mailbox list lock
Мы можем столкнуться с проблемой сохранения писем в некоторых почтовых каталогах пользователя. При этом в логах сервера можно увидеть ошибку:
... couldn't create mailbox list lock ...
Причина: некоторые файловые системы (например, которые используются в облачных дисках) не поддерживают создание файлов блокировки.
Решение: пробуем поиграть с методами блокировки dovecot. Открываем файл:
nano /etc/dovecot/conf.d/10-mail.conf
Находим опцию lock_method и пробуем присвоить разные методы. Доступны 3 варианта:
- fcntl.
- flock.
- dotlock.
В моем случае проблема была решена данной настройкой:
lock_method = dotlock
* важно иметь ввиду, что данный вид блокировки очень медленный и при нагрузках могут возникнуть проблемы. Обязательно следим за сервером некоторое время после смены настройки.