Exim - настройка почтового сервера на базе Exim с хранением списка пользователей в БД MySQL и поддержкой квотирования

Версия для печатиОтправить другуPDF version

MTA Exim

Давно уже собирался написать статью о настройке почтового сервера, но все никак не находилось свободного времени, во время настройки очередного "почтовика". Сейчас же вроде не очень "подгоняют", соответственно попытаемся все подробно задокументировать.

Итак, исходные данные:

  • домен: ispalternativa.net.ua
  • IP-адрес сервера: 91.221.84.10
  • имя сервера: mail.ispalternativa.net.ua

Важно! Согласно RFC, необходимо, чтобы "прямая" и "обратная" запись в ДНС совпадали. Тоесть в нашем случае, необходимо чтобы запись mail.ispalternativa.net.ua "резолвилась" в IP-адрес 91.221.84.10, а PTR-запись 91.221.84.10 была установлена в mail.ispalternativa.net.ua.

Проверяем эти условия:

# host mail.ispalternativa.net.ua
mail.ispalternativa.net.ua has address 91.221.84.10

# host 91.221.84.10
10.84.221.91.in-addr.arpa domain name pointer
mail.ispalternativa.net.ua.

С ДНС-записями почти разобрались... Проверим еще, чтобы МХ-запись домена указывала на наш почтовый сервер:

# dig MX ispalternativa.net.ua

; <<>> DiG 9.6.2-P2 <<>> MX ispalternativa.net.ua
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57347
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3

;; QUESTION SECTION:
;ispalternativa.net.ua.         IN      MX

;; ANSWER SECTION:
ispalternativa.net.ua.  2756    IN      MX      10 mail.ispalternativa.net.ua.
ispalternativa.net.ua.  2756    IN      MX      20 smtp.ispalternativa.net.ua.

;; AUTHORITY SECTION:
ispalternativa.net.ua.  2756    IN      NS      ns2.h26.hvosting.ua.
ispalternativa.net.ua.  2756    IN      NS      ns1.h26.hvosting.ua.

;; ADDITIONAL SECTION:
mail.ispalternativa.net.ua. 3600 IN     A       91.221.84.10
smtp.ispalternativa.net.ua. 2756 IN     A       91.200.40.26
ns1.h26.hvosting.ua.    344     IN      A       91.200.40.26
ns2.h26.hvosting.ua.    344     IN      A       62.149.29.26

;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Aug  7 00:15:03 2011
;; MSG SIZE  rcvd: 173

MX-запись указывает на наш сервер, здесь все в порядке. Пора приступать непосредственно к установке Exim.

Первым делом внесем некоторые изменения в /etc/make.conf. Добавим такую секцию:

# Задаем переменную - путь к каталогу портов
PORTSDIR?= /usr/ports
# EXIM
.if ${.CURDIR} == ${PORTSDIR}/mail/exim
LOG_FILE_PATH?= syslog
WITH_DEFAULT_CHARSET?= koi8-r
.endif

Дело в том, что по умолчанию Exim пишет логи в свой каталог, что не очень удобно. Указав же, что необходимо использовать syslog, логи будут писаться в /var/log/maillog. Добавляем именно в make.conf по той причине, что все опции, кроме логгирования, можно будет задать при запуске make config. Редактировать Makefile тоже не советую, поскольку при обновлении портов он просто будет перезаписан.

Подготовка к инсталляции окончена. Даем команду на установку.

# cd /usr/ports/mail/exim && make install clean && rehash

Выставляем необходимые опции сборки. Главное - не забыть включить поддержку MySQL...

Options for exim 4.76

[ ] ALT_CONFIG_PREFIX  Restrict the set of configuration files
[X] AUTH_CRAM_MD5      Enable CRAM-MD5 authentication mechanisms
[X] AUTH_DOVECOT       Enable Dovecot authentication mechanisms
[X] AUTH_PLAINTEXT     Enable plaintext authentication
[ ] AUTH_RADIUS        Enable radius (RFC 2865) authentication
[ ] AUTH_SASL          Enable use of Cyrus SASL auth library
[X] AUTH_SPA           Enable Secure Password Authentication
[X] CDB                Enable CDB-style lookups
[Х] CONTENT_SCAN       Enable exiscan email content scanner
[X] DAEMON             Install scripts to run as a daemon
[ ] DCC                Enable DCC at ACL support via dccifd
[ ] DEBUG              Build with debugging symbols
[X] DISABLE_D_OPT      Disable macros overrides using option -D
[X] DNSDB              Enable DNS-style lookups
[X] DSEARCH            Enable directory-list lookups
[X] EMBEDDED_PERL      Enable embedded Perl interpreter
[ ] EXIMON             Build eximon monitor (require XFree86!)
[X] ICONV              Enable header charset conversion
[ ] IPV6               Enable IPv6 support
[ ] KAS                Build with Kaspersky AntiSpam local scan 
[X] LMTP               RFC2033 SMTP over command pipe transport
[X] LSEARCH            Enable wildcarded-file lookups
[X] MAILDIR            Enable Maildir mailbox format
[X] MAILSTORE          Enable Mailstore mailbox format
[X] MBX                Enable MBX mailbox format
[X] MYSQL              Link against libmysqlclient library
[X] NIS                Enable NIS-style lookups
[X] OLD_DEMIME         Enable old, deprecated demime ACL
[ ] OPENLDAP           Link against libldap
[X] PAM                Enable PAM authentication mechanisms
[ ] PASSWD             Enable /etc/passwd lookups
[ ] PGSQL              Link against libpq
[X] READLINE           Enable readline(3) library
[ ] SASLAUTHD          Enable use of Cyrus SASL auth daemon
[ ] SA_EXIM            SA-Exim support
[ ] SO_1024            Build with Spamooborona-1024 local scan
[X] SPF                Enable Sender Policy Framework checking
[ ] SQLITE             Enable SQLite lookups
[X] SRS                Enable Sender Rewriting Scheme
[ ] SRS_ALT            Enable alternative SRS library
[X] SUID               Install the exim binary suid root
[ ] TCP_WRAPPERS       Enable /etc/hosts.allow access control
[X] TLS                Link against OpenSSL
[ ] WISHLIST           Include the unsupported patches
[ ] XCLIENT            Enable XCLIENT command in exim

Также не стоит забывать об антивирусной поддержке в Exim. Поэтому устанавливаем Clamav согласно этой статьи.

После установки и запуска Clamav приступаем к редактированию конфигурационного файла Exim. Постараюсь максимально комментировать строки, но не обещаю детальное описание. Скачать конфигурационный файл можно по этой ссылке.

А здесь вывод файла /usr/local/etc/exim/configure с комментариями.

############################################################################
#                  Runtime configuration file for Exim                     #
#                       MAIN CONFIGURATION SETTINGS                        #
############################################################################



# Имя хоста. Используется в HELO/EHLO. Необходимо, чтобы содержалось имя
# домена, для которого принимаем почту. Правильный вариант - чтобы этот
# параметр совпадал  с именем MX-записи.
primary_hostname = mail.ispalternativa.net.ua

# Список доменов, для которых будем принимать почту. В нашем случае
# выборка делается из БД MySQL.
domainlist local_domains = ${lookup mysql{SELECT domain FROM domains \
                        WHERE domain='${domain}' AND \
                        (type='LOCAL' OR type='VIRTUAL')}}



# Список доменов, для которых разрешен релей через данный сервер. Выборка
# делается из БД MySQL.
domainlist relay_to_domains = ${lookup mysql{SELECT domain FROM domains \
                        WHERE domain='${domain}' AND type='RELAY'}}

# Список отправителей, которых считать "спамерами". Выборка делается из БД
# MySQL. hostlist spamers = ${lookup mysql{SELECT senders FROM blacklist_host WHERE \
                        senders='${sender_host_address}'}}



# Список сетей, которым будет разрешена отправка без авторизации.
# Перечисляем сети, которые будут пользоваться даным сервером для
# отправки почты.
hostlist   relay_from_hosts = localhost : 127.0.0.1 : 91.221.84.0/23

# Выбираем данные из БД MySQL для поддержки квотирования.
GET_QUOTA=${lookup mysql{SELECT quota FROM users \
           WHERE login='${local_part}' AND domain='${domain}'}{${value}M}}



# Задаем квотирование.
MAILDIR_SIZE=${eval:${sg{${sg{${readfile{/var/exim/$domain/$local_part/maildirsize}\
                     {\n}}}{\N^.+?\n\N}{}}}{\N(?s)\s+-?\d+\n\N}{+}}0+500K}
# На каких портах будет "работать" Exim.
daemon_smtp_ports = 25 : 465 # Указываем, что на порту 465 будет TLS-шифрование. tls_on_connect_ports = 465
# Перечисляем, для каких хостов будет доступно TLS-шифрование.
tls_advertise_hosts = *

# Указываем путь к сертификату и ключу шифрования.
tls_certificate = /etc/ssl/certs/mail.pem
tls_privatekey = /etc/ssl/certs/mail.pem
# Выбираем, что будем логировать
# + - писать в логи,
# - - Не писать в логи.
# +all_parents - все входящие соединения
# +lost_incoming_connections - потеряные входящие соединения
# +received_sender - отправитель
# +received_recipients - получатель
# +smtp_confirmation - подтверждения SMTP
# +smtp_syntax_error - ошибки синтаксиса SMTP
# +smtp_connection - соединение SMTP
# +smtp_protocol_error - ошибки протокола SMTP
# -queue_run - работа очереди (замороженные мессаги)
log_selector = \
        +all_parents \
        +lost_incoming_connection \
        +received_sender \
        +received_recipients \
        +smtp_confirmation \
        +smtp_syntax_error \
        +smtp_connection \
        +smtp_protocol_error \
        -queue_run

# Убираем из логов временную метку Exim`a - её ставит syslogd
# Внимание! Если планируете использовать утилиту eximstats,
# необходимо установить в значение yes
syslog_timestamp = no

# Задаем acl для проверки почты.
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_mime = acl_check_mime
acl_smtp_data = acl_check_data

# "Цепляем" антивирус. Указываем путь к сокету Clamav.
av_scanner = clamd:/var/run/clamav/clamd.sock

# Доверенные пользователи.
trusted_users = www

# Имя домена добавляемое для локальных отправителей (пользователей системы). 
# Тоесть почта отправляемая от root, будет root@$qualify_domain.
qualify_domain = ispalternativa.net.ua

# Cписок IP-адресов интерфейсов, на которых ожидаются запросы.

local_interfaces = 127.0.0.1 : 91.221.84.10

# Принимать ли почту вида имя_пользователя@IP-адрес.
allow_domain_literals = false

# Имя пользователя и групы, от имени которых будет работать Exim.
exim_user = mailnull exim_group = mail

# В целях безопасности запрещаем работу от root-а.
never_users = root

# Когда доставка сообщения откладывается, Exim посылает предупреждающее
# письмо отправителю, с указанными интервалами.
delay_warning = 4h:8h:24h:48h

# При генерации сообщения об ошибка "вкладывать" не все сообщение, а 
# "кусок", указанного размера.
return_size_limit = 50k

# Резолвить DNS-имена перечисленных хостов.
host_lookup = *

# Таймаут для резолвинга идентификатора пользователя на удаленной машине.
rfc1413_hosts = * rfc1413_query_timeout = 0s

# Принудительна синхронизация команд. Не принимать команды от удаленного
# сервера "потоком".
smtp_enforce_sync = true
# Контроль повторяющихся строк логов.
syslog_duplication = false

# Разрешить, чтобы МХ указывал на IP-адрес.
allow_mx_to_ip
# Уничтожать недоставленные рикошеты, если они "старше" указанного времени.
ignore_bounce_errors_after = 2d

# Какой промежуток времени хранить "замороженные" сообщения.
timeout_frozen_after = 2d
# Максимальный размер письма.
message_size_limit = 20M

# Ограничение на максимальной количество одновременных входящих сообщений.
smtp_accept_max = 100
# Ограничение на максимальное количество сообщений в одной сесию.
smtp_accept_max_per_connection = 50

# Ограничение на максимальное количество сообщений с одного хоста.
smtp_accept_max_per_host = 20
# Количество соединений по стеку TCP/IP.
smtp_connect_backlog = 50

# Класть в очередь, при большем числе сообщений за одну сесию.
smtp_accept_queue_per_connection = 30
# Максимальное количество СМТП-доставок на одно сообщение.
remote_max_parallel = 15

# Разбиение каталога спула. Увеличивает производительность.
split_spool_directory = true
# "Приветствие" сервера.
smtp_banner = "$primary_hostname ESMTP Exim"
# Параметры соединения с БД MySQL: server/database/username/password.
hide mysql_servers = localhost/exim/exim/MySQL-pass-here ############################################################################ # ACL CONFIGURATION # # Specifies access control lists for incoming SMTP mail # ############################################################################
begin acl

acl_check_rcpt:

# Запрещаем письма содержащие в локальной части символы @; %; !; /; |.
deny message      = "Illegal characters are in an address."
     domains       = +local_domains
     local_parts   = ^[.] : ^.*[@%!/|]
# Запрещаем недопустимые символы для нелокальных получателей.
deny message      = "Illegal characters are in an address."
     domains       = !+local_domains
     local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./

# Запрещаем прием почты с определенных доменов. С них жестко СПАМ идет.
# orange.fr
deny message   = "All email from *.orange.fr - discarded!"
     condition = ${if match{$sender_helo_name}{.orange.fr}{yes}{no}}
# mdp2.net
deny message   = "All email from *.mdp2.net - discarded!"
     condition = ${if match{$sender_helo_name}{.mdp2.net}{yes}{no}}
# mail.comcast.net
deny message   = "All email from *.mail.comcast.net - discarded!"
     condition = ${if match{$sender_helo_name}{.mail.comcast.net}{yes}{no}}
# libero.it
deny message   = "All email from *.libero.it - discarded!"
     condition = ${if match{$sender_helo_name}{.libero.it}{yes}{no}}
# ono.com
deny message   = "All email from *.ono.com - discarded!"
     condition = ${if match{$sender_helo_name}{.ono.com}{yes}{no}}
# wanadoo.fr
deny message   = "All email from *.wanadoo.fr - discarded!"
     condition = ${if match{$sender_helo_name}{.wanadoo.fr}{yes}{no}}
# Разрешаем отправку, если отправитель находится в "белом списке". Выборка # делается из БД MySQL. accept senders=${lookup mysql{SELECT senders FROM whitelist \ WHERE senders='${quote_mysql:$sender_address}' \ OR senders='*@${quote_mysql:$sender_address_domain}' LIMIT 1}}
# Запрещаем отправку тем, кто внесен в "черный список". Выборка делается из
# БД MySQL.
deny message = "Your address in banlist!"
        senders=${lookup mysql{SELECT senders FROM blacklist \
        WHERE senders='${quote_mysql:$sender_address}' \
        OR senders='*@${quote_mysql:$sender_address_domain}' LIMIT 1}}

# Запрещаем отправку тем, кто "достал" и приравнивается к спамеру. Выборка
# делается из БД MySQL.
deny hosts = +spamers
     message = "Host rejected by spamers list on rbl.ispalternativa.net.ua!"
# Разрешаем отправку авторизованным пользователям.
accept authenticated = *

# Запрещаем тех, кто не обменивается приветственными сообщениями (HELO/EHLO)
deny message       = "HELO/EHLO required by SMTP RFC"
     condition     = ${if eq{$sender_helo_name}{}{yes}{no}}
# Запрещаем тех, кто в HELO "отдает" только цифры.
deny condition     = ${if match{$sender_helo_name}{\N^\d+$\N}{yes}{no}}
     hosts         = !127.0.0.1:!localhost:*
     message       = "There can not be only numbers in HELO!"

# Запрещаем тех, кто не пишет отправителя.
deny condition     = ${if eq{$sender_address}{}{yes}{no}}
     hosts         = +relay_from_hosts
     message       = "Your message have not return address"
# Запрещаем тех, кто подставляет свой IP в HELO.
deny message   = "The use of IP is forbidden in HELO!"
     hosts     = *:!+relay_from_hosts
     condition = ${if eq{$sender_helo_name}\
                      {$sender_host_address}{true}{false}}
# Запрещаем использовать наш IP в HELO. deny condition = ${if eq{$sender_helo_name}\ {$interface_address}{yes}{no}} hosts = !127.0.0.1 : !localhost : * message = "The use of my IP is forbidden!" # Запрещаем прием почты с динамических хостов. deny message = "Dynamic hosts is forbidden!" condition = ${if match{$sender_host_name}\ {dsl|dial|pool|peer|dhcp|cable} {yes}{no}}
# Запрещаем прием почты с хостов, которые находятся в блэк-листах.
deny    message       = rejected because $sender_host_address \
        is in a black list at $dnslist_domain\n$dnslist_text
        hosts         = !+relay_from_hosts
        !authenticated = *
        log_message   = found in $dnslist_domain
        dnslists      = bl.spamcop.net : \
                        cbl.abuseat.org : \
                        dnsbl.njabl.org : \
                        sbl-xbl.spamhaus.org : \
                        pbl.spamhaus.org

# Удерживание соединения. Метод борьбы со спамом.
# Метод не допускается на высокозагруженых серверах,
# поскольку в результате ему приходится удерживать
# много открытых соединений.
warn
# ставим дефолтовую задержку в 25 секунд
set acl_m0 = 25s
warn
# ставим задержку в 0 секунд для своих сетей
hosts = +relay_from_hosts
set acl_m0 = 0s
warn
# ставим задержку в 0 секунд для авторизованых пользователей
authenticated = *
set acl_m0 = 0s

warn
# пишем в логи задержку (если в этом есть необходимость)
logwrite = Delay $acl_m0 for $sender_host_name \
[$sender_host_address] with HELO=$sender_helo_name. Mail \
from $sender_address to $local_part@$domain.
delay = $acl_m0 # Проверка существования отправителя.
drop   message     = Rejected - Sender Verify Failed
       log_message = Rejected - Sender Verify Failed
       hosts       = *
       !verify     = sender/no_details/callout=2m,defer_ok
       !condition  =  ${if eq{$sender_verify_failure}{}}
# Проверка получателя в локальных доменах.
accept domains    = +local_domains
       endpass
       message    = $acl_verify_message
       verify     = recipient
# Проверяем получателя в релейных доменах.
accept domains  = +relay_to_domains
       endpass
       message  = "Unrouteable address!"
       verify   = recipient/callout=30s,defer_ok,use_postmaster
# Разрешаем почту от хостов в релейных доменах. accept hosts = +relay_from_hosts accept authenticated = * deny message = relay not permitted accept acl_check_mime:
# Запрещаем вложения определенных типов
deny message = Blacklisted file extension detected ($mime_filename)
condition = ${if match \
{${lc:$mime_filename}} \
{\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com|\.vbs|\.cpl)$\N}{1}{0}}
accept 
# ACL проверки "тела" письма.
acl_check_data: 

# Проверка антивирусом.
deny     message  = This message contains a virus ($malware_name).
demime   = *
malware  = */defer_ok

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. Не проверяются 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

# Почтовые алиасы (виртуальные адреса). Выборка делается из БД MySQL.
system_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup mysql{SELECT recipients FROM aliases \
   WHERE (local_part='${local_part}' AND domain='${domain}') \
   OR (local_part='*' AND domain='$domain')ORDER BY local_part='*' \
   LIMIT 1}}

# Перенаправления почты в случае необходимости.
userforward:
  driver = redirect
  check_local_user=false
  file = /var/exim/$domain/$local_part/forward
  user = mailnull
  group = mail
  allow_filter
  no_verify
  no_expn
  check_ancestor
  file_transport = address_file
  pipe_transport = address_pipe
  reply_transport = address_reply
  condition = ${if exists{/var/exim/$domain/$local_part/forward}{yes}{no}}
# Настройка квотирования. Мы не жадные, но порядок должен быть :)
# Выборка делается из БД MySQL.
virtual_user_quota_defer:
  driver          = redirect
  domains         = +local_domains
  condition       = ${if and{\
                    {exists{/var/exim/$domain/$local_part}}\
                    {exists{/var/exim/$domain/$local_part/maildirsize}}\
                    {>{GET_QUOTA}{0}}\
                    {>={MAILDIR_SIZE}{GET_QUOTA}}\
                    } }
  data            = :fail: Over quota!
  verify_sender = false
  allow_fail

# Принимаем почту для валидного пользователя. Выборка делается из БД MySQL.
virtual_localuser:
  driver = accept
  domains = ${lookup mysql{SELECT domain from domains \
              WHERE domain='${domain}'}}
  local_parts = ${lookup mysql{SELECT login from users \
              WHERE login='${local_part}' AND domain='${domain}'}}
  transport = local_delivery
  cannot_route_message = Unknown user

######################################################################
#                      TRANSPORTS CONFIGURATION                      #
######################################################################
#                       ORDER DOES NOT MATTER                        #
#     Only one appropriate transport is called for each delivery.    #
######################################################################
begin transports

# Доставка на удалённые хосты.
remote_smtp:
  driver = smtp
  interface =  91.221.84.10

# Локальная доставка.
local_delivery:
  driver = appendfile
  maildir_use_size_file
  check_string = ""
  create_directory
  delivery_date_add
  directory = ${lookup mysql{SELECT \
             LOWER(CONCAT('/var/exim/$domain/',login)) FROM users \
                WHERE login='${local_part}' AND domain='${domain}';}}
  directory_mode = 770
  envelope_to_add
  group = mail
  maildir_format
  maildir_tag = ,S=$message_size
  message_prefix = ""
  message_suffix = ""
  mode = 0660
  quota = ${lookup mysql{SELECT quota FROM users \
          WHERE login='${local_part}' AND domain='${domain}'}{${value}M}}
  quota_size_regex = S=(\d+)$
  quota_warn_threshold = 80%
  return_path_add
# Транспорт а-ля "труба"
address_pipe:
   driver = pipe
   return_output

# Запись в файл.
address_file:
  driver = appendfile
  delivery_date_add
  envelope_to_add
  return_path_add
# Автоответчик.
address_reply:
  driver = autoreply

# В никуда...
null_transport:
    driver = appendfile
    file = /dev/null

######################################################################
#                      RETRY CONFIGURATION                           #
######################################################################
begin retry

# Настройка повтора недоставленных писем.
*                      quota
*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h
######################################################################
#                      REWRITE CONFIGURATION                         #
######################################################################

# Секция перезаписи адресов. Не использую.
begin rewrite
######################################################################
#                   AUTHENTICATION CONFIGURATION                     #
######################################################################

begin authenticators
# Секция авторизации. Разные типы авторизации для разных почтовых клиентов.
fixed_login:
 driver = plaintext
 public_name = LOGIN
 server_prompts = Username:: : Password::
 server_condition = "${if and { \
                      {!eq{$1}{}} \
                      {!eq{$2}{}} \
                      {crypteq{$2}{\\{crypt\\}${lookup mysql{SELECT \
                      password FROM users \
                      WHERE login='${local_part:$1}' \
                      AND domain='${domain:$1}' AND \
                      smtp_auth='1'}{$value}fail}}} \
                       } {yes}{no}}"
 server_set_id = $1

fixed_plain:
 driver = plaintext
 public_name = PLAIN
 server_prompts = :
 server_condition = "${if and { \
                      {!eq{$2}{}} \
                      {!eq{$3}{}} \
                      {crypteq{$3}{\\{crypt\\}${lookup mysql{SELECT \
                      password FROM users \
                      WHERE login='${local_part:$2}' \
                      AND domain='${domain:$2}' AND \
                      smtp_auth='1'}{$value}fail}}} \
                      } {yes}{no}}"
 server_set_id = $2

# End of Exim configuration file.

С конфигурационным файлом, кажется, разобрались. Следующий шаг - создание БД,  пользователя этой БД и наполнение БД данными.

Создадим пользователя MySQL и базу данных:

mysql> create database exim;
Query OK, 1 row affected (0.00 sec)

mysql> grant all on exim.* to 'exim'@'localhost' identified by 'MySQL-pass-here';
Query OK, 1 row affected (0.00 sec)

Скачиваем дамп базы данных и "заливаем" его в БД:

# fetch http://muff.kiev.ua/files/exim.sql
# mysql -u exim -pMySQL-pass-here exim < exim.sql

Структура БД у нас есть. Теперь пора "заполнить" ее необходимыми данными. По очереди внесу по одной записи в каждую из таблиц.

mysql> use exim;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
 

mysql> INSERT INTO `exim`.`aliases` (`local_part`, `domain`, `recipients`)
    -> VALUES ('root', 'ispalternativa.net.ua', 'muff [at] ispalternativa [dot] net [dot] ua');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `exim`.`blacklist` (`senders`, `when_added`)
    -> VALUES ('elenafrits [at] km [dot] ru', CURDATE());
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `exim`.`blacklist_host` (`senders`, `when_added`)
    -> VALUES ('12.134.36.100', CURDATE());
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO `exim`.`domains` (`domain`, `type`)
    -> VALUES ('ispalternativa.net.ua', 'LOCAL');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `exim`.`users` (`login`, `name`, `password`, `uid`, `gid`, `domain`,
    -> `quota`, `status`, `smtp_auth`) VALUES ('muff', 'Oleg Zinkov. System administrator',
    -> ENCRYPT('password-here'), '26', '6', 'ispalternativa.net.ua', '150', '1', '1');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `exim`.`whitelist` (`senders`, `when_added`)
    -> VALUES ('do-not-reply [at] livejournal [dot] com', CURDATE());
Query OK, 1 row affected (0.00 sec)

Возьмемся за поддержку шифрования... Создадим самоподписной сертификат безопасности. Создадим каталог для сертификата и создадим сертификат, как таковой и немного обезопасим его:

# mkdir /etc/ssl/certs && cd /etc/ssl/certs
# openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/mail.pem -keyout /etc/ssl/certs/mail.pem

Generating a 1024 bit RSA private key
...........................................................................................++++++
....................++++++
writing new private key to '/etc/ssl/certs/mail.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:UA
State or Province Name (full name) [Some-State]:Kiev region.
Locality Name (eg, city) []:Kiev
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ISP Alternativa
Organizational Unit Name (eg, section) []:IT Department
Common Name (eg, YOUR name) []:mail.ispalternativa.net.ua
Email Address []:
noc [at] ispalternativa [dot] net [dot] ua

# chown mailnull:mail mail.pem
# chmod 440 mail.pem

Теперь пора создать каталог, где будет храниться почта. Ну и не нужно забывать о правах на каталог:

# mkdir /var/exim && chown mailnull:mail /var/exim

Также не стоит забывать о файле /etc/mail/mailer.conf. Отредактируем его до такого состояния:

sendmail        /usr/local/sbin/exim
send-mail       /usr/local/sbin/exim
mailq           /usr/local/sbin/exim -bp
newaliases      /usr/local/sbin/exim -bi
hoststat        /usr/local/sbin/exim
purgestat       /usr/local/sbin/exim

Зададим параметры запуска Exim. Кстати, не стоит забывать про необходимость останова штатного Sendmail перед запуском Exim.

# echo '# Mail Server' >> /etc/rc.conf
# echo 'sendmail_enable="NONE"' >> /etc/rc.conf
# echo 'exim_enable="YES"' >> /etc/rc.conf
# killall sendmail
# sh /usr/local/etc/rc.d/exim start

Если не напутать, то Exim должен корректно запуститься. После успешного запуска Exim-а в maillog-е можно обнаружить такую запись:

Aug  9 02:46:30 billing exim[93613]: exim 4.76 daemon started: pid=93613, -q30m, listening for SMTP on [127.0.0.1]:25 [91.221.84.10]:25 and for SMTPS on [127.0.0.1]:465 [91.221.84.10]:465

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

# telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.ispalternativa.net.ua ESMTP Exim
ehlo mail.ispalternativa.net.ua
250-mail.ispalternativa.net.ua Hello mail.ispalternativa.net.ua [127.0.0.1]
250-SIZE 20971520
250-PIPELINING
250-AUTH LOGIN PLAIN
250-STARTTLS
250 HELP
mail from: root [at] ispalternativa [dot] net [dot] ua
250 OK
rcpt to: muff [at] ispalternativa [dot] net [dot] ua
250 Accepted
data
354 Enter message, ending with "." on a line by itself
To: muff [at] ispalternativa [dot] net [dot] ua
From: root [at] ispalternativa [dot] net [dot] ua
Subject: TestMail
 
Hi!
This is a test message.
.
250 OK id=1QqZsP-000PQO-Se
quit
221 mail.ispalternativa.net.ua closing connection
Connection closed by foreign host.

Просмотрим в логах "судьбу" письма...

# cat /var/log/maillog | grep 1QqZsP-000PQO-Se
Aug  9 03:09:06 billing exim[97736]: 1QqZsP-000PQO-Se <= root [at] ispalternativa [dot] net [dot] ua H=(mail.ispalternativa.net.ua) [127.0.0.1] P=esmtp S=368 from <root [at] ispalternativa [dot] net [dot] ua> for muff [at] ispalternativa [dot] net [dot] ua
Aug  9 03:09:06 billing exim[97759]: 1QqZsP-000PQO-Se => muff <muff [at] ispalternativa [dot] net [dot] ua> R=virtual_localuser T=local_delivery
Aug  9 03:09:06 billing exim[97759]: 1QqZsP-000PQO-Se Completed

Кажется пора поздравлять себя с полноценным почтовым сервером. Следующий шаг - настройка Dovecot, чтобы пользователи смогли забрать почту с сервера.

А пока советую ознакомиться с этим инструментом, и определить все ли в порядке с SMTP-сервером. У меня оказалось все в порядке.

Ваша оценка: Нет Средняя: 4.1 (17 голосов)

Очень хорошая и полезная

Очень хорошая и полезная статья, в будущем пригодится. Автор - .

Спасибо... Сейчас работаю над

Спасибо...

Сейчас работаю над продолжением: статья о настройкеDovecot-а (почту ведь нужно как-то доставить абоненту). Решил детально прокомментировать конфигурационный файл... Уже офигеваю: два дня работы, а перевел только половину

Re: Exim - настройка почтового сервера на базе Exim с ...

Привет...

Подскажи как указать exim к адресу отправителя добавлять имя.

Например уходит письмо с test [at] test [dot] ru, надо чтоб отправка была вида Иван Иваныч <test [at] test [dot] ru>.. правило каснется всех отправляемых писем

Re: Exim - настройка почтового сервера на базе Exim с ...

Дык этим должна заниматься почтовая программа...

Re: Exim - настройка почтового сервера на базе Exim с ...

 Добрый день.
Подскажите пожалуйста как правильно настроить почтовый сервер чтобы в Roundcube в папке входящие письма сортировались по подпапкам (по домену или по адресу отправителя)

Re: Exim - настройка почтового сервера на базе Exim с ...

Здравствуйте.

Для сортировки писем непосредственно на стороне сервера, необходимо в Dovecot настроить managesieve. А в Exim доставку писем в ящики пользователей выполнять через dovecot deliver. А к Roundcube необходимо "прицепить" плагин managesieve, в котором можно будет задавать правила сортировки.

Re: Exim - настройка почтового сервера на базе Exim с ...

А не прикрусивали postfixadmin никто?

К него своя структура быза, я так понял нкжно либо в postfix запросы переписвать либо в exim. Может кто- уже делал, поделитемь решением.

Re: Exim - настройка почтового сервера на базе Exim с ...

<blockquote>Скачиваем дамп базы данных и "заливаем" его в БД</blockquote>

Где скачиваем-то?

Re: Exim - настройка почтового сервера на базе Exim с ...

Фраза заканчивается двоеточием. А дальше комманды на загрузку и импорт БД:

 

fetch http://muff.kiev.ua/files/exim.sql
mysql -u exim -pMySQL-pass-here exim < exim.sql

 

Re: Exim - настройка почтового сервера на базе Exim с ...

Это Вы публичным же ключом шифруете TLS?

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

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".

Вставай, Україно!

Литература