Дек 17 2008

Установка и настройка Exim+ClamAv+DSpam+белый список отправителей(whitelist)

Exim — почтовый сервер, один из самых популярных на сегодняшний день. На основе его, построен прием почты таких известных систем, как ukr.net, mail.ru. Всю массу возможностей я описывать не буду, попытаюсь объяснить как настроить систему с антиспам фильтром (DSPAM) и антивирусом(ClamAV).
Начнем с установки Exim. В портах FreeBSD exim представлен в 6 вариантах:
/usr/ports/mail/exim/ — обычная сборка
/usr/ports/mail/exim-mysql/ — добавлена возможность обращаться к базе данных MySQL
/usr/ports/mail/exim-postgresql/ — добавлена возможность обращаться к PostgreSQL
/usr/ports/mail/exim-sqlite/ — добавлена возможность обращаться к SQLite
/usr/ports/mail/exim-sa-exim/ — exim c патчем SA-Exim, специальный патч для работы со SpamAssassing на этапе SMTP диалога

Наиболее популярным является установка Exim c поддержкой MySQL, поддержка MySQL обеспечивает максимальную гибкость при управлении системой, но по моим наблюдениям отрицательно сказывается на производительности. В этой статье мы ограничимся установко «обычного» Exim.
Итак приступим к установке Exim:

cd /usr/ports/mail/exim/
make install clean

Установка происходит без дополнительных вопросов. По окончании установки перейдем к установке ClamAV. На ней я останавливался подробно в статье Установка ClamAv.
Если кратко — то установка производится из:

cd /usr/ports/security/clamav
make install clean

По окончании установки ClamAv, необходимо прописать разрешение на его запуск в /etc/rc.conf:

clamav_freshclam_enable="YES"
clamav_clamd_enable="YES"

и соответсвенно запустить:

/usr/local/etc/rc.d/clamav-freshclam start
/usr/local/etc/rc.d/clamav-clamd start

Возня с ClamAv закончена, в настройке он не нуждается, переходим к DSpam.

cd /usr/ports/mail/dspam/
make install clean

Сборке предшевствует просто гигантский конфигурационный диалог. Я чтобы не загромождать статью, опишу только те пункты, которые я выбираю при сборке:
1. Logs via syslog
2. Enable debugging logging
3. Daemonize dspam; speaks LMTP or DLMTP
4. Use hash driver
5. Use Exim as local delivery agent

Я не люблю использовать без крайней нужды всякие навороты типа SQL, поэтому в настройках сборки DSpam вы так же не найдете пунктов связанных с MySQL или PostgreSQL. Ну не люблю я плодить сущности.

Теперь перейдем к настройке DSpam, файл настроек /usr/local/etc/dspam.conf имеет такой вид:

#Директория для хранения информации DSpam
Home /var/db/dspam
#Драйвер hash определяет формат в котором будет храниться информация DSpam
StorageDriver /usr/local/lib/libhash_drv.so
#Метод которым будет доставляться почта
TrustedDeliveryAgent "/usr/local/sbin/exim -oMr spam-scanned"
#Возвращать ошибку при неудачной доставке
OnFail error
#Описываем доверенных пользователей. Внятного описания этой настройки не нашел, но присутствует #в любой документации по DSpam
Trust root
Trust mail
Trust mailnull 
Trust smmsp
Trust daemon
#Отладка всего-всего
Debug *
DebugOpt process classify spam fp inoculation corpus
#Режим обучения
TrainingMode teft
TestConditionalTraining on
Feature noise
Feature chained
#автоматический whitelist, как показала практика - его для руководства мало, поэтому я реализую #исключение отправителей из проверки на спам средствами Exim
Feature whitelist
#Алгоритм проверки на spam
Algorithm graham burton
PValue graham
#При обнаружениии что это spam - помещаем в карантин
Preference "spamAction=quarantine"
#сигнатуру проверки внутрь сообщения
Preference "signatureLocation=message" 
#Указывать какой фактор принес сколько очков вероятности спама 
Preference "showFactors=on"
Preference "spamAction=tag"
Preference "spamSubject=SPAM"
#Включаем режим обучения спаму
AllowOverride trainingMode
AllowOverride spamAction spamSubject
AllowOverride statisticalSedation
AllowOverride enableBNR
AllowOverride enableWhitelist
AllowOverride signatureLocation
AllowOverride showFactors
AllowOverride optIn optOut
AllowOverride whitelistThreshold
HashRecMax              98317
HashAutoExtend          on  
HashMaxExtents          0
HashExtentSize          49157
HashMaxSeek             100
HashConnectionCache     100

Карантин DSpam будет находиться в /var/db/dspam/data/, для каждого пользователя будет создан свой каталог в котором будет лежать карантинный mailbox и другая нужная DSpam информация.
Главные настройки DSpam мы описали, теперь надо создать файл /var/db/dspam/group, в нем будет описано где будут лежать базы сигнатур спама. В файле разместим такое:

system:shared:*

Добавим разрешение на старт DSpam:

echo "dspam_enable=YES" >> /etc/rc.conf

И запустим его:

/usr/local/etc/rc.d/dspam start

И теперь можно переходить к самому главному, к настройке Exim. Основной файл настройки Exim /usr/local/etc/exim/configure:

#основное имя хоста - будет присутствовать во всех ответах сервера
primary_hostname = hilik.org.ua
#Список доменов для которых мы будем принимать почту
domainlist local_domains= @ : hilik.kiev.ua : sh.hilik.org.ua
#Список доменов для которых мы служим вторичным релаем
domainlist relay_to_domains = 
#IP адреса сетей от которых мы принимаем почту на пересылку
hostlist   relay_from_hosts = localhost : 192.168.0.0/24 
#IP адреса, для которых мы отключаем встречную проверку отправителя
hostlist notvrf = 192.168.0.3 
#ACL на обработку сообщений
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_content
#Указываем использовать ClamAv
av_scanner = clamd:/var/run/clamav/clamd
#Пользователь и группа от которых работает Exim
exim_user = mailnull
exim_group = mail
#Запрос на ident
rfc1413_hosts = *
rfc1413_query_timeout = 0s
#Игнорировать боунс сообщения(отлупы) старше 2 дней
ignore_bounce_errors_after = 2d
timeout_frozen_after = 7d
#Для увеличения производительности включаем разбивку спула на подкаталоги
split_spool_directory
#Включаем поддержку 8 битных майм 
accept_8bitmime = yes
#Разрешаем работу с хостами у которых МХ прописан ip адресом
allow_mx_to_ip = yes
#отключаем проверку синхронности SMTP диалога
smtp_enforce_sync=false
#Увеличим видимую фильтрам часть, тела сообщения
message_body_visible = 6144
envelope_to_remove = no
######################################################################
#                       ACL CONFIGURATION                            #
#         Specifies access control lists for incoming SMTP mail      #
######################################################################
#Списки контроля отвечают за проверку сообщения
begin acl
#Проверка на этапе RCPT TO: 
acl_check_rcpt:
  accept  hosts = :
  deny    message       = Restricted characters in address
          domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|]
  deny    message       = Restricted characters in address
          domains       = !+local_domains
          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
  deny    message       = Restricted sezam.cz
          condition     = ${if eq{$sender_address_domain}{sezam.cz}{1}{0}}
  accept  local_parts   = postmaster
          domains       = +local_domains
#Запрещаем прием сообщений содержащих файлы с расширением pif, bat, scr, lnk, com
  deny    message        = "Virus?"
          condition      = ${if match {${lc:$mime_filename}} \
                           {\N(\.\.\.|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} {1}{0}}
#Не принимаем почту от тех кто не использует HELO
  deny    message       = "HELO/EHLO need by SMTP RFC"
          condition     = ${if eq {$sender_helo_name}{} {yes}}
          log_message   = Bad HELO: HELO Bad
#Не принимаем почту от всяких DSLщиков и динамических пулов
  deny    message       = "Bad host, use SMTP"
          condition     = ${if match{$sender_host_name} \
                               {dsl-|adsl|dynamic|\.hsd1\.|dialup|pool|peer|dhcp|user.veloxzone.com.br|\
                                ssrv\.cl|msmartin.com.pe|\.cablep\.|dial-up|\.dsl\.|fbx.proxad|hsd1.in|-ras1|cpe-|\
                                broadway.dreamhost|\.cable\.|dip..t-ipconnect} \
                               {yes}{no}}
#Не принимаю почту от wanadoo.fr, просто задолбали спамом
          deny    message       = "We do not take mail from provider of wanadoo.fr"
          condition     = ${if match{$sender_host_name} \
                               {\.wanadoo.fr|\
                                abo.wanadoo} \
                               {yes}{no}}
#Не принимаем почту от тех кто в helo ставит адрес моего интерфейса
  deny    condition     = ${if eq{$sender_helo_name}{$interface_address}{yes}{no}}
          hosts         = !127.0.0.1 : !localhost : *
          message       = "SPAM!"
 
  # Рубаем тех, кто подставляет свой IP в HELO
  deny    message       = "This is SPAM!"
          # все хосты кроме тех, что в relay_from_hosts
          hosts         =  * : !+relay_from_hosts
          condition     = ${if eq{$sender_helo_name}{$sender_host_address} \
                          {true}{false}}
 
#Встречная проверка наличия адреса отправителя, исключая хосты, перечисленные в notvrf
   deny  hosts   = !+notvrf
        !verify = sender/callout=90s
#Принмаем почту к доменам описанным в local_domains
  accept  domains       = +local_domains
          endpass
          verify        = recipient
#Принимаем почту на пересылку к доменам описанным в relay_to_domains
  accept  domains       = +relay_to_domains
          endpass
          verify        = recipient
#Принимаем почту на пересылку от ip адресов описанных в  relay_from_hosts
  accept  hosts         = +relay_from_hosts
#Всем остальным отказываем в пересылке 
  deny    message       = relay not permitted
 
#Контрол лист на проверку содержимого письма этап DATA
acl_check_content:
#Если ответ антивируса содержит имя вируса - письмо не принимаем
  deny  message = This message contains malware ($malware_name)
        ! condition = ${if eq {$malware_name}{}{yes}{no}}
 
  accept
######################################################################
#                      ROUTERS CONFIGURATION                         #
#               Specifies how addresses are handled                  #
######################################################################
#Настроки отвечающие за маршрутиpзацию сообщений
begin routers
#Аналог Sendmail mailertable, обеспечивает возможность отправки сообщений не по MX записям DNS
#а так как надо нам. Подробно описывал в статье 
#Маршрутизация (mailertable) в exim http://www.hilik.org.ua/index.php/archives/44
  driver = manualroute
  domains = ! +local_domains
  transport = remote_smtp
  route_data = ${lookup{$domain}dbm{/usr/local/etc/exim/mailertable.dbm}}   
#Смартхост для доставки почты за пределы нашей сети из пересылки на
#smarthost исключаются локальные домены и домены внутренней сети
#Подробно описывал в статье Exim и smarthost
# http://www.hilik.org.ua/index.php/archives/56
smart_relay:
  driver = manualroute
  domains = ! +local_domains
  transport = remote_smtp
  route_data = 89.252.0.132
  no_more
  no_verify_sender
#Маршрутизатор отправляющий отправленный клиентом spam, для изучения dspamом.
#То есть, если вам пришло письмо, которое вы считаете спамом, его надо отправить на адрес
#spam@hilik.org.ua. 
dspam_addspam_router:
  driver = accept
  domains                      = +local_domains
  expn = false
  local_parts = spam
  headers_add = "X-DSPAM-REPORT: Missclassified"
  transport = dspam_addspam_transport
 
#Роутер, что бы доставать из карантина письма, которые ошибочно были помечены как SPAM, #отправлять их надо на адрес notspam-mail@domain, где mail@domain надо заменить на email #пользователя 
dspam_notspam_router:
  driver = accept
  domains                      = +local_domains
  local_part_prefix = notspam-
  transport = dspam_notspam_transport
 
#Это непосредственно роутер который отправляет письмо на проверку DSpam
dspam_spamscan_router:
  no_verify
  headers_remove = X-FILTER-SPAM : X-Spam-Score : X-Spam-Score-Gate : X-Spam-Report : X-Spam-Gate-Subject : X-Spam-Flag : X-S
  condition = "${if and {{!eq {$received_protocol}{spam-scanned}} {!def:h_X-FILTER-SPAM:}} {1}{0}}"
  domains                      = +local_domains
  driver = accept
#В /usr/local/etc/exim/whitelist перечисляются email отправителей, почту от которых проверять не надо
#email перечислены, каждый в одной строке
  senders = ! /usr/local/etc/exim/whitelist
  headers_add = X-FILTER-SPAM: ICF Team Spam Filter on $primary_hostname, $tod_full\n\ X-SENDER-INFO: ${if def:authenticated_id {ID - ${authenticated_id},}} \
                ${if def:authenticated_sender {authenticated_sender - ${authenticated_sender},}} \
                ${if def:sender_ident {rfc1413(ident) - ${sender_ident},}} \
                ${if def:originator_uid {UID - ${originator_uid},}} \
                ${if def:originator_gid {GID - ${originator_gid}}}
  local_parts = !addham:!addspam:!ham:!spam:!sexy
  transport = dspam_spamcheck_transport
#Стандартный маршрутизатор, отпределяет MX на который будет отправляться письмо
dnslookup:
  driver = dnslookup
  domains = ! +local_domains
  transport = remote_smtp
  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
  no_more
#Файл алиасов
system_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup{$local_part}lsearch{/usr/local/etc/exim/aliases}}
  user = mailnull
  group = mail
  file_transport = address_file
  pipe_transport = address_pipe
#Маршрутизатор, складывающий всю почту к домену в почтовый ящик абонента, подробно #описывался в  Exim, почта для домена в один почтовый ящик
#http://www.hilik.org.ua/index.php/archives/347
hilik_router:
  driver = redirect
  domains = hilik.kiev.ua : hilik.org.ua 
  data = sh@sh.hilik.org.ua
#Стандартный роутер, обслуживает .forward файлы
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} }
# Стандартный роутер, предназначен для доставки почты в майлбоксы, находящиеся в /var/mail
#В случае, если доставка невозможна, ответит Unknown user
localuser:
  driver = accept
  check_local_user
  transport = local_delivery
  cannot_route_message = Unknown user
 
######################################################################
#                      TRANSPORTS CONFIGURATION                      #
######################################################################
#Транспорты - та часть что непосредственно занимается доставкой сообщений
begin transports
#Транспорт для отправки по SMTP протоколу
remote_smtp:
  driver = smtp
#Транспорт доставки сообщений для изучения как SPAM DSpamу
dspam_addspam_transport:
  driver = pipe
  command = /usr/local/bin/dspam --user system --class=spam --source=error
  return_path_add = false
  return_fail_output = true
  log_output = true
  home_directory = "/tmp"
  current_directory = "/tmp"
  user = mailnull
  group = mail
#Транспорт для изучения писем DSpam, ложно помеченных как SPAM
dspam_notspam_transport:
  driver = pipe
  command = "/usr/local/bin/dspam --user \
                $local_part@$domain --class=innocent \
                --source=error --deliver=innocent %u"
  return_path_add = false
  return_fail_output = true
  log_output = true
  home_directory = "/tmp"
  current_directory = "/tmp"
  user = mailnull
  group = mail
#Транспорт отправляющий сообщения на проверку DSpamу
dspam_spamcheck_transport:
  driver = pipe
  command = /usr/local/bin/dspam --deliver=innocent \
                --user "$local_part@$domain" -- %u
  user = mailnull
  group = mail
  return_path_add = false
  log_output = true
  return_fail_output = true
  headers_remove        = X-DSPAM-Result
#Транспорт отправляющий письма локальных пользователей в их mailboxы
local_delivery:
  driver = appendfile
  file = /var/mail/$local_part
  delivery_date_add
  envelope_to_add
  return_path_add
  group = mail
  user = $local_part
  mode = 0660
  no_mode_fail_narrower
#Стандартные транспорты для aliasов
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                           #
######################################################################
#Настройки очереди, определяют, что будет делать exim с письмами застрявшими в очереди
begin retry
# Address or Domain    Error       Retries
# -----------------    -----       -------
*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h

После того, как настройка exim окончена, добавим разрешение на его запуск

echo "exim_enable=YES" >>/etc/rc.conf

и запустить exim

/usr/local/etc/rc.d/exim start

Проверим работу.

exim -bt hilik@hilik.org.ua
hilik@hilik.org.ua
  router = dspam_spamscan_router, transport = dspam_spamcheck_transport

Выполнение команды exim -bt hilik@hilik.org.ua показывает что почта будет доставлена на проверку dspamу

exim -bt hilik@ukr.net
hilik@ukr.net
  router = smart_relay, transport = remote_smtp
  host 89.252.0.132 [89.252.0.132]

Письмо на ukr.net пойдет через смартхост.
Настройки верны, а все что мы не принимаем можно увидеть в /var/log/exim/rejectlog
И как финал, поставим лог файлы exim на ротейт, для этого выполним

crontab -e

и внесем такую строку

0       0       *       *       *       /usr/local/sbin/exicyclog

Добавить в закладки:

google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru
  • By Михаил, 17.12.2008 @ 18:53

    Очень хорошая статья — спасибо большое.

  • By sp_grind, 04.11.2009 @ 19:23

    Прошу прощения, вопрос наверное оч глупый, но всё же…
    Будет ли корректно работать почтовик, если у меня нет доменного имени? Нету ни A-записей, ни MX-записей. Т.е. если у меня внешняя айпи 200.200.200.200, то после настройки на почту «admin@200.200.200.200» можно отправить письмо?
    По сути это единственный камень предкновения для поднятия почтовика =) Пол огике вещей всё должно работать, но мало ли… Заранее боагодарен за ответ

  • By sp_grind, 04.11.2009 @ 19:26

    Кстати вашу статью нахожу очень наглядной и понятной. Большое спасибо.

  • By hilik, 04.11.2009 @ 22:57

    Можно вписать произволдьное имяЮ если производить доставку напрямую на сервер, то все будет работать. ДНС нужен почтовому серверу только для того, что бы знать куда доставлять почту. Если вы все делаете в рамках своего сервера, то имя домена можете использовать то, которое вам захочется. Главное настроить сервер так, что бы он знал, что это то имя домена, для которого он должен принимать почту.

Other Links to this Post


Украинская Баннерная Сеть