Всем добрый день!
Решил написать HOWTO по мотивам недавнего внедрения почтового сервера в организации. Материал будет разбит на несколько статей, так как материала много. Параллельно с текстом вся конфигурация будет проверена на новой тестовой инсталляции FreeBSD 10.3.
Итак, в этом материале мы рассмотрим установку и настройку нашего почтового сервера, попутно установим Mysql, PHP и Nginx. Инсталляция будет проводится в операционной системе FreeBSD 10.3 с локалью UTF-8, сервер будет иметь:
- Внешний интерфейс 111.111.111.111
- Внутренний интерфейс 10.10.10.10
- Имя сервера mail.test.ru
- Будем обслуживать домен test.ru
- Будем исходить из того, что в DNS вашей зоны внесены:
- A запись типа mail IN A 111.111.111.111
- MX запись IN MX 10 mail.test.ru.
Из чего будет состоять наш почтовый сервер:
- Postfix — сам MTA (mail transfer agent)
- Dovecot — IMAP и POP3 сервер
- PostfixAdmin — WEB интерфейс для администратора почтового сервера (создание, управление пользователями, виртуальными доменами)
- RoundCube — пользовательский WEB интерфейс к нашему почтовому серверу
Устанавливаем все необходимое
Предварительно обновив или установив набор портов.
Обновление: portsnap fetch update
Первая установка: portsnap fetch extract
MySQL:
cd /usr/ports/databases/mysql56-server/ make install clean
Разрешаем запуск MySQL сервера:
sysrc mysql_enable="YES"
Запускаем MySQL сервер:
/usr/local/etc/rc.d/mysql-server start
Зададим пароль для пользователя root в MySQL, удалим тестовую базу, запретим удаленные подключения и удалим анонимного пользователя:
mysql_secure_installation
- Set root password? [Y/n] Y
- New password: mypassword
- Re-enter new password: mypassword
- Remove anonymous users? [Y/n] Y
- Disallow root login remotely? [Y/n] Y
- Remove test database and access to it? [Y/n] Y
- Reload privilege tables now? [Y/n] Y
Создадим базы для PostfixAdmin и RounCube:
mysql -u root -p mysql> create database postfix; mysql> grant all on postfix.* to postfix@localhost identified by 'mypassword'; mysql> create database roundcube; mysql> grant all on roundcube.* to roundcube@localhost identified by 'mypassword'; mysql> \q
Тем самым мы создали две базы данных:
- postfix с паролем mypassword и пользователем postfix для PostfixAdmin
- rouncube с паролем mypassword и пользователем roundcube для RoundCube
NGINX:
cd /usr/ports/www/nginx make install clean
В config я убрал поддержку IPV6, т.к. ее не использую и убираю ее везде, остальное оставил по умолчанию.

Разрешаем запуск Nginx:
sysrc nginx_enable="YES"
Создадим два виртуальных хоста:
- postfix.test.ng.ru для PostfixAdmin
- mail.test.ru для RounCube
Место для логов и конфигов и создадим пустые конфиги
mkdir -p /var/log/nginx/postfix mkdir /var/log/nginx/mail mkdir /usr/local/etc/nginx/conf.d touch /usr/local/etc/nginx/conf.d/postfix.test.ru.conf touch /usr/local/etc/nginx/conf.d/mail.test.ru.conf
Для подключение конфигурационных файлов виртуальных хостов — укажем nginx где они лежат.
В файле /usr/local/etc/nginx/nginx.conf в секции http (перед последней закрывающей фигурной скобкой) впишем:
include /usr/local/etc/nginx/conf.d/*.conf;
Конфигурационный файл виртуального хоста postfix.test.ru.conf для PostfixAdmin
server {
listen 80;
server_name postfix.test.ru;
root /usr/local/www/postfixadmin/public;
index index.php;
charset utf-8;
access_log /var/log/nginx/postfix/access.log;
error_log /var/log/nginx/postfix/error.log error;
location / {
try_files $uri $uri/ index.php;
#Ограничиваем работу вне своей сети
allow 10.10.10.0/24;
allow 111.111.111.0/24;
deny all;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
} Конфигурационный файл виртуального хоста mail.test.ru.conf для RoundCube
server {
listen 80;
server_name mail.test.ru;
root /usr/local/www/roundcube;
access_log /var/log/nginx/mail/access.log;
error_log /var/log/nginx/mail/error.log error;
location / {
index index.php;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /favicon.ico {
log_not_found off;
access_log off;
}
} Пока не запускаем Nginx, запустим после установки PostfixAdmin и RoundCube.
PostfixAdmin инсталляция:
cd /usr/ports/mail/postfixadmin make install clean
В конфигурации отмечаем MYSQL, на PostgreSQL снимаем галку (можно и не снимать)

RoundCube инсталляция:
cd /usr/ports/mail/roundcube make install clean
В config, я дополнительно отметил GD и PSPELL

PHP-FPM:
Разрешим запуск:
sysrc php_fpm_enable="YES"
date.timezone = Europe/Moscow
Запустим:
/usr/local/etc/rc.d/php-fpm start
Так же запустим Nginx:
/usr/local/etc/rc.d/nginx start
PostfixAdmin установка:
Правим
vi /usr/local/www/postfixadmin/config.inc.php
$CONF['configured'] =true;
$CONF['setup_password'] = 'mypassword';
$CONF['default_language'] = 'ru';
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'mypassword';
$CONF['database_name'] = 'postfix';
$CONF['admin_email'] = 'postmaster@test.ru';
$CONF['generate_password'] = 'YES';
$CONF['show_password'] = 'YES';
# '/([a-zA-Z].*){3}/' => 'password_no_characters 3', # must contain at least 3 characters
# '/([0-9].*){2}/' => 'password_no_digits 2', # must contain at least 2 digits Переходим в браузере на страницу http://postfix.test.ru/setup.php
Проверяем вывод, при необходимости исправляем ошибки, мне в частности было предложено установить php5-imap, установим:
cd /usr/ports/mail/php56-imap/ make install clean /usr/local/etc/rc.d/php-fpm restart
Внизу этой странице вбиваем текущий пароль, который указали в config.inc.php в строке $CONF[‘setup_password’] в поле Setup Password, почтовый адрес администратора и задаем пароль для входа

После этого получим строку подобной этой
Вписываем хеш пароля в config.inc.php в строку $CONF[‘setup_password’]
Заходим на postfix.test.ru, вставляем свои данные.
Добавляем домен http://postfix.test.ru/list.php?table=domain
Postfix:
cd /usr/ports/mail/postfix make install clean
в cofig отмечаем, что нам нужна поддержка MySql и SASL

В конце инсталляции отвечаем утвердительно на вопрос:
Would you like to activate Postfix in /usr/local/etc/mail/mailer.conf [n]? y
Останавливаем sendmail:
# /etc/rc.d/sendmail stop
Запрещаем запуск Sendmail и разрешаем запуск Postfix, прописав соответствующие строки в /etc/rc.conf
sysrc postfix_enable="YES" sysrc sendmail_enable="NONE"
Отключаем различные задачи для обслуживания Sendmail.
Создаем файл /etc/periodic.conf и вписываем туда следующее:
daily_clean_hoststat_enable="NO" daily_status_mail_rejects_enable="NO" daily_status_include_submit_mailq="NO" daily_submit_queuerun="NO"
Если по какой-то причине «не активировали» Postfix в конце инсталляции, то проделываем следующее:
mv /etc/mail/mailer.conf /etc/mail/mailer.conf.old install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /etc/mail/mailer.conf
Создаем дополнительные каталоги для хранения конфигов и ssl ключей:
mkdir /usr/local/etc/postfix/mysql mkdir /usr/local/etc/postfix/ssl
Создаем ключи шифрования на 10 лет (3650 дней):
cd /usr/local/etc/postfix/ssl openssl req -new -x509 -nodes -out cert.pem -keyout key.pem -days 3650
Отвечаем на вопросы:
- Country Name (2 letter code) [AU]:RU
- State or Province Name (full name) [Some-State]:Russia
- Locality Name (eg, city) []:Moscow
- Organization Name (eg, company) [Internet Widgits Pty Ltd]:Testcompany Ltd
- Organizational Unit Name (eg, section) []:Mail Server
- Common Name (e.g. server FQDN or YOUR name) []:mail.test.ru
- Email Address []:postmaster@test.ru
Создадим каталог для хранения почты:
mkdir /usr/mail chown 65534:65534 /usr/mail
Создадим три конфигурационных файла для связи Postfix с Mysql
Для алиасов:
vi /usr/local/etc/postfix/mysql/mysql_virtual_alias_maps.cf user = postfix password = mypassword hosts = localhost dbname = postfix query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
Для почтовых ящиков:
vi /usr/local/etc/postfix/mysql/mysql_virtual_mailbox_maps.cf user = postfix password = mypassword hosts = localhost dbname = postfix query = SELECT maildir FROM mailbox WHERE username='%s'AND active = '1'
Для виртуальных почтовых доменов:
vi /usr/local/etc/postfix/mysql/mysql_virtual_domains_maps.cf user = postfix password = mypassword hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
Редактируем конфигурационный файл Postfix:
vi /usr/local/etc/postfix/main.cf
myhostname = mail.test.ru
mydomain = mail.test.ru
myorigin = $mydomain
#Принимаем почту локально для mail.test.ru
mydestination = $myhostname
#Для алиасов MySQL
virtual_alias_maps = proxy:mysql:$config_directory/mysql/mysql_virtual_alias_maps.cf
#Файл с запросом для почтовых ящиков
virtual_mailbox_maps = proxy:mysql:$config_directory/mysql/mysql_virtual_mailbox_maps.cf
#Файл с запросом о виртуальных доменах
virtual_mailbox_domains = proxy:mysql:$config_directory/mysql/mysql_virtual_domains_maps.cf
#UID и GID
virtual_minimum_uid = 65534
virtual_uid_maps = static:65534
virtual_gid_maps = static:65534
#Где храним почту
virtual_mailbox_base = /usr/mail
inet_interfaces = all
mynetworks_style = subnet
mynetworks = 10.10.10.0/24, 127.0.0.1/32
#Лимит в 10МБ на размер письма
message_size_limit = 10485760
Лимит на ящик в 1ТБ
mailbox_size_limit = 1073741824
unknown_local_recipient_reject_code = 550
invalid_hostname_reject_code = 550
non_fqdn_reject_code = 550
unknown_address_reject_code = 550
unknown_client_reject_code = 550
unknown_hostname_reject_code = 550
unverified_recipient_reject_code = 550
unverified_sender_reject_code = 550
# отложенная обработка всех ограничений
smtpd_delay_reject = yes
# обязательное приветствие HELO/EHLO
smtpd_helo_required = yes
# запрет проверки существования получателя
disable_vrfy_command = yes
#Шифруем исходящие письма
smtp_use_tls = yes
#for gmail
smtp_tls_mandatory_ciphers = high
smtp_tls_mandatory_protocols=!SSLv2,!SSLv3
tls_high_cipherlist = 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:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
#Разрешаем отправку из нашей сети и запрещеам всем остальным + еще запреты
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
# запретить некорректные команды конвейера
reject_unauth_pipelining,
# списки для проверки приветствий, имен хостов,
# адресов отправителей и получателей
check_helo_access hash:/usr/local/etc/postfix/access_helo,
check_client_access hash:/usr/local/etc/postfix/access_client,
check_sender_access hash:/usr/local/etc/postfix/access_sender,
check_recipient_access hash:/usr/local/etc/postfix/access_recipient,
# запретить, если имя хоста отсутствует в DNS
reject_unknown_client_hostname,
# запретить, если приветствие некорректно
reject_non_fqdn_helo_hostname,
reject_invalid_helo_hostname,
reject_unknown_helo_hostname,
# запретить, если адрес отправителя некорректен
reject_non_fqdn_sender,
reject_unknown_sender_domain,
reject_unverified_sender,
# запретить, если адрес получателя некорректен
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
reject_unverified_recipient,
# использование внешних списков DNSBL
reject_rbl_client bl.spamcop.net,
reject_rbl_client zen.spamhaus.org
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
#Подключаем SSL и TLS
smtpd_use_tls = yes
smtpd_tls_received_header = yes
smtpd_tls_cert_file = /usr/local/etc/postfix/ssl/cert.pem
smtpd_tls_key_file = /usr/local/etc/postfix/ssl/key.pem vi /usr/local/etc/postfix/access_helo 10 REJECT Incorrect config. 172.16 REJECT Incorrect config. 192.168 REJECT Incorrect config. 127.0.0.1 REJECT Incorrect config. localhost REJECT Incorrect config. localhost.localdomain REJECT Incorrect config.
touch /usr/local/etc/postfix/access_client touch /usr/local/etc/postfix/access_sender touch /usr/local/etc/postfix/access_recipient
postmap hash:/usr/local/etc/postfix/access_helo postmap hash:/usr/local/etc/postfix/access_client postmap hash:/usr/local/etc/postfix/access_sender postmap hash:/usr/local/etc/postfix/access_recipient
vi /usr/local/etc/postfix/master.cf smtps inet n - n - - smtpd -o smtpd_tls_wrappermode=yes
Запускаем Postfix
/usr/local/etc/rc.d/postfix start
Dovecot:
cd /usr/ports/mail/dovecot2 make install clean
В config обязательно отмечаем поддержку MySQL

Разрешаем запуск:
sysrc dovecot_enable="YES"
Копируем конфиги:
cp -r /usr/local/etc/dovecot/example-config/* /usr/local/etc/dovecot/
vi /usr/local/etc/dovecot/dovecot.conf #Слушаем все интерфейсы listen = *
vi /usr/local/etc/dovecot/conf.d/10-auth.conf # аутентификация открытым текстом disable_plaintext_auth = no # аутентификация через MySQL !include auth-sql.conf.ext #Закомментируем возможность работы системным пользователям #!include auth-system.conf.ext
vi /usr/local/etc/dovecot/conf.d/10-mail.conf mail_home = /usr/mail/%d/%n mail_location = maildir:~ #GID first_valid_gid = 65534
vi /usr/local/etc/dovecot/conf.d/10-ssl.conf ssl = yes ssl_cert = </usr/local/etc/postfix/ssl/cert.pem ssl_key = </usr/local/etc/postfix/ssl/key.pem
vi /usr/local/etc/dovecot/conf.d/auth-sql.conf.ext
passdb {
driver = sql
#Путь до файла с запросом к MySQL
args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /usr/local/etc/dovecot/dovecot-sql.conf.ext
} vi /usr/local/etc/dovecot/dovecot-sql.conf.ext driver = mysql connect = host=localhost dbname=postfix user=postfix password=mypassword default_pass_scheme = MD5-CRYPT password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1' user_query = SELECT maildir, 65534 AS uid, 65534 AS gid FROM mailbox WHERE username = '%u' AND active='1'
vi /usr/local/etc/dovecot/conf.d/10-master.conf
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
} Запускаем Dovecot:
/usr/local/etc/rc.d/dovecot start
Заводим почтовый ящик пользователя через PostfixAdmin
RounCube настройка:
Заходим http://mail.test.ru/installer/
Если видим такую картину, то продолжаем, если не хватает какого-либо PHP модуля, то устанавливаем и передергиваем php-fpm

Если планируется использовать один домен, то можно жестко указать в поле username_domain, жмем «NEXT», записываем сгенерированный конфиг в файл: /usr/local/www/roundcube/config/config.inc.php
Нажимаем continue, исправляем DB config и переходим на страницу http://mail.test.ru/, если вы все сделали правильно, то должны увидеть такую страницу:
Вводим пользователя вида test@test.ru и его пароль и попадаем в почту:
Не забываем в конфигурационных файлах заменить имена и IP адреса на свои.
Почтовый сервер готов к использованию. В следующих статьях я опишу, как нам прикрутить к DNS подпись DKIM, так же опишем правила SPF для нашего домена. Настроим Graylist, Clamav, Spamassassin и организуем мониторинг сервера с помощью Mailgraph и Pflogsumm.
До встречи.

Продолжения настройки пока нет? (DKIM, Graylist, Clamav, Spamassassin)
Никак руки не дойдут, в течении месяца допишу