Данная статья описывает настройку почтового сервера на ОС FreeBSD ( у меня стоит версия 11.1-STABLE ) на базе Exim в качестве SMTP сервера с поддержкой SpamAssasin и ClamAV, Dovecot в качестве POP3 / IMAP сервера, поддержкой SSL и веб интерфейсами Vexim для упрвавления ящиками и Roundcube в качестве почтового веб клиента. Данные будем хранить в MySQL

Установка Web сервера и сервера баз данных

Ставим nginx
# cd /usr/ports/www/nginx
# make config-recursive
# make install clean

в /etc/rc.conf добавляем:
nginx_enable="YES"

Ставим MySQL ( я выбрал MariaDB 10.1 )
# cd /usr/ports/databases/mariadb101-server
# make config-recursive
# make install clean

в /etc/rc.conf добавляем:
mysql_enable="YES"
Запускаем MySQL
# /usr/local/etc/rc.d/mysql-server start

Задаем пароль для root в MySQL ( в скобках сам пароль )
# mysqladmin -u root password 'password'

Ставим PHP ( отмечаем FPM )
# cd /usr/ports/lang/php71
# make config-recursive
# make install clean

в /etc/rc.conf добавляем:
php_fpm_enable="YES"

Приводим файл /usr/local/etc/php-fpm.conf к такмоу виду:
[global]
pid = run/php-fpm.pid
error_log = /var/log/php-fpm.log
events.mechanism = kqueue
include=/usr/local/etc/php-fpm.d/*.conf

Редактируем файл пула
# ee /usr/local/etc/php-fpm.d/www.conf
и приводим к такому виду
[www]
user = www
group = www
listen = /tmp/www.sock
listen.backlog = -1
listen.owner = www
listen.group = www
listen.mode = 0666
pm.status_path = /status
ping.path = /ping
pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 5
pm.max_requests = 5000
security.limit_extensions = .php
chdir = /usr/local/www/
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
php_admin_value[cgi.fix_pathinfo] = 0
php_admin_value[open_basedir] = /usr/local/www:/tmp:/usr/local/share/pear:/usr/local/mail:/var/www
php_admin_value[error_log] = /usr/local/www/logs/php-fpm-error.log
php_admin_value[memory_limit] = 128M
php_admin_value[upload_max_filesize] = 16G
php_admin_value[post_max_size] = 16G
php_admin_value[max_input_time] = -1
php_admin_value[max_execution_time] = 0
php_admin_value[output_buffering] = Off
php_admin_value[disable_functions] = escapeshellarg,escapeshellcmd,exec,ini_alter,parse_ini_file,passthru,pcntl_exec,popen,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,show_source,shell_exec,symlink,system

Запускаем PHP-FPM:
# /usr/local/etc/rc.d/php-fpm start

Установка и настройка Vexim

Ставим Vexim (отмечаем MySQL):
# cd /usr/ports/mail/vexim/
# make config-recursive
# make install clean

Ставим модуль p5-DBD-mysql
# cd /usr/ports/databases/p5-DBD-mysql
# make config-recursive
# make install clean

Заходим в MySQL и создаем базу для Vexim
# mysql -u root -p

Вводим ранее установленный пароль для root

Создаем пользователя для Vexim
CREATE USER 'vexim'@'localhost' IDENTIFIED BY 'PASSWORD';

Устанавливаем тип таблиц и прочие настройки
SET storage_engine=INNODB;
SET GLOBAL innodb_file_per_table=1, innodb_file_format=Barracuda, innodb_large_prefix=1;

Создаем базу
CREATE DATABASE IF NOT EXISTS `vexim` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_general_ci`;

Предоставляем привилегии на базу для пользователя vexim
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER, LOCK TABLES, REFERENCES, TRIGGER ON `vexim`.* TO 'vexim'@'localhost';

Выходим из MySQL
\q

Заливаем дамп
# mysql -p vexim < /usr/local/share/vexim/mysql.sql

получаем логин и пароль
A site administrator user has been created with the following credentials:

User name: siteadmin
Password: PASSWORD

Создаем каталог с виртуальными хостами для nginx
# mkdir -p /usr/local/etc/nginx/vhosts

Приводим /usr/local/etc/nginx/nginx.conf к такому виду:
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# PHP-FPM
upstream php-fpm {
server unix:/tmp/www.sock;
}
include /usr/local/etc/nginx/vhosts/*;
}

Делаем виртуальный хост в nginx для Vexim
# ee /usr/local/etc/nginx/vhosts/exim.deathstar.name и приводим к такому виду
{
listen 80;
#listen 443 ssl;
#ssl on;
#ssl_certificate /usr/local/etc/letsencrypt/live/exim.deathstar.name/fullchain.pem;
#ssl_certificate_key /usr/local/etc/letsencrypt/live/exim.deathstar.name/privkey.pem;
server_name exim.deathstar.name;
access_log /var/log/nginx/exim.deathstar.name_access.log;
error_log /var/log/nginx/exim.deathstar.name_error.log;
root /usr/local/www/vexim;
index index.php;
charset utf-8;
location /.well-known/acme-challenge {
allow all;
auth_basic off;
root /tmp/;
}
location ~ \.php$ {
fastcgi_pass php-fpm;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /usr/local/etc/nginx/fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}

Копируем конфиг vexim
# cp /usr/local/www/vexim/config/variables.php.example /usr/local/www/vexim/config/variables.php
и прописываем в нем пароль к БД
$sqlserver = "localhost";
$sqltype = "mysql";
$sqldb = "vexim";
$sqluser = "vexim";
$sqlpass = "PASSWORD";

и путь к каталогу Mailroot
$mailroot = "/usr/local/mail/"

Создаем группу и пользователя exim:
# pw groupadd vexim -g 90
# pw useradd vexim -u 90 -g vexim -d /usr/local/mail -m -s /nonexistant

Установка и настройка Exim ( с поддержкой SpamAssasin и ClamAV )

Устанавливаем Exim ( отмечаем опцию SA-EXIM для работы SpamAssasin , MySQL , DMARC , SPF ) :
# cd /usr/ports/mail/exim
# make config-recursive
# make install clean

Добавляем в /etc/rc.conf:
exim_enable="YES"

Копируем и правим конфиги
# cd /usr/local/etc/exim/
# cp /usr/local/share/doc/vexim/docs/*.conf ./
# cp /usr/local/share/doc/vexim/docs/configure ./
# ee /usr/local/etc/exim/configure

Находим:
trusted_users = avleen:www-data
и удаляем avleen и www-data .Остается www:
trusted_users = www

Раскомментируем
tls_on_connect_ports = 465

Находим блок #TLS и приводим к такому виду
# TLS
tls_advertise_hosts = *
tls_certificate = /usr/local/etc/exim/exim.crt
tls_privatekey = /usr/local/etc/exim/exim.key
tls_dhparam = /usr/local/etc/exim/dhparam.pem

Находим закоментированную строку, отвечающую за подключение к MySQL серверу,раскоментируем ее и поставим там свой пароль:
hide mysql_servers = localhost::(/tmp/mysql.sock)/vexim/vexim/PASSWORD

Изменяем путь к антивирусу ClamAV:
av_scanner = clamd:/var/run/clamav/clamd
и меняем на
av_scanner = clamd:/var/run/clamav/clamd.sock

Редактируем /usr/local/etc/exim/vexim-acl-check-content.conf
# ee /usr/local/etc/exim/vexim-acl-check-content.conf
и закоментируем или удаляем строки ( так как в Exim 4.88 demime выпилили ):
deny message = This message contains a MIME error ($demime_reason)
demime = *
condition = ${if >{$demime_errorlevel}{2}{1}{0}}
deny message = This domain has a policy of not accepting certain types of attachments \
in mail as they may contain a virus. This mail has a file with a .$found_extension \
attachment and is not accepted. If you have a legitimate need to send \
this particular attachment, send it in a compressed archive, and it will \
then be forwarded to the recipient.
demime = ade:adep:adp:bas:bat:chm:cmd:cnf:com:cpl:crt:dll:hlp:hta:inf:ins:isp:js:jse:lnk:mad:maf:mag:mam:maq:mar:mas:mat:mav:maw:ocx:pcd:pif:reg:scf:scr:sct:vbe:vbs:wsc:wsf:wsh:url:xnk

Генерируем /usr/local/etc/exim/dhparam.pem
<code# >openssl dhparam -out /usr/local/etc/exim/dhparam.pem 4096

Добавляем в /etc/rc.conf
spamd_enable="YES" и запускаем
# sa-update
# /usr/local/etc/rc.d/sa-spamd start

Ставим ClamAV:
# cd /usr/ports/security/clamav
# make config-recursive
# make install clean

Добавляем в /etc/rc.conf:
clamav_freshclam_enable="YES"
clamav_clamd_enable="YES

запускаем ClamAV
# /usr/local/etc/rc.d/clamav-clamd start

Запускаем обновление баз ClamAV
# freshclam
# /usr/local/etc/rc.d/clamav-freshclam start

Установка и настройка Dovecot

Устанавливаем Dovecot ( отмечаем MySQL ):
# cd /usr/ports/mail/dovecot
# make config-recursive
# make install clean

Добавляем в /etc/rc.conf:
dovecot_enable="YES"

Копируем конфиги:
# cp -R /usr/local/etc/dovecot/example-config/* /usr/local/etc/dovecot

Настраиваем подключение к MySQL:
# ee /usr/local/etc/dovecot/dovecot-sql.conf.ext

И добавляем строки
driver = mysql
connect = host=localhost user=vexim password=PASSWORD dbname=vexim
default_pass_scheme = CRYPT
password_query = SELECT `username` AS `user`, `crypt` AS `password`, `pop` AS `userdb_home`, `uid` AS `userdb_uid`, `gid` AS `userdb_gid` FROM `users` WHERE `username` = '%u'
user_query = SELECT pop as home, uid, gid FROM users WHERE username = '%u'

Редактируем dovecot.conf
# ee /usr/local/etc/dovecot/dovecot.conf

Правим ( или раскоментировать при наличии и поправить) строки
protocols = imap pop3
listen = *
base_dir = /var/run/dovecot/
instance_name = dovecot
login_greeting = Dovecot ready.
verbose_proctitle = no
shutdown_clients = yes
doveadm_socket_path = doveadm-server

Редактируем conf.d/10-auth.conf
# ee /usr/local/etc/dovecot/conf.d/10-auth.conf

Правим ( или раскоментировать при наличии и поправить) строки
disable_plaintext_auth = no
auth_cache_size = 0
auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
auth_username_format = %Lu
auth_ssl_require_client_cert = no
auth_ssl_username_from_cert = no
auth_mechanisms = plain
!include auth-sql.conf.ext

Редактируем conf.d/10-master.conf
# ee /usr/local/etc/dovecot/conf.d/10-master.conf
Правим ( или раскоментировать при наличии и поправить) строки:
default_process_limit = 100
default_client_limit = 1000
default_login_user = dovenull
default_internal_user = dovecot

service stats {
fifo_listener stats-mail {
user = vexim
mode = 0600
}
}

service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}

service pop3-login {
inet_listener pop3 {
port = 110
}
inet_listener pop3s {
port = 995
ssl = yes
}
}

service lmtp {
unix_listener lmtp {
}

}

service auth {
unix_listener auth-userdb {
mode = 0666
user = vexim
group = vexim
}
}

Редактируем conf.d/10-mail.conf
# ee /usr/local/etc/dovecot/conf.d/10-mail.conf
Правим ( или раскоментировать при наличии и поправить) строки:
namespace inbox {
inbox = yes
}
mail_uid = mailnull
mail_gid = mail
first_valid_uid = 90
first_valid_gid = 90
auth_socket_path = /var/run/dovecot/auth-userdb
mail_plugin_dir = /usr/local/lib/dovecot
mail_plugins=$mail_plugins stats

Редактируем conf.d/10-ssl.conf
ee /usr/local/etc/dovecot/conf.d/10-ssl.conf
Правим ( или раскоментировать при наличии и поправить) строки:
ssl = yes
ssl_cert = </usr/local/etc/letsencrypt/live/mail.deathstar.name/fullchain.pem;
ssl_key = </usr/local/etc/letsencrypt/live/mail.deathstar.name/privkey.pem;

Добавляем запись в /etc/rc.conf:
dovecot_enable=»YES»

Установка и настройка Roundcube

Ставим RoundCube (выбираем MySQL):
# cd /usr/ports/mail/roundcube/
# make config-recursive
# make install clean

И далее команды по порядку:
# cd /usr/local/www/roundcube
# chmod 777 logs/
# chmod 777 temp/

Заходим в MySQL
# mysql -u root -p

Вводим ранее установленный пароль для root

Создаем пользователя для Roundcube
CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'PASSWORD';

Устанавливаем тип таблиц и прочие настройки
SET storage_engine=INNODB;
SET GLOBAL innodb_file_per_table=1, innodb_file_format=Barracuda, innodb_large_prefix=1;

Создаем базу
CREATE DATABASE IF NOT EXISTS `roundcubemail` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_general_ci`;

Предоставляем привелегии на базу для пользователя vexim
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER, LOCK TABLES, REFERENCES, TRIGGER ON `roundcubemail`.* TO 'roundcube'@'localhost';

Вызодим из MySQL
\q

Копируем конфиг:
# cd /usr/local/www/roundcube/config
c# p config.inc.php.sample config.inc.php

И прописываем подключение к БД:
$config['db_dsnw'] = 'mysql://roundcube:PASSWORD@localhost/roundcubemail';

Заливаем дамп
mysql -p roundcubemail < /usr/local/www/roundcube/SQL/mysql.initial.sql

Редактируем /usr/local/www/roundcube/config/defaults.inc.php
# ee /usr/local/www/roundcube/config/defaults.inc.php

Правим ( или раскоментировать при наличии и поправить) строки:
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';
$config['create_default_folders'] = true;

Делаем виртуальный хост в nginx для Roundcube
# ee /usr/local/etc/nginx/vhosts/mail.deathstar.name и приводим к такому виду

{
listen 80;
#listen 443 ssl;
#ssl on;
#ssl_certificate /usr/local/etc/letsencrypt/live/mail.deathstar.name/fullchain.pem;
#ssl_certificate_key /usr/local/etc/letsencrypt/live/mail.deathstar.name/privkey.pem;

server_name mail.deathstar.name;
access_log /var/log/nginx/mail.deathstar.name_access.log;
error_log /var/log/nginx/mail.deathstar.name_error.log;
root /usr/local/www/vexim;
index index.php;
charset utf-8;

location /.well-known/acme-challenge {
allow all;
auth_basic off;
root /tmp/;
}

location ~ \.php$
{
fastcgi_pass php-fpm;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /usr/local/etc/nginx/fastcgi_params;
}

location ~ /\.ht
{
deny all;
}
}

Запускаем Nginx
/usr/local/etc/rc.d/nginx start

Получение SSL сертификатов от Let’s Encrypt

Устанавливаем Certbot Для получения SSL сертификата.
# cd /usr/ports/security/py-certbot
# make config-recursive
# make install clean

Получаем сертификат SSL
c# ertbot certonly --rsa-key-size 4096 --webroot -w /tmp/ -d exim.deathstar.name
и видим
- Congratulations! Your certificate and chain have been saved at:
/usr/local/etc/letsencrypt/live/exim.deathstar.name/fullchain.pem
Your key file has been saved at:

Тоже самое проделываем для поддомена mail.deathstar.name
# certbot certonly --rsa-key-size 4096 --webroot -w /tmp/ -d mail.deathstar.name

Копируем сертификат для Exim
# cat /usr/local/etc/letsencrypt/live/mail.deathstar.name/fullchain.pem > /usr/local/etc/exim.crt
# cat /usr/local/etc/letsencrypt/live/mail.deathstar.name/privkey.pem > /usr/local/etc/exim.key

Редактируем виртуальный хост в nginx для Roundcube
# ee /usr/local/etc/nginx/vhosts/mail.deathstar.name и раскоментируем строки, отвечающие за работу с SSL
listen 443 ssl;
ssl on;
ssl_certificate /usr/local/etc/letsencrypt/live/mail.deathstar.name/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/mail.deathstar.name/privkey.pem;

Для редиректа с http на https можно прописать после строки ssl_certificate_key
if ( $scheme = "http" ) {
rewrite ^/(.*)$ https://$host/$1 permanent;
}

То же самое делаем с /usr/local/etc/nginx/vhosts/exim.deathstar.name

Запуск

Перезапускаем Nginx
<code# >/usr/local/etc/rc.d/nginx restart

Перезапускаем PHP-FPM
# /usr/local/etc/rc.d/php-fpm restart

Запускаем Exim и Dovecot
# /usr/local/etc/rc.d/exim start
# /usr/local/etc/rc.d/dovecot start

Roundcube доступен по адресу http://mail.deathstar.name а Vexim по http://exim.deathstar.name

Заходим по адресу http://exim.deathstar.name
Логинимся под siteadmin и пароль, что выставляли ранее
Жмем Add local domain
Прописываем домен, имя администратора ( по умолчанию postmaster, можно сменить на любое , так же создастся ящик вида postmaster@domain, а создадим например admin )
прописываем пароль ( например pass )
повторяем пароль
отмечаем антиспам и антивирус ( по желанию ) и жмем Submit

У нас появился почтовый аккаунт admin@domain с паролем pass

Чтоб для созданного домена создать еще ящик, логинимся под логином админа домена, в нашем случае — admin

Жмем Add, delete and manage POP/IMAP accounts
Потом Add User
Прописываем имя ( любое, оно просто для отображения в списке юзеров )
логин ( например user )
два раза пароль ( например userpass )
Has domain admin privileges? — отмечаем, есди хотим сделать юзера тоже админом домена
И жмем Submit.
У нас появился почтовый аккаунт user@domain с паролем userpass
Теперь можно зайти в roundcube по ссылке http://mail.deathstar.name под логином user@domain и паролем userpass

Обновление сертификатов

# certbot renew
# cat /usr/local/etc/letsencrypt/live/mail.deathstar.name/fullchain.pem > /usr/local/etc/exim.crt
# cat /usr/local/etc/letsencrypt/live/mail.deathstar.name/privkey.pem > /usr/local/etc/exim.key
# /usr/local/etc/rc.d/nginx restart
# /usr/local/etc/rc.d/exim restart
# /usr/local/etc/rc.d/dovecot restart