В этом посте будут рассмотрены дальнейшие приключения по настройке почтового сервера. А именно настройка МТА Exim и его связка с MDA DBmail.
Исходя из комментариев к предыдущей статье, постараюсь изложение сделать более подробным.
В комментариях к прошлой статье многие задавали вопрос почему выбран именно такой вариант хранения сообщений, а именно в базе данных. Ведь есть уже проверенный временем способ хранения в файловой системе. Тем более что сама СУБД работает поверх файловой системы и зависит от неё. Касаемо хранения почты есть замечательный формат хранения почты Maildir, который прекрасно стыкуется с распространёнными opensource SMTP-серверами Exim и Postfix.
Давайте вкратце для сравнения посмотрим как обычно обстоит дело с хранением почтовых соообщений в формате Maildir: пришедшие письма складируются в соответствующие директории на почтовом сервере, где ждут своей участи — быть удалёнными после того как их заберёт почтовый клиент, либо остаться (зависит от настроек и задумок). Находясь на сохранение почтовые сообщения представляют собой обыкновенные файлы, доступ к которым ограничен лишь настройками, определяемыми правами доступа на уровне файловой системы. Помимо этого как и все данные, которые не обрабатываются, а хранятся, любят резервное копирование и прочёсывание на предмет анализа. Ну и разбухать со временем имеют тягу. Вроде бы ничего сложного и особых проблем тоже нет.
Чем же тогда привлекательно хранение в базе данных? Как выше было замечено СУБД работает поверх файловой системы, только при этом имеет столько нюансов и особенностей, настроив которые, можно добиться большей скорости обращения к объектам базы данных нежели к индивидуальным файлам. Реляционные СУБД лучше приспособлены к обработке больших объемов структурированных данных. По гибкости и своим возможностям SQL-запросы несоизмеримы с тем, что можно сделать, обрабатывая Maildir различными самописными скриптами на Perl или Python. Также можно задейстовать различные механизмы предоставляемые СУБД: репликация, фрагментирование, балансировка нагрузки, резервное копирование. Помимо этого такой подход позволяет довольно легко разнести хранилище почтовых сообщений и сервисы приёма и отправки сообщений, что удобно при распихивании по контейнерам и виртуальным машинам.
4 Установка и настройка МТА Exim
4.1 Установка МТА Exim
Поскольку почтовый сервер postfix, идущий по умолчанию не нужен, поэтому он остановлен и выключен из автозапуска:
/etc/init.d/postfix stop
chkconfig postfix off
Будут установлены два основных пакета — сам МТА exim и пакет для работы с СУБД Postgresql — exim-pgsq. Если душа или производственная необходимость требуют обработчика серых списков (exim-greylist) или монитора exim (exim-mon), то доустановить их можно по собственному усмотрению.
yum install exim exim-pgsql
Для корректной работы с TLS сертификатами, системный пользователь exim добавлен в группу mail:
usermod -a -G mail exim
Postfix уже не нужен, поэтому удаляется. После его деинсталяции, символические автоматически будут переправлены на exim:
yum erase postfix
Затем добавить в автозапуск exim и сделать сервером почты по умолчанию:
chkconfig --level 35 exim on
alternatives --config mta
Имеется 1 программа, которая предоставляет 'mta'.
Выбор Команда
-----------------------------------------------
*+ 1 /usr/sbin/sendmail.exim
Enter - сохранить текущий выбор[+], или укажите номер: 1
4.2 Настройка МТА Exim
Конфигурационный файл exim.conf приводится к такому виду:
# Имя хоста. Используется в EHLO.
primary_hostname = wow.test.com
# Доменная зона, куда будут приходить письма
domainlist local_domains = test.com : localhost
# Список хостов с которых разрешён неавторизованый релей.
hostlist relay_from_hosts = 127.0.0.1 : localhost
# Список локальных подсетей.
hostlist local_area = 192.168.0.0/24 : 192.168.17.0/24
# Эта опция задаёт хосты для которых резервируются SMTP-соединения.
# Имеет смысл включать при большой нагрузке на сервер.
##smtp_reserve_hosts = local_area
# ACL
acl_smtp_auth = acl_check_auth
acl_smtp_helo = acl_check_helo
acl_smtp_connect = acl_check_connect
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
acl_smtp_mime = acl_check_mime
# Подключение к spamassasin
##spamd_address = 127.0.0.1 783
# Чтобы быстрее работало подключаемся через сокет:
spamd_address = /var/run/spamassassin/spamd.sock
# TLS
tls_advertise_hosts = +local_area
tls_certificate = /etc/pki/tls/certs/wow.test.com.pem
tls_privatekey = /etc/pki/tls/private/wow.test.com.pem
tls_on_connect_ports = 465
tls_require_ciphers = AES : MD5
gnutls_require_mac = SHA_512
tls_verify_certificates = *
# Server
# Дефолтовые порты
daemon_smtp_ports = 25 : 465
# Число повторов при неудачном запуске
daemon_startup_retries = 5
# Время ожидания между повторными запускам
daemon_startup_sleep = 30s
# Cписок ip адресов и портов через двоеточие, откуда exim будет принимать
# почту. Только эти адреса считаются локальными при маршрутизации и
# проверке зацикливания почты
local_interfaces = 127.0.0.1 : 192.168.0.2
# Имя домена добавляемое для локальных отправителей (реальных юзеров системы) т.е. Почта
# отправляемая от root, будет от root@домен_указанный_здесь.
qualify_domain = test.com
# Имя хоста для ситуации, обратной предыдущей, - это имя домена добавляемое
# к почте для системных юзеров, ну и вообще для почты пришедшей на адрес
# типа root.
qualify_recipient = test.com
# Не принимать почту, когда вместо доменного адреса указывается адрес IP
allow_domain_literals = false
# Exim отказывается от root привилегий при запуске процесса доставки,
# и повсюду работает как пользователь exim. Это строго ограничивает
# возможные виды локальной доставки, но жизнеспособно лишь в
# определённых типах конфигурации, например при даставке по протоколу lmtp
# через сетевую подсистему (см. transport_dbmail).
# Имеет смысл включать при доставке по tcp/ip.
###deliver_drop_privilege = true
# Указываю пользователя и группу от которых будет работать exim
exim_user = exim
exim_group = exim
# Запрет работы доставки под пользователями root, daemon, bin, sync, adm
# в целях безопасности
never_users = root : daemon : bin : sync : adm
# Проверка соответствие прямой и обратной зон для всех хостов.
host_lookup = *
# Требовать авторизацию через безопасное SSL соединение
auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
# Если эта опция установленна, обработка очереди останавливается,
# когда средняя загрузка системы больше значения этой опции.
# Т. е. при превышении указанного значения load avarege, останавливается
# обработка почтовых сообщений в очереди
deliver_queue_load_max = 10
# LOGING
log_selector =
+all_parents
+connection_reject
+lost_incoming_connection
+received_sender
+received_recipients
+smtp_confirmation
+smtp_syntax_error
+smtp_protocol_error
-queue_run
# Убираю проверку identd на клиентской стороне.
rfc1413_query_timeout = 0s
# Если сообщение не было доставлено, то создаётся сообщение об ошибке.
# Если сообщение об ошибке не удалось доставить то оно замораживается
# на указанный в этом пункте срок, после чего снова осуществляется попытка доставить его.
ignore_bounce_errors_after = 2d
# Замороженные сообщения, находящиеся в очереди, дольше указанного
# времени удаляются и создаётся сообщение об ошибке (при условии,
# что это не было недоставленное сообщение об ошибке )
timeout_frozen_after = 7d
# Список адресов, разделённых через запятой, на которые засылаются письма
# о замороженных сообщениях
freeze_tell = support@test.com
# Через какое время повторять попытку доставки замороженного сообщения
auto_thaw = 4h
# Ограничение размера сообщения
message_size_limit = 12M
# Если число получателей (RCPT) превышает это число, то на все
# последующие команды RCPT возвращается код возврата 452,
# но все ранние получатели обрабатываются нормально
recipients_max = 24
# Полностью отвергать SMTP соединение со слишком большим числом
# получателей - коды 552, 554
recipients_max_reject = true
# Максимальное число одновременных подключений по SMTP.
smtp_accept_max = 24
# Максимальное число сообщений принимаемое за одно соединение
# от удалённого сервера (или пользователя)
smtp_accept_max_per_connection = 96
# Максимальное число подключений с одного хоста
smtp_accept_max_per_host = 8
# Если у сообщения много адресатов на удалённых хостах, то запускается
# до указанного числа максимально число параллельных процессов доставки
remote_max_parallel = 12
# Если средняя загрузка системы становиться выше чем тут указано, входящие
# SMTP-соединения принимаются только от тех хостов, которые совпадают с
# указанным в “smtp_reserve_hosts”
##smtp_load_reserve = 8
# Приветствие
smtp_banner = «Post Server»
accept_8bitmime = true
# Подключение к базе данных
# [hide mysql_servers = имя-сервера/имя-БД/имя пользователя/пароль],
# (PgSQL для получения данных маршрутизации) Или чтобы работать через
# сокет:
hide pgsql_servers = (/var/run/postgresql/.s.PGSQL.5432)/dovecot/pig/wes
##hide pgsql_servers = localhost/dovecot/pig/wes
# Отключение поддержки IPv6
disable_ipv6 = true
# Принудительная синхронизация. Если отправитель торопится подавать
# команды, не дождавшись ответа, то он посылается далеко и надолго
smtp_enforce_sync = false
# Убрать собственную временную метку exim`a из логов, её ставит
# сам syslogd
syslog_timestamp = no
######################################################################
# ACL CONFIGURATION #
# Specifies access control lists for incoming SMTP mail #
######################################################################
begin acl
# В acl_check_auth проверяется тип аутентификации. Разрешаю все типы
# аутентификации при использовании TLS и только CRAM аутентификации
# без TLS.
acl_check_auth:
accept encrypted = +local_domains
accept condition = ${if eq{${uc:$smtp_command_argument}}{CRAM-MD5}}
deny
# Проверка правильности поля HELO
acl_check_helo:
# Белый список для кривоватых отправителей до нас:
accept hosts = wildlsearch;/etc/exim/custom/white_list
# Спам лист для отъявленных:
deny condition = ${lookup {$sender_helo_name}wildlsearch{/etc/exim/custom/block_list}{yes}{no}}
delay = 30s
log_message = REJECT: a block list pessenger
# Запрет тех, кто не обменивается приветственными сообщениями (HELO/EHLO)
deny condition = ${if eq{$sender_helo_name}{}{yes}{no}}
hosts = *
message = Nice boys say HELO first
log_message = REJECT: HELO/EHLO require by SMTP RFC
# Запрет тех, кто подставляет свой IP в HELO
deny condition = ${if eq{$sender_helo_name}{$sender_host_address}{yes}{no}}
hosts = *
delay = 30s
log_message = REJECT: HELO/EHLO require by SMTP RFC
deny condition = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
hosts = !127.0.0.1 : !localhost : !192.168.0.2 : *
delay = 30s
log_message = REJECT: HELO/EHLO require by SMTP RFC
deny condition = ${if match{$sender_helo_name}{^[0-9].[0-9].[0-9].[0-9]}{yes}{no}}
delay = 30s
log_message = REJECT: HELO/EHLO require by SMTP RFC
# Запрет HELO с нашим именем
deny condition = ${if match_domain{$sender_helo_name}
{$primary_hostname : +local_domains }{true}{false}}
delay = 30s
log_message = REJECT: HELO с нашим именем
accept
# Проверка для начала SMTP соединения
acl_check_connect:
# Белый список для кривоватых отправителей до нас:
accept hosts = wildlsearch;/etc/exim/custom/white_list
# Спам лист для отъявленных:
drop hosts = wildlsearch;/etc/exim/custom/block_list
message = Sram blocking!
log_message = REJECT : Host in Black list
# Запрет пользователей с хостами, подпадающими
# под список ip-адресов /etc/exim/custom/net_block
drop hosts = net-iplsearch;/etc/exim/custom/net_block
message = This ip-address in our blacklist
log_message = REJECT : Net in black list
accept
# Этот список доступа описывает проверки, осуществляемые при вызове любой RCPT команды
acl_check_rcpt:
# Принимать сообщения которые пришли с локалхоста, не по TCP/IP
accept hosts = :
control = dkim_disable_verify
# Проверка на недопустимые символы для локальных получателей:
deny message = Restricted characters in address
domains = +local_domains
local_parts = ^[.] : ^.*[@%!/]
# Проверка на недопустимые символы для нелокальных получателей
deny message = Restricted characters in address
domains = ! +local_domains
local_parts = ^[./] : ^.*[@%!] : ^.*/\.\./
# Не принимать почту для постмастеров
deny local_parts = postmaster
# Проверка отправителя (присутствует ли в списке пользователей локального домена)
require verify = sender
require message = Sender did not verify
# Проверка аутентификации
accept authenticated = *
control = submission
control = dkim_disable_verify
# Проверка наличия получателя в локальных доменах
accept domains= +local_domains
require verify = recipient
message = Recipient did not verify
# Запрет хостов типа *adsl*; *dialup*; *pool*;.... Ведь нормальные люди с таких не пишут.
deny condition = ${if match{$sender_host_name}{adsl|dsl|dialup|pool|peer|dhcp} {yes}{no}}
message = Your host is not pleasant to Chuck Norris
log_message = REJECT : Bad type host
# Задержка. Это такой метод борьбы со спамом, основанный на принципе его
# рассылки. Считается, на этом задерживается почти весь спам.
warn
# Ставим дефолтовую задержку в 20 секунд
set acl_m0 = 20s
# Ставим задержку в 0 секунд своим хостам и дружественным сетям
hosts = local_area
set acl_m0 = 0s
warn condition = ${if and {{! match{$sender_host_name}
{N.+.outblaze.com$N}}
{eq{$acl_c0}{outblaze_helo}}}{yes}{no}}
set acl_m0 = 99s
warn condition = ${if and {{! match{$sender_host_name}
{N.+.outblaze.com$N}}
{eq{$acl_c2}{outblaze_domain}}}{yes}{no}}
set acl_m0 = 99s
# Пропускаем остальное
accept
# Проверка тела письма
acl_check_data:
# Защита от спама с помощью SpamAssassin.
# Bypass SpamAssassin checks if the message is too large (100 кБ).
accept condition = ${if >={$message_size}{100000} {1}}
add_header = X-Spam-Note: SpamAssassin run bypassed due to message size
# Run SpamAssassin, but allow for it to fail or time out. Add a warning message
# and accept the mail if that happens. Add an X-Spam-Flag: header if the SA
# score exceeds the SA system threshold.
warn spam = nobody/defer_ok
add_header = X-Spam-Flag: YES
accept condition = ${if !def:spam_score_int {1}}
add_header = X-Spam-Note: SpamAssassin invocation failed
# Unconditionally add score and report headers
warn add_header = X-Spam-Score: $spam_score ($spam_bar)n
X-Spam-Report: $spam_report
# And reject if the SpamAssassin score is greater than ten
deny condition = ${if >{$spam_score_int}{120} {1}}
message = Your message scored $spam_score SpamAssassin point. n
Report follows: $spam_report
# Проверка содержимого писем.
deny condition = ${if >{$demime_errorlevel}{2}{1}{0}}
message = This message contains a MIME error ($demime_reason)
log_message = REJECT : Error in MIME
demime = *
deny message = Possible Microsoft attack ($found_extension)
log_message = REJECT : Bad attachment
demime = mad : maf : mag : mam : maq : mar : mas : mat : mav : maw
: xnk : wsc : wsf : wsh : vbs : vbe : sct : scf : ins : hta : cnf : chm
: reg : js : com : cmd : scr : vbs : bat : lnk : pif : dll : cpl
deny condition = ${if >{$body_zerocount}{0}{1}{0}}
log_message = REJECT : NUL characters!
message = This message contains NUL characters
deny message = Incorrect headers syntax
log_message = REJECT : Incorrect header syntax
!verify = header_syntax
# Пропускаем остальное
accept
acl_check_mime:
# Декодирование mime сообщений. Полезно для дальнейшей проверки
# на вирусы
warn decode = default
# Можно очень быстро отсеять сообщения, просто запретив некоторые
# mime вложения, чаще всего содержащие вирусы, хотя, конечно, это не панацея.
# Поэтому следует на своё одуманное усмотрение.
deny message = Blacklisted file extension detected
condition = ${if match {${lc:$mime_filename}}{N(.acm|.ax|.bin|.bpl|.cat n
|.chm|.com|.cpl|.dat|.drv|.hlp|.ini|.msc|.nls n
|.ocx|.olb|.pif|.rom|.scr|.src|.sys|.tlb|.vbs|.vxd n
|.exe|.bat|.cmd|.msi|.asf n
$N}{1}{0}}
# Это китайского спама поубавит.
deny message = Sorry, noone speaks chinese here
condition = ${if eq{$mime_charset}{gb2312}{1}{0}}
# Пропускаем остальное
accept
######################################################################
# ROUTERS CONFIGURATION #
# Specifies how addresses are handled #
######################################################################
begin routers
# Роутер, осуществляющий поиск по MX-записям в DNS -- поиск маршрута к хосту в DNS. Не проверяются локальные домены, 0.0.0.0 и 127.0.0.0/8
# За коментарием ### вариант транспорта при доставке через tcp/ip.
# В данном случае рассматривается доставка через lmtp-socket.
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more
# Всё что осталось - это локальные адресаты.
# Доставка почты в dbmail
dbmail_user:
driver = accept
condition = ${lookup pgsql{SELECT alias_idnr FROM
dbmail_aliases WHERE
alias='${quote_pgsql:$local_part@$domain}' OR
alias='${quote_pgsql:@$domain}'}{yes}{no}}
##'#transport = transport_dbmail
transport = local_lmtp
cannot_route_message = Unknown user
######################################################################
# TRANSPORTS CONFIGURATION #
######################################################################
begin transports
# Доставка на удалённые хосты - по SMTP
remote_smtp:
driver = smtp
### Закоментирован вариант удалённой доставки по lmtp через tcp/ip
###transport_dbmail:
### driver = smtp
### protocol = lmtp
### hosts = 127.0.0.1
### allow_localhost
### return_path_add
# Локальная доставка через сокет lmtp, ну чтоб быстрее
local_lmtp:
driver = lmtp
socket = /var/run/dbmail/lmtpd.sock
batch_max = 8
user = exim
######################################################################
# RETRY CONFIGURATION #
######################################################################
# Повторы недоставленных писем.
begin retry
# Domain Error Retries
* * F,2h,20m; G,16h,1h,1.5; F,4d,6h
#####################################################################
# REWRITE CONFIGURATION #
######################################################################
# Преобразование адресов.
begin rewrite
####################################################################
# AUTHENTICATION CONFIGURATION #
######################################################################
# Секция авторизации при отправке писем.
begin authenticators
# Так авторизуется TheBat!
client_auth:
driver = cram_md5
public_name = CRAM-MD5
server_secret = ${lookup pgsql{SELECT passwd FROM dbmail_users
WHERE userid = '${quote_pgsql:$1}'}{$value}fail}
server_set_id = $1
server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
# Аутентификация по PLAN
PLAIN:
driver = plaintext
server_set_id = $auth2
server_prompts = :
server_condition = ${lookup pgsql{SELECT user_idnr FROM dbmail_users
WHERE userid = '${quote_pgsql:$2}'
AND passwd = '${quote_pgsql:$3}'}{1}fail}
server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
# Аутентификация через LOGIN
LOGIN:
driver = plaintext
server_set_id = $auth1
server_prompts = <| Username: | Password:
server_condition = ${lookup pgsql{SELECT user_idnr FROM dbmail_users
WHERE userid = '${quote_pgsql:$1}'
AND passwd = '${quote_pgsql:$2}'}{1}fail}
server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
######################################################################
# CONFIGURATION FOR local_scan() #
######################################################################
# begin local_scan
# End of Exim configuration file
# End of Exim configuration file
Создание дополнительных файлов с белыми и чёрными списками, описанных ранее в конфигурационном файле Exim:
mkdir /etc/exim/custom/
touch /etc/exim/custom/white_list /etc/exim/custom/block_list /etc/exim/custom/net_block
chcon -R -u system_u /etc/exim/custom/*
restorecon -R -v /etc/exim/custom/*
*.rmc.tog.me
2-smtp.mecrury.ru
*.virtual.com.ar
*.doory.net
*.uwpronto.ca
*.ventil.pl
*.ntdalin.net
*subscribe.ru
*ucoz.net
221.128.0.0/16
221.129.0.0/16
Огромная благодарность Лиссяре за перевод документации по Exim и статьи по настройке.
4.3 Настройки SELinux для Exim
По идее модуль политики для Exim должен быть установлен:
semodule -lv |grep exim
exim 1.4.2
Если его по какой-то причине нет, то в каталоге /usr/share/selinux/targeted лежит много разных интересных политик. Здесь имеется политика SELinux для exim. Её можно взять для своих нужд:
bunzip2 -d exim.pp.bz2
semodule -i exim.pp
Разрешить подключаться exim-у к БД:
setsebool -P exim_can_connect_db on
Поскольку пользовательские данные будут храниться в БД, следовательно права на управление непривилегированными файлами пользователей не требуются, поэтому переключатели exim_manage_user_files и exim_read_user_files остаются в состояние по умолчанию.
Здесь приведены настройки политики TE для SELinux, выловленных силами утилиты audit2allow (grep exim /var/log/audit/audit.log | audit2allow), созерцанием вывода netstat -anZ и многочисленными опытами:
module post 1.0;
require {
type sysfs_t;
type exim_t;
type spamd_t;
type initrc_t;
type var_run_t;
type spamd_var_run_t;
class file { open read };
class dir search;
class sock_file { read write };
class unix_stream_socket connectto;
}
#============= exim_t ==============
allow exim_t sysfs_t:dir search;
allow exim_t sysfs_t:file { open read };
allow exim_t spamd_var_run_t:dir search;
allow exim_t spamd_var_run_t:sock_file write;
allow exim_t spamd_t:sock_file { read write };
allow exim_t var_run_t:sock_file write;
allow exim_t initrc_t:dir search;
allow exim_t initrc_t:sock_file { read write };
allow exim_t initrc_t:unix_stream_socket connectto;
Лирическое отступление. Прошу обратить внимание и действовать только исходя из своих сил и возможностей. В данной политике есть довольно слабое место — exim подключается к сокет-файлу, который работает в домене initrc_t. Причиной тому что агент доставки сообщений конечным пользователям DBmail работает в этом домене. Перерыл интернеты, так и не нашёл политики для этого приложения, а написать грамотную и безопасную политику, каюсь, пока не по зубам. Если есть сомнения по поводу безопасности, то лучше плюнуть на эти сокеты и работать через tcp/ip.
Компилирование и загрузка модуля политики SELinux:
checkmodule -M -m -o post.mod post.te && semodule_package -o post.pp -m post.mod
semodule -i post.рр
5 Проверка работоспособности связки Dbmail+Exim+PostgreSQL
У DBmail есть хорошая возможность, он позволяет хранить в базе данных пароли сразу в зашифрованном виде (enryption_type=md5). Для этого в параметрах команды управления пользователями необходимо указать -p md5-hash:
dbmail-users -a user@test.com -p md5-hash -w shmser -s user@test.com
Adding INBOX for new user... ok.
[user@test.com]
Done
user@test.com:x:4:0:0.00:0.00:user@test.com
В базу пароль будет записан в виде:
$1$SKWJC5xL$PVynlB6pq3VflNi9IL7ow.
Более подробно о управлении пользователями dbmail здесь, тут и тама.
Теперь очередь проверить конфигурационный файл exim на наличие ошибок:
exim -bV
Если ошибок не найдено, можно запустить exim в режиме отладки:
exim -bd -d+all&
Если и здесь ошибок нет, то уже можно проверить распознавание локальной почты:
exim -bt user@test.com
user@test.com
router = dbmail_user, transport = lmtp_delivery
Если ошибок нет, проверим распознавание почты на внешние адреса:
exim -bt support@microsoft.com
router = dnslookup, transport = remote_smtp
host microsoft-com.mail.protection.outlook.com [207.46.163.138] MX=10
host microsoft-com.mail.protection.outlook.com [207.46.163.215] MX=10
host microsoft-com.mail.protection.outlook.com [207.46.163.247] MX=10
В случае положительного исхода, можно пробовать отправлять самые настоящие тестовые письма локальному пользователю и себе любимому на внешний ящик:
exim -v user@test.com
From: user@test.com
To: user@test.com
Subject: Splin
Check the microphone
^D
На всякий случай Шпаргалки по полезным командам exim 1, 2, 3.
В следующей (заключительной) статье собираюсь дорассмотреть окончательно настройку почтового сервера. Туда войдут описание настройки Spamassassin, подсистемы аудита и журналирования системных событий Auditd, а так же программы защиты системы от попыток вторжения Fail2ban.
Автор: bARmaleyKA