Последний основной компонент почтового сервера — SMTP сервер.
SMTP сервер, это именно та часть которая будет отсылать и принимать почту от удаленных серверов тут же можно организовать и проверку на вирусы, а также спам фильтр чтоб облегчить жизнь конечному пользователю. Но так как ни один спам фильтр не застрахован от ложных срабатываний всю спам почту будем складывать папку «spam storage»

Прежде чем приступить к установке и настройке Exim убедитесь что:

- У вас создана база данных пользователей с помощью postfixadmin 

- Установлен и настроен Dovecot

Для устанавливаем Exim, нам понадобятся два пакета  Exim и Exim-mysql
выполняем команды в консоли:

zypper in exim
zypper in exim-mysql

Переходим в папку «/etc/exim/», тут мы будем редактировать конфиг эксима exim.conf

После корректировки конфиг должен выглядеть примерно вот так -

######################################################################
# Runtime configuration file for Exim                                #
###################################################################### 
# 
###################################################################### 
# MAIN CONFIGURATION SETTINGS                                        # 
###################################################################### 
# 
# Имя хоста, которое используется в HELO/EHLO. 
# Это имя должно совпадать с тем что укачано в MX записи DNS сервера.
primary_hostname = vneshservice.com
# 
# Вводим данные для подключения к MySQL серверу. 
# `hide`, вначале, означает, что при вызове проверки конфига командой 
# exim -bV config_file эти данные не будут отображаться. 
# хост/имя_бд/пользователь/пароль
hide mysql_servers = localhost/exim/exim/password
# 
# Домены для которых сервер будет принимать почту. В данном случае mysql запрос
domainlist local_domains = ${lookup mysql{SELECT domain FROM domain \ 
		WHERE domain='${domain}' AND backupmx='0' AND active=1}}
# 
# Список доменов, для которых разрешен релей через данный сервер. Выборка 
# делается из БД MySQL. 
domainlist relay_to_domains =${lookup mysql{SELECT domain FROM domain \
		WHERE domain='${domain}' AND backupmx='0' AND active=1}}
# 
# Список серей и хостов которым будет разрешена отправка почты без авторизации 
# Как говорил доктор Хаус, никому нельзя верить поэтому я оставил тут только 
# локалхост. Если добавить в разрешенные сети внутреннюю сеть любой зараженный 
# комп сети сможет рассылать спам без ограничений через наш сервер. 
hostlist   relay_from_hosts = 127.0.0.1
#
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
# 
# Говорим почтовому серверу на какой порт передавать писльмо для сканирования 
# на вирусы
av_scanner = clamd:127.0.0.1 3310
# 
# А также спам проверяльщик, в моем случае спам ассасин
spamd_address = 127.0.0.1 783
# 
# Хосты и и пути для TLS шифрования, у меня отключено 
# tls_advertise_hosts = *
# tls_certificate = /etc/ssl/exim.crt
# tls_privatekey = /etc/ssl/exim.pem
# tls_on_connect_ports = 465
# 
# Порты SMTP
daemon_smtp_ports = 25 : 587
# 
# Имя домена добавляемое для локальных отправителей (реальных 
# юзеров системы) т.е. почта отправляемая от root, будет от 
# root@домен_указанный_здесь. Если пункт незадан, то используется 
# имя хоста из `primary_hostname`.
qualify_domain = example.com
# 
# Имя хоста для ситуации, обратной предыдущей, - это имя домена 
# добавляемое к почте для системных юзеров, ну и вообще для почты 
# пришедшей на адрес типа `root`
qualify_recipient = example.com
# 
# А это как раз кусок вышеописанного анахронизма - про почту в 
# виде user@[222.222.222.222] - принимать её или нет. По дефолту 
# (когда строка закомментирована) значение - false. Если захотите 
# поставить true то надо будет добавить в список доменов 
# комбинацию @[] - она означает `все локальные адреса`
allow_domain_literals = false
# 
# Пользователь от которого работает exim
exim_user = vmail
# 
# группа в кторой работает exim
exim_group = mail
# 
# Запрещаем работать как root
never_users = root

# Резолвить DNS-имена перечисленных хостов. 
host_lookup = *
# 
# Тоже анахронизм Это проверка - Ваш 
# хост спрашивает у удалённого, с которого было подключение, а кто 
# собстно ко мне подключился на такой-то порт? Если на удалённом хосте 
# работает identd - он может ответить (а может и не ответить - как 
# настроить), скажет UID пользователя от которого установлено 
# соединение, тип ОС, и имя пользователя. 
# Короче - если хостс поставить * то будет проверять все. Таймаут - 
# 0 то не будет ждать ответа ни от кого. По вышеописанным причинам - отключаем 
#rfc1413_hosts = *
rfc1413_query_timeout = 0s
# 
# По дефолту, экзим отфутболивает все `неквалифицированные` адреса, 
# состоящие тока из локальной части. Для того чтобы разрешить такие письма 
# определённых хостов используются эти директивы:
sender_unqualified_hosts = +relay_from_hosts
# 
# Если сообщение было недоставлено, то генерится соощение 
# об ошибке. Если сообщение об ошибке не удалось доставить 
# то оно замораживается на указанный в этом пункте срок, 
# после чего снова попытка доставить его. При очередной 
# неудаче - сообщение удаляется.
ignore_bounce_errors_after = 30m
# 
# Замороженные сообщения, находящиеся в очереди, дольше 
# указанного времени удаляются и генерится сообщение 
# об ошибке
timeout_frozen_after = 1d
# 
# Через какое время повторять попытку доставки 
# замороженного сообщения
auto_thaw = 3h
#
freeze_tell = postmaster@vneshservice.com
# 
# Параметры логирования
log_selector = +all_parents +lost_incoming_connection +received_sender +smtp_confirmation +smtp_syntax_error +smtp_protocol_error -queue_run
# 
# Разбиение каталога спула. Увеличивает производительность.
split_spool_directory = true
# 
###################################################################### 
# ACL CONFIGURATION                                                  # 
# Specifies access control lists for incoming SMTP mail              #
###################################################################### 
#
begin acl
#
acl_check_rcpt:
  # accept  hosts = :
  # Запрещаем письма содержащие в локальной части символы @; %; !; /; |.
  deny    message       = Restricted characters in address
          domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|]
  # 
  # Запрещаем недопустимые символы для нелокальных получателей.
  deny    message      = "Illegal characters are in an address."
	  domains       = !+local_domains
	  local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
  # 
  # Принимаем все для postmastera без проверок
  accept  local_parts   = postmaster
          domains       = +local_domains
  # 
  # Deny unless the sender address can be verified. #
  require verify        = sender
  #
  accept  hosts         = +relay_from_hosts
          control       = submission
  #
  accept  authenticated = *
          control       = submission
  # 
  # deny message = "Reverse DNS lookup not correct" 
  # condition = $host_lookup_failed 
  # 
  # Запрещаем тех, кто не обменивается приветственными 
  # сообщениями (HELO/EHLO)
  deny    message       = "HELO/EHLO require by SMTP RFC"
          condition     = ${if eq{$sender_helo_name}{}{yes}{no}}
  # 
  # Запрещаем тех, кто подставляет свой IP в HELO
  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!"
  # 
  # Запрещаем тех, кто в HELO пихает только цифры
  deny    condition     = ${if match{$sender_helo_name}{\N^\d+$\N}{yes}{no}}
          hosts         = !127.0.0.1 : !localhost : *
          message       = "can not be only number in HELO!"
   # 
  # Запрещаем тех, кто в блэк-листах. Серваки перебираются 
  # сверху вниз, если не хост не найден на первом, то 
  # запрашивается второй, и т.д. Если не найден ни в одном 
  # из списка - то почта пропускается.
  deny    message       = "you in blacklist - $dnslist_domain \n $dnslist_text"
          dnslists      = sbl.spamhaus.org:bl.spamcop.net:cbl.abuseat.org
  # 
  # Задержка. (это такой метод борьбы со спамом, 
  # основанный на принципе его рассылки) На этом рубается 
  # почти весь спам. Единственно - метод неприменим на 
  # реально загруженных MTA - т.к. в результате ему 
  # приходится держать много открытых соединений. 
  # но на офисе в сотню-две человек - шикарный метод. 
  #
  # warn
  # ставим дефолтовую задержку в 20 секунд 
  # set acl_m0 = 20s
  # warn
  # ставим задержку в 0 секунд своим хостам и 
  # дружественным сетям
  #        hosts = +relay_from_hosts:192.168.66.0/24
  #        set acl_m0 = 0s                                                              
   #
  require message = relay not permitted
          domains = +local_domains : +relay_to_domains
   #
  require verify = recipient
   #
  accept
#
acl_check_data:
  #Запрещаем сообщения в которых обнаружены вирусы
  deny    malware    = *
          log_message  = This message contains a virus ($malware_name).
  # 
#Спам не запрещаем а только добавляем в заголовок метку о том что это спам
  warn    spam     = nobody
          message  = X-Spam-Score: $spam_score\n\
                     X-Spam-Flag: YES\n\
                     Subject:*SPAM* $spam_score $h_Subject:\n\
                     X-Spam_report: $spam_report
 #
  accept
# 
# 
###################################################################### 
# ROUTERS CONFIGURATION # # Specifies how addresses are handled      # 
###################################################################### 
# THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT!           # 
# An address is passed to each router in turn until it is accepted.  # 
###################################################################### 
#
begin routers
# 
# Поиск маршрута к хосту в DNS. Если маршрут не найден в DNS - 
# то это `унроутабле аддресс`. Не проверяются локальные 
# домены, 0.0.0.0 и 127.0.0.0/8 #
dnslookup:
  driver = dnslookup
  domains = ! +local_domains
  transport = remote_smtp
  ignore_target_hosts = 0.0.0.0:127.0.0.0/8
  no_more
# 
# 
# Роутер для сообщений помеченных как спам. передает такие сообщения не 
# обычному транспорту, а специально настроенному для складываения всего 
# спама в отдельную папку
spam_router:
   driver = accept
   condition = ${if match{$h_X-Spam-Flag:}{YES}{yes}{no}}
   transport = spam_transport
   no_more
# 
# Примерно тоже самое что и выше только смотрит не на метку в сообщении 
# а делает запрос в базу данных 
blacklist_router:
    driver = accept
    condition = ${lookup mysql{SELECT chart FROM chart WHERE chart='$sender_address' limit 1}{yes}{no}}
    transport = bl_transport
    no_more
# 
# Почтовые алиасы (виртуальные адреса). Выборка делается из БД MySQL.  
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}' AND active = '1'}}
  file_transport = address_file
  pipe_transport = address_pipe
# 
# Принимаем почту для валидного пользователя. Выборка делается из БД о пользователях dovecot в MySQL
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
    no_more
# 
###################################################################### 
# TRANSPORTS CONFIGURATION                                           #
###################################################################### 
# ORDER DOES NOT MATTER                                              # 
# Only one appropriate transport is called for each delivery.        # 
###################################################################### 
#
begin transports
# # Доставка на удалённые хосты
remote_smtp:
  driver = smtp
  interface = 82.207.101.169
  # Доставка пользователся dovecot, для доставки используется утилита довекота deliver #
  dovecot_delivery:
  driver = pipe
  command = /usr/lib/dovecot/deliver -d $local_part@$domain 
  delivery_date_add
  envelope_to_add
  return_path_add
  log_output
  user = vmail
  group = mail
# 
# Транспорт для доставки сообщений, отправители которых в блек листе, в спец папку 
bl_transport:
   driver = pipe
   command = /usr/lib/dovecot/deliver -d $local_part@$domain -m 'Public/Spam storage'
   delivery_date_add
   envelope_to_add
   return_path_add
   user = vmail
   group = mail
# 
# Транспорт для доставки сообщений помеченных как спам в спец папку
spam_transport:
  driver = pipe
  command = /usr/lib/dovecot/deliver -d $local_part@$domain -m 'Public/Spam storage'
  delivery_date_add
  envelope_to_add
  return_path_add
  user = vmail
  group = mail
#
address_pipe:
  driver = pipe
  return_output
#
address_reply:
  driver = autoreply
# 
###################################################################### 
# RETRY CONFIGURATION                                                #
######################################################################

begin retry
# Настройка повтора недоставленных писем. 
# Address or Domain Error Retries 
# ----------------- ----- -------
*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h
# 
###################################################################### 
# REWRITE CONFIGURATION                                              #
###################################################################### 
# 
# Переписываем адреса некоторых пользователей. 
# Иногда необходимо чтоб несколько человек отправляли сообщения какбы с 
# одного адреса. 
# 
begin rewrite
user1@example.com		info@example.com Ffrs
user2@example.com		info@example.com Ffrs
user3@example.com		info@example.com Ffrs
# 
###################################################################### 
# AUTHENTICATION CONFIGURATION                                       # 
###################################################################### 
#
begin authenticators
# 
# Аутентификация пользователей. Так как мы рассматриваем эксим в связке с 
# Pop3/imap сервером dovecot, то и небудем с аутентификацией в EXIM особо 
# заворачиваться, пусть этим довекот занимается, такм уже все настроено
dovecot_plain:
  driver = dovecot
  public_name = PLAIN
  server_socket = /var/run/dovecot/auth-client
  server_set_id = $auth1
#
dovecot_login:
  driver = dovecot
  public_name = LOGIN
  server_socket = /var/run/dovecot/auth-client
  server_set_id = $auth1

Запускаем Exim и добавляем его в автозапуск

rcexim start
chkconfig -l 35 exim

Выполним тестовою отправку письма, выполнив SMTP-диалог:

# telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 example.com ESMTP Exim
ehlo example.com
250-example.com Hello example.com [127.0.0.1]
250-SIZE 20971520
250-PIPELINING
250-AUTH LOGIN PLAIN
250-STARTTLS
250 HELP
mail from: test@example.com
250 OK
rcpt to: info@example.com
250 Accepted
data
354 Enter message, ending with "." on a line by itself
To: info@example.com
From: test@example.com
Subject: TestMail

Hi!
This is a test message.
.
250 OK id=1QqZsP-000PQO-Se
quit
221 example.com closing connection
Connection closed by foreign host.

В логах можно глануть как все прошло
# cat /var/log/maillog

Если все Ок то поздравляю, у вас есть работающий SMTP сервер.