uscr 21.03.2011 17:19
How-to`s — Настраиваем релей почты с почтовика под exim'ом (exim smarthost).
Здравствуйте. Недавно я задавал вопрос, а теперь показываю вам развёрнутый ответ.Задача: есть много серверов на debian с exim'ом на борту, нужно со всех серваков релеить почту на main_server, который и будет эту почту доставлять адресату.
Сначала идём в статью (спасибо doit за подсказку). Делаем так, как в ней написано. Эта статья работает только если у вас debian, но под катом вы найдёте решение для других ОС. Но даже если у вас debian, у вас всё равно ничего не будет работать. Вам всё равно под кат. А если вы и так всё настроили, то всё равно зайдите - может быть полезным посмотреть бонусы.
Дабы не палить домены и адреса, я ввёл такие обозначения:
domain.ru - домен, в котором разворачивается действие пьессы.
main_ip - адрес сервера на который будем релеить.
ip - адрес сервера с которого будем релеить.
Все настройки сводятся к правке конфигов exim'а (К.О. у меня за плечом).
Для порядка нужно застопить exim:
1 |
|
Первым делом правим /etc/exim4/update-exim4.conf.conf (вот на это вам и нужно обратить внимание, не debian'щики). Приводим его к такому виду:
Теперь делаем update-exim4.config (да, да, прямо в консольке это пишем).
Следующим шагом правим /etc/exim4/exim4.conf.
Нам нужно:
поправить шапку конфига (описание доменов)поправить настройки aclсоздать новый роутер smarthostотредактировать описание транспорта remote_smtp
Правим шапку конфига:
приводим её к такому виду (тут стоит думать о том, что вы копипастите, тут таки нужны нужные вам настройки):
Правим секцию ACL:
добавляем запись, котрая разрешит релеить почту на другие хосты:
1 |
|
В разделе с описанием роутеров руками прописываем роутер smarthost и раскомментируем описание роутера dnslookup:
Правим транспорт remote_smtp прописываем interface равный ip (не main_ip):
1 |
|
Вот и всё. Запускаем exim
1 |
|
и всё работает.
Бонусы:
Подробное описание опций конфига на русском. Украдено из интернета, но не указываю источник потому, что непонятно кто изначальный автор:
CONFIG_PREFIX=/usr/local/etc/exim
ACL_PREFIX=CONFIG_PREFIX/acls
CERTDIR=CONFIG_PREFIX/certs
# Здесь мы указываем, где находить наш postgresql сервер, соединение
# осуществляется через локальный сокет, команда hide помогает спрятать эту
# настройку при вызове exim -bP, когда exim выводит все конфигурационные опции в
# стандартный вывод. Учтите,
# что сам /usr/local/etc/exim/configure должен иметь владельца root:wheel и
# иметь права доступа 0600, что отличается от того, что принято по умолчанию
# (0644)
hide pgsql_servers = (тут коннектимся к базе postgre)
# Тут мы описываем списки доменов
# Local_domains включает домены, считающиеся локальными, то есть те домены, для
# которых exim делает локальную доставку, для остальных доменов почта
# доставляется по MX записям в DNS. Обратите внимание на дополнительные файлы
# ACL_PREFIX/localdomains и ACL_PREFIX/hostingdomains, в которых перечислены
# домены, разделенные переводом строки (то есть, по одному домену на каждую строку)
#domainlist local_domains = mxpost.tcn.ru : ACL_PREFIX/hostingdomains : ACL_PREFIX/localdomains
domainlist local_domains = mxpost.tcn.ru : mxpost : ACL_PREFIX/hostingdomains : ${lookup pgsql {select domainname from localdomains where domainname='$domain'}{$value}fail}
# Дополнительная настройка
#domainlist hosting_domains = ${lookup pgsql {select domainname from localdomains}{yes}{no}}
domainlist hosting_domains = ACL_PREFIX/hostingdomains
# Список хостов, почту на которые мы явно отвергаем
hostlist host_reject = ACL_PREFIX/hostreject
domainlist relay_to_domains =
# Список адресов, с которых разрешена передача почты во внешний мир
hostlist relay_from_hosts = localhost : mxpost.tcn.ru : ACL_PREFIX/relayfromhosts
# Проверка получателя
acl_smtp_rcpt = acl_check_rcpt
# Проверка mime содержимого
acl_smtp_mime = acl_check_mime
# Проверка на спам и вирусы
acl_smtp_data = acl_check_virus
# Здесь мы описываем наш антивирус
av_scanner = clamd:127.0.0.1 3310
# И spamassasin
spamd_address = 127.0.0.1 783
# Настройки пользователя и группы по умолчанию
exim_user = mailnull
exim_group = mail
# Никогда не осуществляем доставку под рутом - root должен быть алиасом на
# другого локального пользователя. Кстати, это _обязательное_ условие, заданное
# еще на этапе компиляции
never_users = root
# Настройки директории для очереди
spool_directory = /var/spool/exim
# Разделяем spool_directory на несколько более маленьких - аналог хеш таблицы,
# ускоряет обработку spool'а
split_spool_directory
# Пытаемся сделать соответствие прямой и обратной зоны dns для каждого хоста.
# Несколько затратно, но весьма полезно
host_lookup = *
# Убираем проверку identd на клиентской стороне. Из-за неправильно настроенных
# firewall'ов это часто вызывает длительные тайм-ауты, кроме того, этот сервис
# поднят не у многих
rfc1413_query_timeout = 0s
# Указываем кое-какие лимиты (их назначение ясно из названия)
smtp_accept_max = 50
smtp_connect_backlog = 40
smtp_accept_max_per_host = 10
smtp_accept_queue = 22
smtp_accept_queue_per_connection = 10
recipients_max = 16
recipients_max_reject = true
message_size_limit = 16M
accept_8bitmime
# Игнорируем сообщения, которые приходят нам же, давность которых более 12-ти часов
ignore_bounce_errors_after = 12h
# Удаляем замороженные сообщения, давность которых больше недели.
timeout_frozen_after = 7d
# Настройки TLS
tls_certificate = CERTDIR/mailed.crt
tls_privatekey = CERTDIR/mailed.key
tls_advertise_hosts = *
tls_verify_certificates = *
# Следующая опция закомментирована, но весьма полезна, позволяя авторизироваться
# только через безопасный ssl канал
auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
######################################################################
# ACL CONFIGURATION #
# Specifies access control lists for incoming SMTP mail #
######################################################################
begin acl
# Этот список доступа описывает проверки, осуществляемые при вызове любой RCPT
# команды
acl_check_rcpt:
# Вначале проверяем достоверность отправителя
require verify = sender
# Принимаем соединения от локальных MUA (то есть не через TCP/IP)
accept hosts = :
#############################################################################
# Проверка соответствия почтового адреса стандарту
deny message = Access denied - $sender_host_address listed by $dnslist_domain\n$dnslist_text
dnslists = dnsbl.sorbs.net
deny message = message from $sender_host_address rejected - see http://njabl.org/
dnslists = dnsbl.njabl.org
deny message = rejected because $sender_host_address for bad WHOIS info, see http://www.rfc-ignorant.org/
dnslists = ipwhois.rfc-ignorant.org
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = dialups.mail-abuse.org
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = list.dsbl.org
deny message = Spam blocked see: http://www.spamcop.net/w3m?action=checkblock&ip;=$sender_host_address
dnslists = bl.spamcop.net
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = relays.ordb.org
deny message = rejected, $sender_host_address Open Proxy, see: $dnslist_domain\n$dnslist_text
dnslists = dnsbl.void.ru
# deny message = Restricted characters in address
# domains = +local_domains
# local_parts = ^<.> : ^.*<@%!/|>
accept domains = +local_domains
# Здесь прописаны так называемые dnsbl, то есть черные списки MTA с открытым
# релеем, мы проверяем ip адрес отправителя на соответствие таким спискам и
# блокируем письмо, если отправитель был найден в таком списке
deny message = host is listed in $dnslist_domain
dnslists = blackholes.mail-abuse.org:relays.mail-abuse.org
# Правило на проверку всех почтовых адресов, кроме локальных (менее строгое)
deny message = Restricted characters in address
domains = !+local_domains
local_parts = ^<./|> : ^.*<@%!> : ^.*/\\.\\./
#############################################################################
# Принимаем почту для пользователя postmaster локальных доменов, не взирая на
# отправителя
accept local_parts = postmaster
domains = +local_domains
# Deny unless the sender address can be verified.
accept domains = +local_domains
endpass
verify = recipient
# Если домен в списке relay_to_domains, то разрешаем релей
accept domains = +relay_to_domains
endpass
verify = recipient
accept domains = +hosting_domains
endpass
verify = recipient
accept hosts = +relay_from_hosts
# Принимаем любые соединения, которые были успешно авторизованы
accept authenticated = *
# Реализация нашего бан-листа
deny hosts = +host_reject
message = You are banned. Go away.
# Запрещаем все, что не разрешено, закрывая тем самым релей для спамеров
deny message = relay not permitted
# Список доступа для проверки mime частей сообщения
acl_check_mime:
# Произодим декодирование mime сообщений. Полезно для дальнейшей проверки на
# вирусы
warn decode = default
# Можно очень быстро отсеять сообщения, просто запретив некоторые mime
# вложения, чаще всего содержащие вирусы, хотя, конечно, это не панацея
deny message = Blacklisted file extension detected
condition = ${if match \
{${lc:$mime_filename}} \
{\N(\.wav|\.cpl|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} \
{1}{0}}
# Много ли у нас людей, знающих китайский? А вот китайского спама это поубавит
# :-)
deny message = Sorry, noone speaks chinese here
condition = ${if eq{$mime_charset}{gb2312}{1}{0}}
accept
# Проверка содержимого на вирусы и спам
acl_check_virus:
# Мы не запрещаем письма со спамом, а просто добавляем заголовок,
# содержащий количество спамерских очков, а пользователь на своей
# стороне уже просто настраивает свои фильтры. Так мы исключаем жалобы
# со стороны пользователей о потерянных письмах
# warn message = X-Spam-Score: $spam_score ($spam_bar)
# spam = spamd:true
#
# Добавляем заголовки, указывающие, что письма были проверены
# spamasssasin'ом
# warn message = X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on post.tcn.ru
# warn message = X-Spam-Scanned: Yes
# warn message = X-Spam-Scanner: SpamAssassin running on MXpost.tcn.ru
warn message = X-Spam-Score: $spam_score ($spam_bar)
hosts = !+relay_from_hosts
spam = spamd:true
warn message = X-Spam-Report: $spam_report
hosts = !+relay_from_hosts
spam = spamd:true
# warn message = Subject: ***SPAM*** $h_Subject:
# hosts = !+relay_from_hosts
# spam = spamd
warn message = X-Spam-Status: Yes
hosts = !+relay_from_hosts
spam = spamd
deny message = This message scored $spam_score spam points.
spam = spamd:true
hosts = !+relay_from_hosts
condition = ${if >{$spam_score_int}{120}{1}{0}}
# Вот что-что, а вирусы нам не нужны.
deny message = Message rejected: virus found. Your message was successfully trashed.
hosts = *
malware = *
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
# Роутер, осуществляющий поиск по MX записям в DNS
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more
# Все останльные роутеры обслуживают доставку локальной почты
# Драйвер алиасов пользователя. Обратите внимание на lookup в pgsql базе. Что
# интересно, этот lookup работает даже для иерархических алиасов, например,
# postmaster -> root -> cebka -> [email protected] Также определяются транспорты
# для передачи почты в файл (>/path/to/file) и в pipe
# (|/usr/local/libexec/slocal)
system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup pgsql{select alias from aliases where mail ='$local_part@$domain'}{$value}fail}
user = mailnull
group = mail
file_transport = address_file
pipe_transport = address_pipe
# Для локальных пользователей также создаем возможность перенаправления почты
# через ~/.forward файл. Если включена директива allow_filter, то в .forward
# файле можно использовать язык sieve фильтров. Для подробностей см.
# документацию на www.exim.org, т.к. на рассмотрение этой темы уйдет слишком
# много времени
userforward:
driver = redirect
check_local_user
file = $home/.forward
no_verify
no_expn
check_ancestor
# allow_filter
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
condition = ${if exists{$home/.forward} {yes} {no} }
# Локальная доставка, если данный пользователь найдем в базе
localuser:
driver = accept
condition = ${lookup pgsql {select 150 as uid from accounts where login = '$local_part' and domain='$domain'}{yes}{no}}
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
# Драйвер для доставки через соединения с удаленными smtp серверами
remote_smtp:
driver = smtp
# Этот транспорт доставляет почту в локальные maildir'ы. Путь к maildir хранится
# опять же в таблице accounts. Разрешения на директорию 0700 для возможности
# работы с данными директориями imap сервера. При этом владельцем является
# группа и пользователь из accounts (потому при вставлении записей в эту таблицу
# надо начинать значения uid с достаточно большого числа, например, 2000 и
# пересекаться с реальными пользователями оно должно только если реальному
# пользователю нужен локальный доступ к maildir'у).
# Также из таблицы accounts извлекается данные о размере квоты, и
# устанавливается порог в 75% от квоты, когда пользователю посылается указанное
# предупреждение об подходе к порогу квоты
local_delivery:
driver = appendfile
# directory = ${lookup pgsql{select maildir from accounts where login = '$local_part@$domain'}{$value}fail}
directory = ${lookup pgsql{select '/usr/local/mailusers/'||c.domain||'/'||substring(c.login from 1 for 1)||'/'||c.login as maildir from accounts as c where login = '$local_part' and domain='$domain'}{$value}fail}
create_directory
directory_mode = 0770
maildir_format
delivery_date_add
envelope_to_add
return_path_add
group = ${lookup pgsql{select 150 as gid from accounts where login = '$local_part' and domain='$domain'}{$value}fail}
user = ${lookup pgsql{select 150 as uid from accounts where login = '$local_part' and domain='$domain'}{$value}fail}
mode = 0660
no_mode_fail_narrower
quota = ${lookup pgsql{select mailquota from accounts where login = '$local_part' and domain='$domain'}{$value}fail}M
quota_warn_message = "\
To: $local_part@domain\n\
From: [email protected]\n\
Subject: Your maildir is going full\n\
This message is automaticaly gnerated by your mail server.\n\
This means, that your mailbox is 75% full. If you would \n\
override this limit new mail would not be delivered to you!\n"
quota_warn_threshold = 75%
# Транспорт, осуществляющий доставку в pipe
address_pipe:
driver = pipe
return_output
# Транспорт, осуществляющий доставку прямо в файл
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
# Этот транспорт используется для автоматического ответа на сообщения об ошибках
address_reply:
driver = autoreply
######################################################################
# RETRY CONFIGURATION #
######################################################################
begin retry
# Настройки по умолчанию, которые я не трогал, управляют интервала повторной
# передачи сообщений
# This single retry rule applies to all domains and all errors. It specifies
# retries every 15 minutes for 2 hours, then increasing retry intervals,
# starting at 1 hour and increasing each time by a factor of 1.5, up to 16
# hours, then retries every 6 hours until 4 days have passed since the first
# failed delivery.
# Address or Domain Error Retries
# ----------------- ----- -------
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
######################################################################
# REWRITE CONFIGURATION #
######################################################################
begin rewrite
# Создаем правило, по переписыванию заголовка To: с *@test.ru на локальный
# smart-host - @unona.test.ru. Это было сделано для локальных пользователей,
# по идее с хранением пользователей в postgres, уже не нужно, показано для
# примера.
*@test.ru [email protected] T
######################################################################
# AUTHENTICATION CONFIGURATION #
######################################################################
# Описания аутентификации
begin authenticators
# CRAM-MD5 аутентификация, требует наличия пароля в открытом виде, имя
# пользователя должно быть в формате user@domain, как оно хранится в таблице
# accounts
lookup_cram:
driver = cram_md5
public_name = CRAM-MD5
server_secret = ${lookup pgsql {select password from accounts where login||'@'||domain='$1'}{$value}fail}
server_set_id = $1
# LOGIN аутентификация - не требует хранения пароля в открытом виде, однако, по
# сети пароль передается в открытом виде - требуется лишь выполнение условия
# server_condition - $1 - имя пользователя, а $2 - пароль. LOGIN безопасен
# только при установлении ssl соединения.
login:
driver = plaintext
public_name = LOGIN
server_prompts = Username:: : Password::
server_condition = ${lookup pgsql {select login from accounts where login||'@'||domain='$1' and password='$2'}{yes}{no}}
server_set_id = $1
######################################################################
# CONFIGURATION FOR local_scan() #
######################################################################
# If you have built Exim to include a local_scan() function that contains
# tables for private options, you can define those options here. Remember to
# uncomment the "begin" line. It is commented by default because it provokes
# an error with Exim binaries that are not built with LOCAL_SCAN_HAS_OPTIONS
# set in the Local/Makefile.
# begin local_scan
# End of Exim configuration file
ACL_PREFIX=CONFIG_PREFIX/acls
CERTDIR=CONFIG_PREFIX/certs
# Здесь мы указываем, где находить наш postgresql сервер, соединение
# осуществляется через локальный сокет, команда hide помогает спрятать эту
# настройку при вызове exim -bP, когда exim выводит все конфигурационные опции в
# стандартный вывод. Учтите,
# что сам /usr/local/etc/exim/configure должен иметь владельца root:wheel и
# иметь права доступа 0600, что отличается от того, что принято по умолчанию
# (0644)
hide pgsql_servers = (тут коннектимся к базе postgre)
# Тут мы описываем списки доменов
# Local_domains включает домены, считающиеся локальными, то есть те домены, для
# которых exim делает локальную доставку, для остальных доменов почта
# доставляется по MX записям в DNS. Обратите внимание на дополнительные файлы
# ACL_PREFIX/localdomains и ACL_PREFIX/hostingdomains, в которых перечислены
# домены, разделенные переводом строки (то есть, по одному домену на каждую строку)
#domainlist local_domains = mxpost.tcn.ru : ACL_PREFIX/hostingdomains : ACL_PREFIX/localdomains
domainlist local_domains = mxpost.tcn.ru : mxpost : ACL_PREFIX/hostingdomains : ${lookup pgsql {select domainname from localdomains where domainname='$domain'}{$value}fail}
# Дополнительная настройка
#domainlist hosting_domains = ${lookup pgsql {select domainname from localdomains}{yes}{no}}
domainlist hosting_domains = ACL_PREFIX/hostingdomains
# Список хостов, почту на которые мы явно отвергаем
hostlist host_reject = ACL_PREFIX/hostreject
domainlist relay_to_domains =
# Список адресов, с которых разрешена передача почты во внешний мир
hostlist relay_from_hosts = localhost : mxpost.tcn.ru : ACL_PREFIX/relayfromhosts
# Проверка получателя
acl_smtp_rcpt = acl_check_rcpt
# Проверка mime содержимого
acl_smtp_mime = acl_check_mime
# Проверка на спам и вирусы
acl_smtp_data = acl_check_virus
# Здесь мы описываем наш антивирус
av_scanner = clamd:127.0.0.1 3310
# И spamassasin
spamd_address = 127.0.0.1 783
# Настройки пользователя и группы по умолчанию
exim_user = mailnull
exim_group = mail
# Никогда не осуществляем доставку под рутом - root должен быть алиасом на
# другого локального пользователя. Кстати, это _обязательное_ условие, заданное
# еще на этапе компиляции
never_users = root
# Настройки директории для очереди
spool_directory = /var/spool/exim
# Разделяем spool_directory на несколько более маленьких - аналог хеш таблицы,
# ускоряет обработку spool'а
split_spool_directory
# Пытаемся сделать соответствие прямой и обратной зоны dns для каждого хоста.
# Несколько затратно, но весьма полезно
host_lookup = *
# Убираем проверку identd на клиентской стороне. Из-за неправильно настроенных
# firewall'ов это часто вызывает длительные тайм-ауты, кроме того, этот сервис
# поднят не у многих
rfc1413_query_timeout = 0s
# Указываем кое-какие лимиты (их назначение ясно из названия)
smtp_accept_max = 50
smtp_connect_backlog = 40
smtp_accept_max_per_host = 10
smtp_accept_queue = 22
smtp_accept_queue_per_connection = 10
recipients_max = 16
recipients_max_reject = true
message_size_limit = 16M
accept_8bitmime
# Игнорируем сообщения, которые приходят нам же, давность которых более 12-ти часов
ignore_bounce_errors_after = 12h
# Удаляем замороженные сообщения, давность которых больше недели.
timeout_frozen_after = 7d
# Настройки TLS
tls_certificate = CERTDIR/mailed.crt
tls_privatekey = CERTDIR/mailed.key
tls_advertise_hosts = *
tls_verify_certificates = *
# Следующая опция закомментирована, но весьма полезна, позволяя авторизироваться
# только через безопасный ssl канал
auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
######################################################################
# ACL CONFIGURATION #
# Specifies access control lists for incoming SMTP mail #
######################################################################
begin acl
# Этот список доступа описывает проверки, осуществляемые при вызове любой RCPT
# команды
acl_check_rcpt:
# Вначале проверяем достоверность отправителя
require verify = sender
# Принимаем соединения от локальных MUA (то есть не через TCP/IP)
accept hosts = :
#############################################################################
# Проверка соответствия почтового адреса стандарту
deny message = Access denied - $sender_host_address listed by $dnslist_domain\n$dnslist_text
dnslists = dnsbl.sorbs.net
deny message = message from $sender_host_address rejected - see http://njabl.org/
dnslists = dnsbl.njabl.org
deny message = rejected because $sender_host_address for bad WHOIS info, see http://www.rfc-ignorant.org/
dnslists = ipwhois.rfc-ignorant.org
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = dialups.mail-abuse.org
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = list.dsbl.org
deny message = Spam blocked see: http://www.spamcop.net/w3m?action=checkblock&ip;=$sender_host_address
dnslists = bl.spamcop.net
deny message = rejected because $sender_host_address is in a black list at $dnslist_domain\n$dnslist_text
dnslists = relays.ordb.org
deny message = rejected, $sender_host_address Open Proxy, see: $dnslist_domain\n$dnslist_text
dnslists = dnsbl.void.ru
# deny message = Restricted characters in address
# domains = +local_domains
# local_parts = ^<.> : ^.*<@%!/|>
accept domains = +local_domains
# Здесь прописаны так называемые dnsbl, то есть черные списки MTA с открытым
# релеем, мы проверяем ip адрес отправителя на соответствие таким спискам и
# блокируем письмо, если отправитель был найден в таком списке
deny message = host is listed in $dnslist_domain
dnslists = blackholes.mail-abuse.org:relays.mail-abuse.org
# Правило на проверку всех почтовых адресов, кроме локальных (менее строгое)
deny message = Restricted characters in address
domains = !+local_domains
local_parts = ^<./|> : ^.*<@%!> : ^.*/\\.\\./
#############################################################################
# Принимаем почту для пользователя postmaster локальных доменов, не взирая на
# отправителя
accept local_parts = postmaster
domains = +local_domains
# Deny unless the sender address can be verified.
accept domains = +local_domains
endpass
verify = recipient
# Если домен в списке relay_to_domains, то разрешаем релей
accept domains = +relay_to_domains
endpass
verify = recipient
accept domains = +hosting_domains
endpass
verify = recipient
accept hosts = +relay_from_hosts
# Принимаем любые соединения, которые были успешно авторизованы
accept authenticated = *
# Реализация нашего бан-листа
deny hosts = +host_reject
message = You are banned. Go away.
# Запрещаем все, что не разрешено, закрывая тем самым релей для спамеров
deny message = relay not permitted
# Список доступа для проверки mime частей сообщения
acl_check_mime:
# Произодим декодирование mime сообщений. Полезно для дальнейшей проверки на
# вирусы
warn decode = default
# Можно очень быстро отсеять сообщения, просто запретив некоторые mime
# вложения, чаще всего содержащие вирусы, хотя, конечно, это не панацея
deny message = Blacklisted file extension detected
condition = ${if match \
{${lc:$mime_filename}} \
{\N(\.wav|\.cpl|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} \
{1}{0}}
# Много ли у нас людей, знающих китайский? А вот китайского спама это поубавит
# :-)
deny message = Sorry, noone speaks chinese here
condition = ${if eq{$mime_charset}{gb2312}{1}{0}}
accept
# Проверка содержимого на вирусы и спам
acl_check_virus:
# Мы не запрещаем письма со спамом, а просто добавляем заголовок,
# содержащий количество спамерских очков, а пользователь на своей
# стороне уже просто настраивает свои фильтры. Так мы исключаем жалобы
# со стороны пользователей о потерянных письмах
# warn message = X-Spam-Score: $spam_score ($spam_bar)
# spam = spamd:true
#
# Добавляем заголовки, указывающие, что письма были проверены
# spamasssasin'ом
# warn message = X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on post.tcn.ru
# warn message = X-Spam-Scanned: Yes
# warn message = X-Spam-Scanner: SpamAssassin running on MXpost.tcn.ru
warn message = X-Spam-Score: $spam_score ($spam_bar)
hosts = !+relay_from_hosts
spam = spamd:true
warn message = X-Spam-Report: $spam_report
hosts = !+relay_from_hosts
spam = spamd:true
# warn message = Subject: ***SPAM*** $h_Subject:
# hosts = !+relay_from_hosts
# spam = spamd
warn message = X-Spam-Status: Yes
hosts = !+relay_from_hosts
spam = spamd
deny message = This message scored $spam_score spam points.
spam = spamd:true
hosts = !+relay_from_hosts
condition = ${if >{$spam_score_int}{120}{1}{0}}
# Вот что-что, а вирусы нам не нужны.
deny message = Message rejected: virus found. Your message was successfully trashed.
hosts = *
malware = *
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
# Роутер, осуществляющий поиск по MX записям в DNS
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more
# Все останльные роутеры обслуживают доставку локальной почты
# Драйвер алиасов пользователя. Обратите внимание на lookup в pgsql базе. Что
# интересно, этот lookup работает даже для иерархических алиасов, например,
# postmaster -> root -> cebka -> [email protected] Также определяются транспорты
# для передачи почты в файл (>/path/to/file) и в pipe
# (|/usr/local/libexec/slocal)
system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup pgsql{select alias from aliases where mail ='$local_part@$domain'}{$value}fail}
user = mailnull
group = mail
file_transport = address_file
pipe_transport = address_pipe
# Для локальных пользователей также создаем возможность перенаправления почты
# через ~/.forward файл. Если включена директива allow_filter, то в .forward
# файле можно использовать язык sieve фильтров. Для подробностей см.
# документацию на www.exim.org, т.к. на рассмотрение этой темы уйдет слишком
# много времени
userforward:
driver = redirect
check_local_user
file = $home/.forward
no_verify
no_expn
check_ancestor
# allow_filter
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
condition = ${if exists{$home/.forward} {yes} {no} }
# Локальная доставка, если данный пользователь найдем в базе
localuser:
driver = accept
condition = ${lookup pgsql {select 150 as uid from accounts where login = '$local_part' and domain='$domain'}{yes}{no}}
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
# Драйвер для доставки через соединения с удаленными smtp серверами
remote_smtp:
driver = smtp
# Этот транспорт доставляет почту в локальные maildir'ы. Путь к maildir хранится
# опять же в таблице accounts. Разрешения на директорию 0700 для возможности
# работы с данными директориями imap сервера. При этом владельцем является
# группа и пользователь из accounts (потому при вставлении записей в эту таблицу
# надо начинать значения uid с достаточно большого числа, например, 2000 и
# пересекаться с реальными пользователями оно должно только если реальному
# пользователю нужен локальный доступ к maildir'у).
# Также из таблицы accounts извлекается данные о размере квоты, и
# устанавливается порог в 75% от квоты, когда пользователю посылается указанное
# предупреждение об подходе к порогу квоты
local_delivery:
driver = appendfile
# directory = ${lookup pgsql{select maildir from accounts where login = '$local_part@$domain'}{$value}fail}
directory = ${lookup pgsql{select '/usr/local/mailusers/'||c.domain||'/'||substring(c.login from 1 for 1)||'/'||c.login as maildir from accounts as c where login = '$local_part' and domain='$domain'}{$value}fail}
create_directory
directory_mode = 0770
maildir_format
delivery_date_add
envelope_to_add
return_path_add
group = ${lookup pgsql{select 150 as gid from accounts where login = '$local_part' and domain='$domain'}{$value}fail}
user = ${lookup pgsql{select 150 as uid from accounts where login = '$local_part' and domain='$domain'}{$value}fail}
mode = 0660
no_mode_fail_narrower
quota = ${lookup pgsql{select mailquota from accounts where login = '$local_part' and domain='$domain'}{$value}fail}M
quota_warn_message = "\
To: $local_part@domain\n\
From: [email protected]\n\
Subject: Your maildir is going full\n\
This message is automaticaly gnerated by your mail server.\n\
This means, that your mailbox is 75% full. If you would \n\
override this limit new mail would not be delivered to you!\n"
quota_warn_threshold = 75%
# Транспорт, осуществляющий доставку в pipe
address_pipe:
driver = pipe
return_output
# Транспорт, осуществляющий доставку прямо в файл
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
# Этот транспорт используется для автоматического ответа на сообщения об ошибках
address_reply:
driver = autoreply
######################################################################
# RETRY CONFIGURATION #
######################################################################
begin retry
# Настройки по умолчанию, которые я не трогал, управляют интервала повторной
# передачи сообщений
# This single retry rule applies to all domains and all errors. It specifies
# retries every 15 minutes for 2 hours, then increasing retry intervals,
# starting at 1 hour and increasing each time by a factor of 1.5, up to 16
# hours, then retries every 6 hours until 4 days have passed since the first
# failed delivery.
# Address or Domain Error Retries
# ----------------- ----- -------
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
######################################################################
# REWRITE CONFIGURATION #
######################################################################
begin rewrite
# Создаем правило, по переписыванию заголовка To: с *@test.ru на локальный
# smart-host - @unona.test.ru. Это было сделано для локальных пользователей,
# по идее с хранением пользователей в postgres, уже не нужно, показано для
# примера.
*@test.ru [email protected] T
######################################################################
# AUTHENTICATION CONFIGURATION #
######################################################################
# Описания аутентификации
begin authenticators
# CRAM-MD5 аутентификация, требует наличия пароля в открытом виде, имя
# пользователя должно быть в формате user@domain, как оно хранится в таблице
# accounts
lookup_cram:
driver = cram_md5
public_name = CRAM-MD5
server_secret = ${lookup pgsql {select password from accounts where login||'@'||domain='$1'}{$value}fail}
server_set_id = $1
# LOGIN аутентификация - не требует хранения пароля в открытом виде, однако, по
# сети пароль передается в открытом виде - требуется лишь выполнение условия
# server_condition - $1 - имя пользователя, а $2 - пароль. LOGIN безопасен
# только при установлении ssl соединения.
login:
driver = plaintext
public_name = LOGIN
server_prompts = Username:: : Password::
server_condition = ${lookup pgsql {select login from accounts where login||'@'||domain='$1' and password='$2'}{yes}{no}}
server_set_id = $1
######################################################################
# CONFIGURATION FOR local_scan() #
######################################################################
# If you have built Exim to include a local_scan() function that contains
# tables for private options, you can define those options here. Remember to
# uncomment the "begin" line. It is commented by default because it provokes
# an error with Exim binaries that are not built with LOCAL_SCAN_HAS_OPTIONS
# set in the Local/Makefile.
# begin local_scan
# End of Exim configuration file
С большой долей вероятности вы можете получить в логах (кстати, лог живёт в /var/log/exim4/mainlog) ошибку такого вида:
1 |
2011-03-20 22:22:07 1Q1Nn8-0001wb-1o == user@some_domain.ru R=dnslookup T=remote_smtp defer (-53): retry time not reached for any host
|
Это лечится следующей магической командой:
1 |
|
Пособие по чтению логов exim'а:
http://caravan.ru/reference/faq/hosting/logs/

+ 1 -
Не за что =)
Да, извиняюсь.
Просто статью я видел и раньше, а предложенный способ проверки не информативен в данном случае.
Просто статью я видел и раньше, а предложенный способ проверки не информативен в данном случае.
Ах тыж! Всё таки поел ты моей еды! Почему ты просыпаешься только на мои посты?!
Просто так или это оказалось полезным?
На самом деле мне интересно, насколько это решение работоспособно для других конфигураций.
Блин, я не настолько крут, и пока для собственного домена не думал почту устраивать, но мне нравится, когда на ресурсе появляется полезный пост. (Я КО =)
Первым делом правим /etc/exim4/update-exim4.conf.conf (вот на это вам и нужно обратить внимание, не debian'щики).
ЕМНИП этот файлик есть только в Debian и производных.