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

Материал из Webko Wiki
Перейти к навигации Перейти к поиску
 
(не показано 35 промежуточных версий этого же участника)
Строка 3: Строка 3:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
OS - CentOS 7
 
OS - CentOS 7
smtp - Exim
+
smtp - Exim (DKIM подпись, SSL/TLS)
pop3/imap - Dovecot
+
pop3/imap - Dovecot (SSL/TLS)
 
antivirus - ClamAV
 
antivirus - ClamAV
 
gui - PostfixAdmin
 
gui - PostfixAdmin
Строка 13: Строка 13:
  
 
1) Устанавливаем ОС в минимальной поставке.
 
1) Устанавливаем ОС в минимальной поставке.
 +
 
2) Назначаем валидный(белый) ip адрес с бэерезолвом в хостнейм сервера (PTR).
 
2) Назначаем валидный(белый) ip адрес с бэерезолвом в хостнейм сервера (PTR).
 +
 
3) Обновляем свежеустановленую систему:
 
3) Обновляем свежеустановленую систему:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Строка 116: Строка 118:
 
[root@mail ~] vim /etc/sysconfig/freshclam
 
[root@mail ~] vim /etc/sysconfig/freshclam
 
</syntaxhighlight>
 
</syntaxhighlight>
Закоментируем последнюю строчку
+
удаляем последнюю строчку
 +
<syntaxhighlight lang="bash">
 +
FRESHCLAM_DELAY=disabled-warn  # REMOVE ME
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] mv /etc/freshclam.conf /etc/freshclam.conf.bak
 +
[root@mail ~] vim /etc/freshclam.conf
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="bash">
 +
UpdateLogFile /var/log/freshclam.log
 +
DatabaseMirror database.clamav.net
 +
NotifyClamd /etc/clamd.d/clamd.conf
 +
</syntaxhighlight>
 +
Обновляем базу сигнатур (займет какое-то время)
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] freshclam
 +
</syntaxhighlight>
 +
Дальше он будет обновлятся по крону.
 +
 
 +
Запускаем демона clamd
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] systemctl daemon-reload
 +
[root@mail ~] systemctl start clamd
 +
# проверим запустился ли
 +
[root@mail ~] systemctl status clamd
 +
[root@mail ~] systemctl enable clamd
 +
</syntaxhighlight>
 +
 
 +
===MySQL/MariaDB===
 +
Установим и настроим базу данных для хранения информации о наших ящиках и работы postfixadmin, roundcube.
 +
 
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] yum install mariadb-server mariadb
 +
</syntaxhighlight>
 +
Запустим и установим рутовй пароль
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] systemctl start mariadb
 +
[root@mail ~] systemctl enable mariadb
 +
[root@mail ~] mysql_secure_installation
 +
# на вопрос ''Enter current password for root (enter for none):'' жмем Enter
 +
# на следующий вопрос отвечаем Yes и вводим рутовый пароль
 +
</syntaxhighlight>
 +
 
 +
Создадим базу данных и дадим 2 пользователям на нее права (однуму чтение запись, второму чтение(для postfix и exim))
 +
 
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] mysql -u root -p
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="sql">
 +
MariaDB [(none)]> create database vmail;
 +
MariaDB [(none)]> grant all on vmail.* to pf_admin@localhost identified by 'fizvSdyCXy';
 +
MariaDB [(none)]> grant select on vmail.* to mail@localhost identified by '17V3BZ8Vh9'; # exim и dovecot больше и не нужно.
 +
MariaDB [(none)]> flush privileges;
 +
MariaDB [(none)]> exit
 +
</syntaxhighlight>
 +
 
 +
===Exim===
 +
 
 +
Установим и настроим exim
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] yum install exim exim-mysql -y
 +
[root@mail ~] usermod -G exim,vmail,mail exim
 +
[root@mail ~] mv /etc/exim/exim.conf /etc/exim/exim.conf.def
 +
[root@mail ~] vim /etc/exim/exim.conf
 +
</syntaxhighlight>
 +
 
 +
====Основные опции====
 +
<syntaxhighlight lang="bash">
 +
# подключаем mysql (хост/база/логин/пароль)
 +
hide mysql_servers = 127.0.0.1/vmail/mail/17V3BZ8Vh9
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="sql">
 +
# определяем место с какого будем вычитывать локальные домены и домены для которых будем выступать релеем.
 +
domainlist local_domains = ${lookup mysql{SELECT `domain` FROM `domain` WHERE `domain`='${quote_mysql:$domain}' AND `active`='1'}}
 +
domainlist relay_to_domains = ${lookup mysql{SELECT `domain` FROM `domain` WHERE `domain`='${quote_mysql:$domain}' AND `active`='1'}}
 +
</syntaxhighlight>
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
#FRESHCLAM_DELAY=disabled-warn  # REMOVE ME
+
hostlist relay_from_hosts = 127.0.0.1
 +
 
 +
# имя хоста, будет использоваться при HELO
 +
primary_hostname = mail.webko.net.ua
 +
 
 +
# домен, добавляемый при отправке локальной почты;
 +
# например письма от root будут вида [email protected]
 +
qualify_domain = mail.webko.net.ua
 +
# домен для локальный получателей, противоположность пункта выше;
 +
# если не указать - будет использоваться значение из qualify_domain
 +
qualify_recipient = mail.webko.net.ua
 +
 
 +
# приветственное сообщение сервера
 +
smtp_banner = "$primary_hostname, Microsoft ESMTP MAIL service ready"
 +
 
 +
# ip на котором будет слушать exim, если их несколько можно указать конкретный
 +
local_interfaces = 212.216.16.35
 +
# отключаем ipv6
 +
disable_ipv6 = true
 +
 
 +
# порты на которых бдет слушать exim, в том числе tls
 +
daemon_smtp_ports = 25 : 465 : 587
 +
tls_on_connect_ports = 465
 +
 
 +
# сертификаты для tls соединений
 +
tls_certificate = /etc/ssl/certs/exim.pem
 +
tls_privatekey = /etc/ssl/private/exim.key
 +
 
 +
tls_advertise_hosts = *
 +
 
 +
# подключаем антивирус
 +
av_scanner = clamd:/var/run/clamd/clamd.sock
 +
 
 +
# определяем пользователя и групу для работы exim
 +
never_users = root
 +
trusted_users = mail:exim:root:vmail
 +
 
 +
exim_user = exim
 +
exim_group = vmail
 +
 
 +
host_lookup = !10.0.0.0/8 : !127.0.0.0/8 : !192.168.0.0/16 : !172.16.0.0/12 : *
 +
 
 +
rfc1413_hosts = !*
 +
rfc1413_query_timeout = 1s
 +
 
 +
ignore_bounce_errors_after = 3h
 +
 
 +
timeout_frozen_after = 7d
 +
 
 +
split_spool_directory = true
 +
 
 +
check_rfc2047_length = false
 +
 
 +
log_selector = +smtp_confirmation \
 +
              -queue_run \
 +
              -retry_defer \
 +
              +sender_on_delivery \
 +
              +received_recipients \
 +
              +delivery_size \
 +
              +subject \
 +
              -etrn \
 +
              -host_lookup_failed \
 +
              +received_sender \
 +
              -rejected_header \
 +
              -skip_delivery \
 +
              +deliver_time
 +
 
 +
allow_utf8_domains = true
 +
accept_8bitmime = true
 +
queue_run_max = 6
 +
 
 +
# максимальный обем письма для приема/передачи
 +
message_size_limit = 50M
 +
# макс. количество одновременных подключений для отправки
 +
smtp_accept_max = 50
 +
 
 +
# макс. кол-во писем за одно подключение
 +
smtp_accept_max_per_connection = 25
 +
 
 +
# макс. подключений с одного хоста
 +
smtp_accept_max_per_host = 20
 +
 
 +
queue_run_in_order = false
 +
 
 +
remote_max_parallel = 15
 +
return_size_limit = 70k
 +
 
 +
# принудительная синхронизация с клиентом при обмене сообщениями/командами
 +
smtp_enforce_sync = true
 +
 
 +
# принимать ли почту с доменов, состоящих из IP;
 +
# не вижу адекватных серверов, которые бы так отправляли - запрещаем;
 +
# по-умолчанию тоже false
 +
allow_domain_literals = false
 +
 
 +
# список хостов, которым не делаем проверку корректности HELO/EHLO
 +
helo_accept_junk_hosts = 127.0.0.0/8
 +
helo_allow_chars = _
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
==== ACL ====
 +
 +
<syntaxhighlight lang="bash">
 +
# задаём имена ACL для проверок
 +
acl_smtp_rcpt = acl_check_rcpt
 +
acl_smtp_data = acl_check_data
 +
acl_smtp_mime = acl_check_mime
 +
 +
begin acl
 +
 +
# проверяем адрес получателя - блок ACL acl_check_rcpt
 +
 +
acl_check_rcpt:
 +
 +
accept hosts = :
 +
 +
# некорректные символы в адресе (кроме "своих" доменов из списка local_domains)
 +
deny message = "incorrect symbol in address"
 +
domains = !+local_domains
 +
local_parts = ^[./|] : ^.*[@%!] : ^.*/../
 +
 +
# отклоняем, если нет HELO/EHLO
 +
deny message = "HELO/EHLO required by SMTP RFC"
 +
condition = ${if eq{$sender_helo_name}{}{yes}{no}}
 +
 +
# отклоняем отправителей, у которых IP вместо домена
 +
# исключение - список relay_from_hosts
 +
deny message = "Your IP in HELO - access denied!"
 +
hosts = * : !+relay_from_hosts
 +
condition = ${if eq{$sender_helo_name}{$sender_host_address}{true}{false}}
 +
 +
# отклоняем, если в HELO наш собственный IP
 +
deny condition = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
 +
hosts = !127.0.0.1 : !localhost : *
 +
message = "My IP in your HELO! Access denied!"
 +
 +
# отклоняем, если в EHLO наше имя хоста
 +
deny message = Message was delivered by ratware - own
 +
condition = ${if match_domain{sender_helo_name}{$primary_hostname:+local_domains:+relay_to_domains}{true}{false}}
 +
log_message = remote host used our name in EHLO/HELO.
 +
 +
# отклоняем отправителей с именем хоста только из цифр
 +
deny condition = ${if match{$sender_helo_name}{N^d+$N}{yes}{no}}
 +
hosts = !127.0.0.1 : !localhost : *
 +
message = "Incorrect HELO string"
 +
 +
# отклонять отправителей, у которых в имени хоста adsl/dialup и т.д.
 +
# не используется в данном случае
 +
deny message = "your hostname is bad (adsl, poll, ppp & etc)."
 +
condition = ${if match{$sender_host_name}{adsl|dialup|pool|peer|dhcp}{yes}{no}}
 +
 +
# задаём задержку при подключении клиента
 +
# спам-боты как правило не дожидаются ответа сервера
 +
# требуется smtp_enforce_sync = true
 +
set acl_m0 = 30s
 +
accept hosts = +relay_from_hosts:127.0.0.0/8
 +
set acl_m0 = 0s
 +
delay = $acl_m0
 +
 +
# проверяем в спам-базах
 +
# сервера спам-баз опрашиваются по очереди
 +
# сверху вниз, если не отправитель не найден на первом, то
 +
# запрашивается второй, и т.д.;
 +
# если не найден ни в одном
 +
# из списка - то почта пропускается
 +
deny message = "you in blacklist - $dnslist_domain -->$dnslist_text; $dnslist_value"
 +
  log_message = REJECT: Listed in $dnslist_domain
 +
  hosts = !+relay_from_hosts
 +
  dnslists = cbl.abuseat.org : dul.dnsbl.sorbs.net : sbl-xbl.spamhaus.org
 +
# проверяем наличие получателя в локальных доменах
 +
accept domains = +local_domains
 +
verify = recipient
 +
 +
# принимаем почту от локальных доменов
 +
accept hosts = +relay_from_hosts
 +
 +
# пропускаем прошедшим авторизацию
 +
accept authenticated = *
 +
 +
# если письмо не попало не под одно правило в списке - отклоняем его
 +
deny message = "relay not permitted"
 +
log_message = "REJECT: We aren't an open relay"
 +
 +
acl_check_mime:
 +
 +
  deny  message = No executable files please
 +
        condition = ${if match{${lc:$mime_filename}}{\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} {yes}{no}}
 +
 +
  accept
 +
 +
acl_check_data:
 +
 +
deny malware = *
 +
message    = This message contains a virus ($malware_name)
 +
log_message = Virus found ($malware_name) for $recipients size $message_size
 +
 +
accept
 +
</syntaxhighlight>
 +
 +
==== Routes/Transport ====
 +
 +
<syntaxhighlight lang="bash">
 +
begin routers
 +
 +
dnslookup:
 +
driver = dnslookup
 +
domains = ! +local_domains
 +
transport = remote_smtp
 +
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
 +
no_more
 +
 +
system_aliases:
 +
driver = redirect
 +
allow_fail
 +
allow_defer
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="sql">
 +
data = ${lookup mysql{SELECT `goto` FROM `alias` WHERE `address`='${quote_mysql:$local_part@$domain}' OR `address`='${quote_mysql:@$domain}'}}
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="bash">
 +
dovecot_user:
 +
driver = accept
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="sql">
 +
condition = ${lookup mysql{SELECT `goto` FROM `alias` WHERE `address`='${quote_mysql:$local_part@$domain}' OR `address`='${quote_mysql:@$domain}'}{yes}{no}}
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="bash">
 +
transport = dovecot_delivery
 +
 +
begin transports
 +
 +
#DKIM OPTS
 +
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
 +
DKIM_FILE = /etc/exim/domains/${lc:${domain:$h_from:}}/dkim.pem
 +
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
 +
 +
remote_smtp:
 +
  driver = smtp
 +
  max_rcpt = 10
 +
  delay_after_cutoff = false
 +
  dkim_domain = DKIM_DOMAIN
 +
  dkim_selector = mail
 +
  dkim_private_key = DKIM_PRIVATE_KEY
 +
  dkim_canon = relaxed
 +
  dkim_strict = 0
 +
 +
dovecot_delivery:
 +
driver = pipe
 +
command = /usr/libexec/dovecot/deliver -d $local_part@$domain
 +
message_prefix =
 +
message_suffix =
 +
delivery_date_add
 +
envelope_to_add
 +
return_path_add
 +
log_output
 +
user = exim
 +
 +
address_pipe:
 +
driver = pipe
 +
return_output
 +
 +
address_reply:
 +
driver = autoreply
 +
</syntaxhighlight>
 +
 +
===Dovecot===
 +
Установим и настроим dovecot
 +
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] yum -y install dovecot dovecot-mysql
 +
[root@mail ~] usermod -G dovecot,vmail dovecot
 +
</syntaxhighlight>
 +
 +
===Web services===
 +
====Nginx+PHP-FPM====
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] yum -y install nginx php-fpm php-cli php-mbstring php-imap php-mysql php-xml php-intl php-ldap
 +
#настроим php, установим временную зону,
 +
[root@mail ~] vim /etc/php.ini
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="bash">
 +
date.timezone = Europe/Kiev
 +
</syntaxhighlight>
 +
 +
Запускаем и добваляем в автозагрузку nginx и php-fpm
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] systemctl start nginx php-fpm
 +
[root@mail ~] systemctl enable nginx php-fpm
 +
</syntaxhighlight>
 +
 +
====Postfixadmin====
 +
Установим и проведем первичную настройку
 +
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] mkdir /srv/www/
 +
[root@mail ~] cd
 +
[root@mail ~] tar -xvf postfixadmin-3.0.tar.gz
 +
[root@mail ~] mv postfixadmin-3.0/ postfixadmin && mv postfixadmin /srv/www/
 +
[root@mail ~] chown -R nginx.nginx /srv/www
 +
# настроим php-fpm юнит для postfixadmin
 +
[root@mail ~] vim /etc/php-fpm.d/postfixadmin.conf
 +
# настроим nginx vhost для postfixadmin
 +
[root@mail ~] vim /etc/nginx/conf.d/postfixadmin.conf
 +
#внесем настройеи базы данных в конфиг Postfixadmin
 +
[root@mail ~] vim /srv/www/postfixadmin/config.inc.php
 +
</syntaxhighlight>
 +
 +
 +
<syntaxhighlight lang="bash">
 +
#/etc/php-fpm.d/postfixadmin.conf
 +
[postfixadmin]
 +
listen = /var/run/php-fpm/postfixadmin.sock
 +
listen.allowed_clients = 127.0.0.1
 +
 +
user = nginx
 +
group = nginx
 +
 +
listen.owner = nobody
 +
listen.group = nobody
 +
 +
pm = dynamic
 +
pm.max_children = 5
 +
pm.start_servers = 1
 +
pm.min_spare_servers = 1
 +
pm.max_spare_servers = 3
 +
 +
slowlog = /var/log/php-fpm/postfixadmin-slow.log
 +
 +
env[HOSTNAME] = $HOSTNAME
 +
env[PATH] = /usr/local/bin:/usr/bin:/bin
 +
env[TMP] = /tmp
 +
env[TMPDIR] = /tmp
 +
env[TEMP] = /tmp
 +
 +
php_admin_value[error_log] = /var/log/php-fpm/postfixadmin-error.log
 +
php_admin_flag[log_errors] = on
 +
php_admin_value[open_basedir] = /srv/www/postfixadmin:/tmp
 +
php_value[session.save_handler] = files
 +
php_value[session.save_path] = /tmp
 +
</syntaxhighlight>
 +
 +
 +
<syntaxhighlight lang="bash">
 +
#/etc/nginx/conf.d/postfixadmin.conf
 +
server {
 +
 
 +
        listen 91.205.17.159:8080;
 +
        server_name pf.aplus.tools;
 +
 
 +
        root            /srv/www/postfixadmin;
 +
        index          index.php;
 +
        charset        utf-8;
 +
 +
        access_log  /var/log/nginx/postfixadmin.log combined;
 +
        error_log  /var/log/nginx/postfixadmin.error.log error;
 +
 +
        add_header Strict-Transport-Security max-age=31536000;
 +
        add_header X-Frame-Options DENY;
 +
 +
        # auth_basic "Restricted area";
 +
        # auth_basic_user_file /etc/nginx/passwd;
 +
 +
        location / {
 +
                try_files $uri $uri/ @rewrites;
 +
        }
 +
   
 +
        location @rewrites {
 +
                rewrite ^ /index.php last;
 +
        }
 +
 +
        ## php block
 +
        location ~ \.php?$ {
 +
                try_files $uri =404;
 +
                include fastcgi_params;
 +
                include fastcgi.conf;
 +
 +
                fastcgi_pass  unix:/var/run/php-fpm/postfixadmin.sock;
 +
 +
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 +
                fastcgi_intercept_errors on;
 +
                fastcgi_split_path_info ^(.+\.php)(.*)$;
 +
                fastcgi_hide_header X-Powered-By;
 +
        }
 +
 +
}
 +
</syntaxhighlight>
 +
 +
 +
<syntaxhighlight lang="bash">
 +
#/srv/www/postfixadmin/config.inc.php
 +
$CONF['configured'] = false;            >> $CONF['configured'] = true;
 +
$CONF['default_language'] = 'en';        >> $CONF['default_language'] = 'ru';
 +
$CONF['database_type'] = 'mysqli';      >> $CONF['database_type'] = 'mysql';
 +
$CONF['database_host'] = 'localhost';
 +
$CONF['database_user'] = 'vexim';        >> $CONF['database_user'] = 'pf_admin';
 +
$CONF['database_password'] = 'PassWord'; >> $CONF['database_password'] = 'fizvSdyCXy';
 +
$CONF['database_name'] = 'vexim';        >> $CONF['database_name'] = 'vmail';
 +
$CONF['admin_email'] = '';              >> $CONF['admin_email'] = '[email protected]';
 +
$CONF['smtp_client'] = '';              >> $CONF['smtp_client'] = 'mail.aplus.tools';
 +
</syntaxhighlight>
 +
 +
Перезапускаем nginx и php-fpm
 +
<syntaxhighlight lang="bash">
 +
[root@mail ~] systemctl restart nginx php-fpm
 +
</syntaxhighlight>
 +
 +
Для дальнейшей настройки откроем в броузере страницу конфигурации postfixadmin  http://pf.aplus.tools:8080/setup.php
 +
 +
Если все проверки пройдено успешно то продолжим конфигурирование.
 +
 +
В открывшемя окне введем пароль(любое сочетание букв и цифр), после нажатия на кнопку нам будет предоставлен хеш нашего пароля который нужно внести в файл конфигурации.
 +
 +
[[Файл:Pfadmin setup1.png]]
 +
 +
<syntaxhighlight lang="bash">
 +
# vim /srv/www/postfixadmin/config.inc.php
 +
$CONF['setup_password'] = ''; >> $CONF['setup_password'] = '67ca56aa538ffa2d9e8d52e52389b920c7:9b9aded104dbe14bc485d2aabf70078d';
 +
</syntaxhighlight>
 +
 +
Дальше с использованием введенного рание пароля создаем аккаунт администратора.
 +
 +
[[Файл:Pfadmin .png]]
 +
 +
Для входа в панель используем http://pf.aplus.tools:8080/login.php
 +
 +
====Roundcube====
  
  
 
[[Категория:Mail]]
 
[[Категория:Mail]]

Текущая версия на 10:28, 13 декабря 2016

Исходная информация

Настройка почтового сервера на базе CentOS 7 и Exim

OS - CentOS 7
smtp - Exim (DKIM подпись, SSL/TLS)
pop3/imap - Dovecot (SSL/TLS)
antivirus - ClamAV
gui - PostfixAdmin
webmail - Roundcube

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

1) Устанавливаем ОС в минимальной поставке.

2) Назначаем валидный(белый) ip адрес с бэерезолвом в хостнейм сервера (PTR).

3) Обновляем свежеустановленую систему:

[root@mail ~] yum update -y
[root@mail ~] reboot

4) Устанавливаем необходимые репозитории

[root@mail ~] yum install epel-release.noarch -y

5) Устанавливаем необходимый прикладной софт

[root@mail ~] yum install mc vim wget net-tools bind-utils htop -y

6) Отключаем SELINUX

[root@mail ~] vim /etc/sysconfig/selinux
Заменяем SELINUX=enforcing на SELINUX=disabled, сохраняем

7) Отключаем firewalld

[root@mail ~] systemctl stop firewalld
[root@mail ~] systemctl disable firewalld
[root@mail ~] yum remove firewalld -y

8) Отключаем и удаляем то что нам не пригодится

[root@mail ~] systemctl stop wpa_supplicant postfix
[root@mail ~] systemctl disable wpa_supplicant postfix
[root@mail ~] yum remove postfix -y

9) Перезагружаемся

[root@mail ~] reboot

Натройка компонентов

Переходим непосредственно к настройке почтовых и вспомагательных сервисов.

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

Так как почту будем хранить в каталоге /var/spool/vmail то туда же и назначим домашнюю деректорию нашего пользователя.

[root@mail ~] useradd -d /var/spool/vmail -s /sbin/nologin -c "vmail user" vmail

ClamAV

Установим и настроим антивирус, подготовим его для работы с exim.

[root@mail ~] yum install clamav-server clamav-update clamav -y

Создадим пользователя от которого будет рботать демон clamav и добавим его в групу vmail

[root@mail ~] useradd -G clamupdate -d /var/lib/clamav -s /sbin/nologin -c "clamd user" clamd
[root@mail ~] usermod -G clamd,clamupdate,vmail clamd

Создадим файл сервиса для управления clamav через systemd

[root@mail ~] vim /usr/lib/systemd/system/clamd.service
[Unit]
Description = clamd scanner daemon
After = syslog.target nss-lookup.target network.target
[Service]
Type = simple
ExecStartPre=-/usr/bin/mkdir /var/run/clamd
ExecStartPre=/usr/bin/chown -R clamd:vmail /var/run/clamd
ExecStart = /usr/sbin/clamd -c /etc/clamd.d/clamd.conf --foreground=yes
Restart = on-failure
PrivateTmp = true

[Install]
WantedBy=multi-user.target

Натроим clamd

[root@mail ~] vim /etc/clamd.d/clamd.conf
LogSyslog yes
LogFacility LOG_MAIL
ExtendedDetectionInfo yes

PidFile /var/run/clamd/clamd.pid

TemporaryDirectory /tmp

LocalSocket /var/run/clamd/clamd.sock
LocalSocketMode 660

User clamd
AllowSupplementaryGroups yes
PhishingSignatures yes

MaxThreads 20

Настроим freshclam

[root@mail ~] vim /etc/sysconfig/freshclam

удаляем последнюю строчку

FRESHCLAM_DELAY=disabled-warn  # REMOVE ME
[root@mail ~] mv /etc/freshclam.conf /etc/freshclam.conf.bak
[root@mail ~] vim /etc/freshclam.conf
UpdateLogFile /var/log/freshclam.log
DatabaseMirror database.clamav.net
NotifyClamd /etc/clamd.d/clamd.conf

Обновляем базу сигнатур (займет какое-то время)

[root@mail ~] freshclam

Дальше он будет обновлятся по крону.

Запускаем демона clamd

[root@mail ~] systemctl daemon-reload
[root@mail ~] systemctl start clamd
# проверим запустился ли
[root@mail ~] systemctl status clamd
[root@mail ~] systemctl enable clamd

MySQL/MariaDB

Установим и настроим базу данных для хранения информации о наших ящиках и работы postfixadmin, roundcube.

[root@mail ~] yum install mariadb-server mariadb

Запустим и установим рутовй пароль

[root@mail ~] systemctl start mariadb
[root@mail ~] systemctl enable mariadb
[root@mail ~] mysql_secure_installation
# на вопрос ''Enter current password for root (enter for none):'' жмем Enter
# на следующий вопрос отвечаем Yes и вводим рутовый пароль

Создадим базу данных и дадим 2 пользователям на нее права (однуму чтение запись, второму чтение(для postfix и exim))

[root@mail ~] mysql -u root -p
MariaDB [(none)]> create database vmail;
MariaDB [(none)]> grant all on vmail.* to pf_admin@localhost identified by 'fizvSdyCXy';
MariaDB [(none)]> grant select on vmail.* to mail@localhost identified by '17V3BZ8Vh9'; # exim и dovecot больше и не нужно.
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> exit

Exim

Установим и настроим exim

[root@mail ~] yum install exim exim-mysql -y
[root@mail ~] usermod -G exim,vmail,mail exim
[root@mail ~] mv /etc/exim/exim.conf /etc/exim/exim.conf.def
[root@mail ~] vim /etc/exim/exim.conf

Основные опции

# подключаем mysql (хост/база/логин/пароль)
hide mysql_servers = 127.0.0.1/vmail/mail/17V3BZ8Vh9
# определяем место с какого будем вычитывать локальные домены и домены для которых будем выступать релеем.
domainlist local_domains = ${lookup mysql{SELECT `domain` FROM `domain` WHERE `domain`='${quote_mysql:$domain}' AND `active`='1'}}
domainlist relay_to_domains = ${lookup mysql{SELECT `domain` FROM `domain` WHERE `domain`='${quote_mysql:$domain}' AND `active`='1'}}
hostlist relay_from_hosts = 127.0.0.1

# имя хоста, будет использоваться при HELO
primary_hostname = mail.webko.net.ua

# домен, добавляемый при отправке локальной почты;
# например письма от root будут вида [email protected]
qualify_domain = mail.webko.net.ua
# домен для локальный получателей, противоположность пункта выше;
# если не указать - будет использоваться значение из qualify_domain
qualify_recipient = mail.webko.net.ua

# приветственное сообщение сервера
smtp_banner = "$primary_hostname, Microsoft ESMTP MAIL service ready"

# ip на котором будет слушать exim, если их несколько можно указать конкретный
local_interfaces = 212.216.16.35
# отключаем ipv6
disable_ipv6 = true

# порты на которых бдет слушать exim, в том числе tls
daemon_smtp_ports = 25 : 465 : 587
tls_on_connect_ports = 465

# сертификаты для tls соединений
tls_certificate = /etc/ssl/certs/exim.pem
tls_privatekey = /etc/ssl/private/exim.key

tls_advertise_hosts = *

# подключаем антивирус
av_scanner = clamd:/var/run/clamd/clamd.sock

# определяем пользователя и групу для работы exim
never_users = root
trusted_users = mail:exim:root:vmail

exim_user = exim
exim_group = vmail

host_lookup = !10.0.0.0/8 : !127.0.0.0/8 : !192.168.0.0/16 : !172.16.0.0/12 : *

rfc1413_hosts = !*
rfc1413_query_timeout = 1s

ignore_bounce_errors_after = 3h

timeout_frozen_after = 7d

split_spool_directory = true

check_rfc2047_length = false

log_selector = +smtp_confirmation \
               -queue_run \
               -retry_defer \
               +sender_on_delivery \
               +received_recipients \
               +delivery_size \
               +subject \
               -etrn \
               -host_lookup_failed \
               +received_sender \
               -rejected_header \
               -skip_delivery \
               +deliver_time

allow_utf8_domains = true
accept_8bitmime = true
queue_run_max = 6

# максимальный обем письма для приема/передачи
message_size_limit = 50M
# макс. количество одновременных подключений для отправки
smtp_accept_max = 50

# макс. кол-во писем за одно подключение
smtp_accept_max_per_connection = 25

# макс. подключений с одного хоста
smtp_accept_max_per_host = 20

queue_run_in_order = false

remote_max_parallel = 15
return_size_limit = 70k

# принудительная синхронизация с клиентом при обмене сообщениями/командами
smtp_enforce_sync = true

# принимать ли почту с доменов, состоящих из IP;
# не вижу адекватных серверов, которые бы так отправляли - запрещаем;
# по-умолчанию тоже false
allow_domain_literals = false

# список хостов, которым не делаем проверку корректности HELO/EHLO
helo_accept_junk_hosts = 127.0.0.0/8
helo_allow_chars = _

ACL

# задаём имена ACL для проверок
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
acl_smtp_mime = acl_check_mime

begin acl

# проверяем адрес получателя - блок ACL acl_check_rcpt

acl_check_rcpt:

 accept hosts = :

 # некорректные символы в адресе (кроме "своих" доменов из списка local_domains)
 deny message = "incorrect symbol in address"
 domains = !+local_domains
 local_parts = ^[./|] : ^.*[@%!] : ^.*/../

 # отклоняем, если нет HELO/EHLO
 deny message = "HELO/EHLO required by SMTP RFC"
 condition = ${if eq{$sender_helo_name}{}{yes}{no}}

 # отклоняем отправителей, у которых IP вместо домена
 # исключение - список relay_from_hosts
 deny message = "Your IP in HELO - access denied!"
 hosts = * : !+relay_from_hosts
 condition = ${if eq{$sender_helo_name}{$sender_host_address}{true}{false}}

 # отклоняем, если в HELO наш собственный IP
 deny condition = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
 hosts = !127.0.0.1 : !localhost : *
 message = "My IP in your HELO! Access denied!"

 # отклоняем, если в EHLO наше имя хоста
 deny message = Message was delivered by ratware - own
 condition = ${if match_domain{sender_helo_name}{$primary_hostname:+local_domains:+relay_to_domains}{true}{false}}
 log_message = remote host used our name in EHLO/HELO.

 # отклоняем отправителей с именем хоста только из цифр
 deny condition = ${if match{$sender_helo_name}{N^d+$N}{yes}{no}}
 hosts = !127.0.0.1 : !localhost : *
 message = "Incorrect HELO string"

 # отклонять отправителей, у которых в имени хоста adsl/dialup и т.д.
 # не используется в данном случае
 deny message = "your hostname is bad (adsl, poll, ppp & etc)."
 condition = ${if match{$sender_host_name}{adsl|dialup|pool|peer|dhcp}{yes}{no}}

 # задаём задержку при подключении клиента
 # спам-боты как правило не дожидаются ответа сервера
 # требуется smtp_enforce_sync = true
 set acl_m0 = 30s
 accept hosts = +relay_from_hosts:127.0.0.0/8
 set acl_m0 = 0s
 delay = $acl_m0

 # проверяем в спам-базах
 # сервера спам-баз опрашиваются по очереди
 # сверху вниз, если не отправитель не найден на первом, то
 # запрашивается второй, и т.д.;
 # если не найден ни в одном
 # из списка - то почта пропускается
 deny message = "you in blacklist - $dnslist_domain -->$dnslist_text; $dnslist_value"
   log_message = REJECT: Listed in $dnslist_domain
   hosts = !+relay_from_hosts
   dnslists = cbl.abuseat.org : dul.dnsbl.sorbs.net : sbl-xbl.spamhaus.org
# проверяем наличие получателя в локальных доменах
 accept domains = +local_domains
 verify = recipient

 # принимаем почту от локальных доменов
 accept hosts = +relay_from_hosts

 # пропускаем прошедшим авторизацию
 accept authenticated = *

 # если письмо не попало не под одно правило в списке - отклоняем его
 deny message = "relay not permitted"
 log_message = "REJECT: We aren't an open relay"

acl_check_mime:

  deny  message = No executable files please
        condition = ${if match{${lc:$mime_filename}}{\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} {yes}{no}}

  accept

acl_check_data:

 deny malware = *
 message    = This message contains a virus ($malware_name)
 log_message = Virus found ($malware_name) for $recipients size $message_size

 accept

Routes/Transport

begin routers

dnslookup:
 driver = dnslookup
 domains = ! +local_domains
 transport = remote_smtp
 ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
 no_more

system_aliases:
 driver = redirect
 allow_fail
 allow_defer
 data = ${lookup mysql{SELECT `goto` FROM `alias` WHERE `address`='${quote_mysql:$local_part@$domain}' OR `address`='${quote_mysql:@$domain}'}}
dovecot_user:
 driver = accept
 condition = ${lookup mysql{SELECT `goto` FROM `alias` WHERE `address`='${quote_mysql:$local_part@$domain}' OR `address`='${quote_mysql:@$domain}'}{yes}{no}}
 transport = dovecot_delivery

begin transports

#DKIM OPTS
DKIM_DOMAIN = ${lc:${domain:$h_from:}}
DKIM_FILE = /etc/exim/domains/${lc:${domain:$h_from:}}/dkim.pem
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}

remote_smtp:
  driver = smtp
  max_rcpt = 10
  delay_after_cutoff = false
  dkim_domain = DKIM_DOMAIN
  dkim_selector = mail
  dkim_private_key = DKIM_PRIVATE_KEY
  dkim_canon = relaxed
  dkim_strict = 0

dovecot_delivery:
 driver = pipe
 command = /usr/libexec/dovecot/deliver -d $local_part@$domain
 message_prefix =
 message_suffix =
 delivery_date_add
 envelope_to_add
 return_path_add
 log_output
 user = exim

address_pipe:
 driver = pipe
 return_output

address_reply:
 driver = autoreply

Dovecot

Установим и настроим dovecot

[root@mail ~] yum -y install dovecot dovecot-mysql
[root@mail ~] usermod -G dovecot,vmail dovecot

Web services

Nginx+PHP-FPM

[root@mail ~] yum -y install nginx php-fpm php-cli php-mbstring php-imap php-mysql php-xml php-intl php-ldap
#настроим php, установим временную зону,
[root@mail ~] vim /etc/php.ini
date.timezone = Europe/Kiev

Запускаем и добваляем в автозагрузку nginx и php-fpm

[root@mail ~] systemctl start nginx php-fpm
[root@mail ~] systemctl enable nginx php-fpm

Postfixadmin

Установим и проведем первичную настройку

[root@mail ~] mkdir /srv/www/
[root@mail ~] cd
[root@mail ~] tar -xvf postfixadmin-3.0.tar.gz
[root@mail ~] mv postfixadmin-3.0/ postfixadmin && mv postfixadmin /srv/www/
[root@mail ~] chown -R nginx.nginx /srv/www
# настроим php-fpm юнит для postfixadmin
[root@mail ~] vim /etc/php-fpm.d/postfixadmin.conf
# настроим nginx vhost для postfixadmin
[root@mail ~] vim /etc/nginx/conf.d/postfixadmin.conf
#внесем настройеи базы данных в конфиг Postfixadmin
[root@mail ~] vim /srv/www/postfixadmin/config.inc.php


#/etc/php-fpm.d/postfixadmin.conf
[postfixadmin]
listen = /var/run/php-fpm/postfixadmin.sock
listen.allowed_clients = 127.0.0.1

user = nginx
group = nginx

listen.owner = nobody
listen.group = nobody

pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 3

slowlog = /var/log/php-fpm/postfixadmin-slow.log

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

php_admin_value[error_log] = /var/log/php-fpm/postfixadmin-error.log
php_admin_flag[log_errors] = on
php_admin_value[open_basedir] = /srv/www/postfixadmin:/tmp
php_value[session.save_handler] = files
php_value[session.save_path] = /tmp


#/etc/nginx/conf.d/postfixadmin.conf
server {
  
        listen 91.205.17.159:8080;
        server_name pf.aplus.tools;
   
        root            /srv/www/postfixadmin;
        index           index.php;
        charset         utf-8;

        access_log  /var/log/nginx/postfixadmin.log combined;
        error_log   /var/log/nginx/postfixadmin.error.log error;

        add_header Strict-Transport-Security max-age=31536000;
        add_header X-Frame-Options DENY;

        # auth_basic "Restricted area";
        # auth_basic_user_file /etc/nginx/passwd;

        location / {
                try_files $uri $uri/ @rewrites;
        }
    
        location @rewrites {
                rewrite ^ /index.php last;
        }

        ## php block
        location ~ \.php?$ {
                try_files $uri =404;
                include fastcgi_params;
                include fastcgi.conf;

                fastcgi_pass  unix:/var/run/php-fpm/postfixadmin.sock;

                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_intercept_errors on;
                fastcgi_split_path_info ^(.+\.php)(.*)$;
                fastcgi_hide_header X-Powered-By;
        }

}


#/srv/www/postfixadmin/config.inc.php
$CONF['configured'] = false;             >> $CONF['configured'] = true;
$CONF['default_language'] = 'en';        >> $CONF['default_language'] = 'ru';
$CONF['database_type'] = 'mysqli';       >> $CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'vexim';        >> $CONF['database_user'] = 'pf_admin';
$CONF['database_password'] = 'PassWord'; >> $CONF['database_password'] = 'fizvSdyCXy';
$CONF['database_name'] = 'vexim';        >> $CONF['database_name'] = 'vmail';
$CONF['admin_email'] = '';               >> $CONF['admin_email'] = '[email protected]';
$CONF['smtp_client'] = '';               >> $CONF['smtp_client'] = 'mail.aplus.tools';

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

[root@mail ~] systemctl restart nginx php-fpm

Для дальнейшей настройки откроем в броузере страницу конфигурации postfixadmin http://pf.aplus.tools:8080/setup.php

Если все проверки пройдено успешно то продолжим конфигурирование.

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

Pfadmin setup1.png

# vim /srv/www/postfixadmin/config.inc.php
$CONF['setup_password'] = ''; >> $CONF['setup_password'] = '67ca56aa538ffa2d9e8d52e52389b920c7:9b9aded104dbe14bc485d2aabf70078d';

Дальше с использованием введенного рание пароля создаем аккаунт администратора.

Pfadmin .png

Для входа в панель используем http://pf.aplus.tools:8080/login.php

Roundcube