<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jared.kiev.ua &#187; Spamassassin</title>
	<atom:link href="http://jared.kiev.ua/tags/spamassassin/feed/" rel="self" type="application/rss+xml" />
	<link>http://jared.kiev.ua</link>
	<description>Сетап как стиль жизни</description>
	<lastBuildDate>Wed, 07 Mar 2012 19:15:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Exim: автоблокировка спам-хостов</title>
		<link>http://jared.kiev.ua/2011/05/exim-autoblock-spam/</link>
		<comments>http://jared.kiev.ua/2011/05/exim-autoblock-spam/#comments</comments>
		<pubDate>Mon, 16 May 2011 11:38:27 +0000</pubDate>
		<dc:creator>jared</dc:creator>
				<category><![CDATA[Exim]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Скрипты]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[Spamassassin]]></category>

		<guid isPermaLink="false">http://jared.kiev.ua/?p=246</guid>
		<description><![CDATA[<p>Несмотря на то, что моя конфигурация Exim вышла довольно удачной, некоторое количество спама через нее все же проходит. Как правило, сыпется он с одних и тех же спам-серверов, которые можно блокировать. Однако, каждый раз ходить на сервер через некоторое время становится лениво, потому автоматизируем процесс:</p>
<p><a href="http://jared.kiev.ua/2011/05/exim-autoblock-spam/" class="more-link">Далее&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Несмотря на то, что моя конфигурация Exim вышла довольно удачной, некоторое количество спама через нее все же проходит. Как правило, сыпется он с одних и тех же спам-серверов, которые можно блокировать. Однако, каждый раз ходить на сервер через некоторое время становится лениво, потому автоматизируем процесс:</p>
<pre>#!/bin/sh

for file in `find /var/mail/yourdomain.com/spamreport/new -type f`
do
    cat $file | grep "Subject: block=" | sed 's/Subject: block=//' >> /usr/local/etc/exim/spam-hosts
done

rm -f /var/mail/yourdomain.com/spamreport/new/*
</pre>
<p>Осталось внести изменения в конфигурацию Exim. Добавляем в /usr/local/etc/exim/100.main.conf: </p>
<pre>hostlist bad_hosts = net-iplsearch;/usr/local/etc/exim/spam-hosts</pre>
<p>В /usr/local/etc/exim/configure правим ту часть, где описывается acl_check_rcpt:</p>
<pre># Эти правила срабатывают для каждого письма
acl_check_rcpt:

warn set acl_c_lp       = $local_part@$domain

deny   message = Relay not permitted
       hosts = +bad_hosts
</pre>
<p>Создаем файл и перезапускаем Exim:</p>
<pre># touch /usr/local/etc/exim/spam-hosts
# /usr/local/etc/rc.d/exim restart
</pre>
<p>Для успешной работы надо создать почтовый ящик spamreport@yourdomain.com и вставить вызов скрипта в Cron. Теперь на spamreport@yourdomain.com можно отправлять письма с темой &#171;block=123.32.14.56&#8243;, где 123.32.14.56 &#8212; ip спам-сервера.</p>
]]></content:encoded>
			<wfw:commentRss>http://jared.kiev.ua/2011/05/exim-autoblock-spam/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exim &#8212; ошибка в конфиге</title>
		<link>http://jared.kiev.ua/2010/07/exim-bug/</link>
		<comments>http://jared.kiev.ua/2010/07/exim-bug/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 11:10:09 +0000</pubDate>
		<dc:creator>jared</dc:creator>
				<category><![CDATA[Exim]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[SpamAssassin]]></category>
		<category><![CDATA[Почта]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[Spamassassin]]></category>

		<guid isPermaLink="false">http://jared.kiev.ua/?p=228</guid>
		<description><![CDATA[<p>К сожалению, в мою <a href="http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/">конфигурацию</a> Экзима закралась ошибка, которая хоть и появлялась редко, была довольно досадной. В частности, при определенных условиях, ACL, который проверяет почту на спам, не видел переменную, в которой хранился адрес адресата и не отрабатывал. В основную статью изменения уже добавлены, решил выложить дополнительный пост для тех, кто ее не будет перечитывать. Итак, надо поправить 2 файла: 500.acl-check-data.conf и configure.</p>
<p><a href="http://jared.kiev.ua/2010/07/exim-bug/" class="more-link">Далее&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>К сожалению, в мою <a href="http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/">конфигурацию</a> Экзима закралась ошибка, которая хоть и появлялась редко, была довольно досадной. В частности, при определенных условиях, ACL, который проверяет почту на спам, не видел переменную, в которой хранился адрес адресата и не отрабатывал. В основную статью изменения уже добавлены, решил выложить дополнительный пост для тех, кто ее не будет перечитывать. Итак, надо поправить 2 файла: 500.acl-check-data.conf и configure.</p>
<p>500.acl-check-data.conf: после &#171;.ifdef USE_SPAMD&#187; добавляем строку:</p>
<pre>warn set acl_m5 = $acl_c_lp
</pre>
<p>configure: после строки &#171;acl_check_rcpt:&#187; вставляем:</p>
<pre>warn set acl_c_lp       = $local_part@$domain</pre>
<p>Перед обоими вставками лучше вставить пустую строку.</p>
]]></content:encoded>
			<wfw:commentRss>http://jared.kiev.ua/2010/07/exim-bug/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Почтовый сервер как у провайдера, часть 2: ClamAV, SpamAssassin, Dovecot</title>
		<link>http://jared.kiev.ua/2010/01/isp-mailserver-2-clam-assassin/</link>
		<comments>http://jared.kiev.ua/2010/01/isp-mailserver-2-clam-assassin/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 15:55:34 +0000</pubDate>
		<dc:creator>jared</dc:creator>
				<category><![CDATA[ClamAV]]></category>
		<category><![CDATA[Dovecot]]></category>
		<category><![CDATA[Exim]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[SpamAssassin]]></category>
		<category><![CDATA[Почта]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[Spamassassin]]></category>

		<guid isPermaLink="false">http://jared.kiev.ua/?p=67</guid>
		<description><![CDATA[<p>Продолжим с нашим почтовым сервером, ставим Spamassassin и ClamAV:</p>
<pre># cd /usr/ports/security/clamav
# make config

  ┌────────────────────────────────────────────────────────────────────┐
  │                    Options for clamav 0.95.3                       │
  │ ┌────────────────────────────────────────────────────────────────┐ │
  │ │    [X] ARC           Enable arch archives support              │ │
  │ │    [X] ARJ           Enable arj archives support               │ │
  │ │    [X] LHA           Enable lha archives support               │ │
  │ │    [X] UNZOO         Enable zoo archives support               │ │
  │ │    [X] UNRAR         Enable rar archives support               │ │
  │ │    [ ] MILTER        Compile the milter interface              │ │
  │ │    [ ] LDAP          libmilter was built with LDAP             │ │
  │ │    [X] ICONV         Enable ICONV support                      │ │
  │ │    [ ] STDERR        Print logs to stderr instead of stdout    │ │
  │ │    [ ] EXPERIMENTAL  Build experimental code                   │ │
  ├─└────────────────────────────────────────────────────────────────┘─┤
  │                       [  OK  ]       Cancel                        │
  └────────────────────────────────────────────────────────────────────┘</pre>
<p><a href="http://jared.kiev.ua/2010/01/isp-mailserver-2-clam-assassin/" class="more-link">Далее&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<p>Продолжим с нашим почтовым сервером, ставим Spamassassin и ClamAV:</p>
<pre># cd /usr/ports/security/clamav
# make config

  ┌────────────────────────────────────────────────────────────────────┐
  │                    Options for clamav 0.95.3                       │
  │ ┌────────────────────────────────────────────────────────────────┐ │
  │ │    [X] ARC           Enable arch archives support              │ │
  │ │    [X] ARJ           Enable arj archives support               │ │
  │ │    [X] LHA           Enable lha archives support               │ │
  │ │    [X] UNZOO         Enable zoo archives support               │ │
  │ │    [X] UNRAR         Enable rar archives support               │ │
  │ │    [ ] MILTER        Compile the milter interface              │ │
  │ │    [ ] LDAP          libmilter was built with LDAP             │ │
  │ │    [X] ICONV         Enable ICONV support                      │ │
  │ │    [ ] STDERR        Print logs to stderr instead of stdout    │ │
  │ │    [ ] EXPERIMENTAL  Build experimental code                   │ │
  ├─└────────────────────────────────────────────────────────────────┘─┤
  │                       [  OK  ]       Cancel                        │
  └────────────────────────────────────────────────────────────────────┘

# make install clean
# cd /usr/ports/mail/p5-Mail-SpamAssassin/
# make config

   ┌────────────────────────────────────────────────────────────────────┐
   │             Options for p5-Mail-SpamAssassin 3.2.5_4               │
   │ ┌────────────────────────────────────────────────────────────────┐ │
   │ │   [X] AS_ROOT        Run spamd as root (recommended)           │ │
   │ │   [X] SPAMC          Build spamd/spamc (not for amavisd)       │ │
   │ │   [ ] SACOMPILE      sa-compile                                │ │
   │ │   [ ] DKIM           DKIM/DomainKeys Identified Mail           │ │
   │ │   [X] SSL            Build with SSL support for spamd/spamc    │ │
   │ │   [X] GNUPG          Install GnuPG (for sa-update)             │ │
   │ │   [X] MYSQL          Add MySQL support                         │ │
   │ │   [ ] PGSQL          Add PostreSQL support                     │ │
   │ │   [X] RAZOR          Add Vipul's Razor support                 │ │
   │ │   [X] SPF_QUERY      Add SPF query support                     │ │
   │ │   [ ] RELAY_COUNTRY  Relay country support                     │ │
   ├─└────────────────────────────────────────────────────────────────┘─┤
   │                       [  OK  ]       Cancel                        │
   └────────────────────────────────────────────────────────────────────┘
# make install clean</pre>
<p>В дефолтной конфигурации clamav написаны вполне разумные значения, потому файл конфига /usr/local/etc/clamd.conf вышел маленький:</p>
<pre><span style="color: #000000;"># Включаем логгирование. </span>
LogFile /var/log/clamav/clamd.log

<span style="color: #000000;"># Писать ли в лог время события</span>
#LogTime yes

<span style="color: #000000;"># Расположение pid-файла</span>
PidFile /var/run/clamav/clamd.pid

<span style="color: #000000;"># Путь к временному каталогу</span>
TemporaryDirectory /tmp

<span style="color: #000000;"># Путь к базе данных</span>
DatabaseDirectory /var/db/clamav

<span style="color: #000000;"># Демон может работать в локальном режиме, сетевом или обоих сразу.</span>
# Рекомендуется локальный, оставим.

<span style="color: #000000;"># Путь к локальному сокету.</span>
LocalSocket /var/run/clamav/clamd.sock

<span style="color: #000000;"># Удалять сокет-файл после нечистого завершения</span>
FixStaleSocket yes

<span style="color: #000000;"># Работать под указанным юзером</span>
User exim
<span style="color: #000000;">
# Дополнительные группы AllowSupplementaryGroups yes

# Включить e-mail сканер</span>
ScanMail yes</pre>
<p>/usr/local/etc/freshclam.conf:</p>
<pre><span style="color: #000000;"># Путь к каталогу с базой, должен совпадать с путем самого clamav</span>
DatabaseDirectory /var/db/clamav

<span style="color: #000000;"># Путь к лог-файлу</span>
UpdateLogFile /var/log/clamav/freshclam.log

<span style="color: #000000;"># Логгировать ли время</span>
LogTime yes

<span style="color: #000000;"># PID-файл</span>
PidFile /var/run/clamav/freshclam.pid

<span style="color: #000000;"># Пользователь, под которым работать</span>
DatabaseOwner exim

<span style="color: #000000;"># Дополнительные группы</span>
AllowSupplementaryGroups yes

<span style="color: #000000;"># Зеркала для обновления, для Украины - ua</span>
DatabaseMirror db.ua.clamav.net
DatabaseMirror database.clamav.net

<span style="color: #000000;"># Настройки прокси, если кому надо</span>
# Default: disabled
#HTTPProxyServer myproxy.com
#HTTPProxyPort 1234
#HTTPProxyUsername myusername
#HTTPProxyPassword mypass

<span style="color: #000000;"># Исходящий ip-адрес, с которого будут запрашиваться обновления</span>
#LocalIPAddress aaa.bbb.ccc.ddd

<span style="color: #000000;"># Путь к конфигу clamd для его перегрузки с новыми базами</span>
NotifyClamd /usr/local/etc/clamd.conf</pre>
<p>Со SpamAssassin-ом та же история, большинство дефолтных опций нам подходит, /usr/local/etc/mail/spamassassin/local.cf:</p>
<pre><span style="color: #000000;"># Хедеры, которые не принимаем во внимание при проверке</span>
bayes_ignore_header X-Bogosity
bayes_ignore_header X-Spam-Flag
bayes_ignore_header X-Spam-Status</pre>
<p>Теперь включаем Clamd и SpamAssassin и взлетаем:</p>
<pre># chown -R exim:mail /var/log/clamav
# chown -R exim:mail /var/db/clamav
# chown -R exim:mail /var/run/clamav
# chown -R exim:mail /var/run/spamd
# echo clamav_clamd_enable=\"YES\" &gt;&gt; /etc/rc.conf
# echo clamav_freshclam_enable=\"YES\" &gt;&gt; /etc/rc.conf
# echo spamd_flags=\"--socketpath=/var/run/spamd.sock\" &gt;&gt; /etc/rc.conf
# echo spamd_enable=\"YES\" &gt;&gt; /etc/rc.conf
# sa-update
# /usr/local/etc/rc.d/sa-spamd start
# /usr/local/etc/rc.d/clamav-clamd restart
# /usr/local/etc/rc.d/clamav-freshclam start
</pre>
<p>Теперь займемся POP3-сервером,  который будет отдавать почту клиентам. В качестве него мы используем давно проверенное и надежное решение на базе Dovecot. Это многофункциональный сервер, который умеет оба эти протокола, как с поддержкой SSL, так и без, плюс умеет работать с MySQL-базой, что, стобственно, нам и нужно. Итак, начнем:</p>
<pre># cd /usr/ports/mail/dovecot
# make config

 ┌────────────────────────────────────────────────────────────────────┐
 │                    Options for dovecot 1.2.8                       │
 │ ┌────────────────────────────────────────────────────────────────┐ │
 │ │              [X] KQUEUE       kqueue(2) support                │ │
 │ │              [X] SSL          SSL support                      │ │
 │ │              [ ] IPV6         IPv6 support                     │ │
 │ │              [X] LDA          LDA support                      │ │
 │ │              [ ] MANAGESIEVE  ManageSieve support              │ │
 │ │              [ ] GSSAPI       GSSAPI support                   │ │
 │ │              [ ] VPOPMAIL     VPopMail support                 │ │
 │ │              [ ] BDB          BerkleyDB support                │ │
 │ │              [ ] LDAP         OpenLDAP support                 │ │
 │ │              [ ] PGSQL        PostgreSQL support               │ │
 │ │              [X] MYSQL        MySQL support                    │ │
 │ │              [ ] SQLITE       SQLite support                   │ │
 │ │                                                                │ │
 │ │                                                                │ │
 │ │                                                                │ │
 ├─└────────────────────────────────────────────────────────────────┘─┤
 │                       [  OK  ]       Cancel                        │
 └────────────────────────────────────────────────────────────────────┘

# make install clean
</pre>
<p>Пока довкот собирается, напишем ему конфигурационные файлы и положим в /usr/local/etc. Большинство значений по умолчанию достаточно разумны, потому тут пишем только то, что нам надо заменить.</p>
<p>dovecot.conf:</p>
<pre># Каталог для хранения рабочих данных
base_dir = /var/run/dovecot/

# Протоколы, которые будем поддерживать
protocols = imap pop3 imaps pop3s

# Адреса, которые будем слушать, мы слушаем все
listen = *

# Отключать ли авторизацию без SSL
disable_plaintext_auth = no

# Сбрасывать ли клиентские подключения при остановке главного процесса.
# Теоретически с этой опцией можно апгрейдить довкот на ходу
shutdown_clients = no

# Лог-файл для ошибок
log_path = /var/log/dovecot.log

# Лог-файл для остального
info_log_path = /var/log/dovecot-info.log

# На каких адресах ждать соединений с SSL, нам надо на всех
ssl_listen = *

# Включаем SSL
ssl = yes

# Файлы ключа и сертификата SSL
ssl_cert_file = /etc/ssl/certs/mail.pem
ssl_key_file = /etc/ssl/certs/mail.pem

# Каталог, где довкот держит сокеты для логин-процессов
login_dir = /var/run/dovecot/login

# Делать ли chroot для логин-процессов
login_chroot = yes

# Пользователь, под которым запускать логин-процессы. НЕ должен совпадать с тем, под которым работает почтовый сервер
login_user = dovecot

# Надо ли для каждой попытки логина запускать новый процесс
#login_process_per_connection = no

# Приветственное сообщение для клиентов, не будем палиться <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> )
login_greeting = Microsoft POP3 server

# Место и формат хранения пользовательской почты. У нас - Maildir
mail_location = maildir:/var/mail/%d/%n

# Пользователь и группа, под которыми работаем с почтой
mail_uid = exim
mail_gid = mail

# "Привелигированная группа" для доступа к письмам. У нас и так основная - mail, но пусть будет
mail_privileged_group = mail

# Если что - тут включается дебаг
mail_debug = no

# Показывать в top и ps более подробные данные о процессах
verbose_proctitle = yes

# Ограничиваем UID/GID, которым с нами можно вообще работать
first_valid_uid = 500
last_valid_uid = 0
first_valid_gid = 0
last_valid_gid = 0

# Каталоги, куда можно делать chroot
valid_chroot_dirs = /var/mail

protocol imap {

 # Исправление известных глюков с почтовыми клиентами
 imap_client_workarounds = delay-newmail netscape-eoh tb-extra-mailbox-sep
}

protocol pop3 {
 # Поддерживать ли команду LAST из ранних спецификаций POP3
 #pop3_enable_last = no

 # Лочить ли ящик на время сессии
 #pop3_lock_session = no

 # Формат POP3 UIDL идентификатора
 pop3_uidl_format = %08Xu%08Xv

 # Формат POP3 logout сообщения:
 #pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s

 # Исправление известных глюков с почтовыми клиентами
 pop3_client_workarounds = outlook-no-nuls oe-ns-eoh
}

# Допустимые символы в логине
auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@

# Логгирование безуспешных попыток входа с причинами
auth_verbose = no

# Дебаг авторизации
#auth_debug = no

# Если пароль не подходит, записать его в лог
auth_debug_passwords = no

auth default {

 # Список желаемых механизмов авторизации. Допускаются:
 # plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey gss-spnego
 mechanisms = plain login cram-md5

 # База откуда брать пароли
 passdb sql {
 # Путь к файлу конфигурации SQL
 args = /usr/local/etc/dovecot-sql.conf
 }

 # База откуда брать пользовательские данные (путь, uid/gid и т.д.)
 userdb sql {
 # Путь к файлу конфигурации SQL
 args = /usr/local/etc/dovecot-sql.conf
 }

 # Пользователь, под которым проводить авторизацию. По возможности - не root
 user = exim

}
</pre>
<p>dovecot-sql.conf:</p>
<pre># Тип SQL-сервера
driver = mysql

# Параметры соединения с SQL
connect = host=localhost user=vexim password=9gp784whp9w28wy5 dbname=vexim

# Схема хранения паролей
default_pass_scheme = PLAIN-MD5

# Запросы для извлечения данных из БД
password_query = SELECT users.crypt as `password` FROM users,domains WHERE users.username = '%u' AND users.enabled = '1' AND users.type='local' and domains.enabled='1' and domains.domain_id = users.domain_id
user_query = SELECT pop as home, uid, gid FROM users WHERE username = '%u'
</pre>
<p>Вот и все, конфигурация достаточно простая (хотя в дефолтном файле dovecot.conf есть еще большоt количество опций). Теперь запускаем всю конструкцию и тестируем:</p>
<pre># echo dovecot_enable=\"YES\" &gt;&gt; /etc/rc.conf
# /usr/local/etc/rc.d/dovecot restart
# telnet localhost 110
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK Microsoft POP3 server
^C
</pre>
<p>Все хорошо, довкот нас приветствует правильно. Дальше уже тестировать будем вживую, почтовыми клиентами, хотя проблем быть не должно.</p>
<p>С сопутствующим софтом вроде закончили, можно <a href="http://jared.kiev.ua/2010/01/isp-mailserver-3-vexim/">ехать дальше</a>.</p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/">Почтовый сервер как у провайдера, часть 1: Exim</a></p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-2-clam-assassin/">Почтовый сервер как у провайдера, часть 2: ClamAV, SpamAssassin, Dovecot</a></p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-3-vexim/">Почтовый сервер как у провайдера, часть 3: Vexim</a></p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-4-start/">Почтовый сервер как у провайдера, часть 4: взлетаем</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jared.kiev.ua/2010/01/isp-mailserver-2-clam-assassin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Почтовый сервер как у провайдера, часть 1: Exim</title>
		<link>http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/</link>
		<comments>http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 13:10:48 +0000</pubDate>
		<dc:creator>jared</dc:creator>
				<category><![CDATA[Exim]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Почта]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[Greylisting]]></category>
		<category><![CDATA[Spamassassin]]></category>
		<category><![CDATA[Vexim]]></category>

		<guid isPermaLink="false">http://jared.kiev.ua/?p=27</guid>
		<description><![CDATA[<h5>Exim + Vexim + MySQL + Clamav + SpamAssassin + Greylisting + Whitelisting + Dovecot</h5>
<p style="text-align: justify;">Решил я обновить почтовый сервер в провайдере, где работаю. Старый был в принципе тоже ничего, но строился в свое время изрядно впопыхах, без детального изучения документации, плюс пропускал довольно много спама и не обладал некоторыми фичами. В роли нового демона был выбран Exim плюс веб-интерфейс для него Vexim. Exim &#8212; хороший и мощный почтовый сервер, способный пропускать через себя огромные потоки писем. Однако, в конфигурации он сложнее, чем, например, Postfix,  за что и не любим многими, потому статей по его настройке, особенно с прибамбасами, в сети не так много.</p>
<p><a href="http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/" class="more-link">Далее&#8230;</a></p>
]]></description>
			<content:encoded><![CDATA[<h5>Exim + Vexim + MySQL + Clamav + SpamAssassin + Greylisting + Whitelisting + Dovecot</h5>
<p style="text-align: justify;">Решил я обновить почтовый сервер в провайдере, где работаю. Старый был в принципе тоже ничего, но строился в свое время изрядно впопыхах, без детального изучения документации, плюс пропускал довольно много спама и не обладал некоторыми фичами. В роли нового демона был выбран Exim плюс веб-интерфейс для него Vexim. Exim &#8212; хороший и мощный почтовый сервер, способный пропускать через себя огромные потоки писем. Однако, в конфигурации он сложнее, чем, например, Postfix,  за что и не любим многими, потому статей по его настройке, особенно с прибамбасами, в сети не так много.</p>
<p style="text-align: justify;">Эксперименты, которые полагается проводить на кошках, решил провести на своем сервере, который держит почту для jared.kiev.ua, собственно, по нему статья и писалась. Сначала думал пойти по простому пути: нашел сайт <a href="http://n1ck.name" target="_blank">http://n1ck.name</a>, где товарищ делает связку exim+vexim для Линукса. Может быть для сетапа на чистый линуксовйы сервер оно и есть самое то, но под фрей масса тамошних фич просто не завелась (хотя подкинули идеи). Далее попытался собрать связку по мануалу с сайта Vexim &#8212; та же история. В конце концов, после прочтения <a href="http://www.lissyara.su/articles/freebsd/mail/exim+exchange/" target="_blank">статьи у Лиссяры</a> (статья хорошая, но нет нужных мне фич, опять же взял идеи), решил построить свой конфиг, с <span style="text-decoration: line-through;">блекджеком и шлюхами</span> тем, что мне надо.</p>
<p style="text-align: justify;">Итак, к делу. В дальнейшем буду исходить из того, что у нас есть сервер под FreeBSD (неважно, jail или нет), на нем поднята связка Apache+PHP+MySQL. Версия MySQL должна быть не ниже 5, иначе некоторые запросы откажутся работать. Заходим в порты и видим, что экзиму наконец написали конфигурационное меню и больше не надо править мейкфайлы:</p>
<pre># cd /usr/ports/mail/exim
# make config

  ┌────────────────────────────────────────────────────────────────────┐
  │                      Options for exim 4.71                         │
  │ ┌────────────────────────────────────────────────────────────────┐ │
  │ │[ ] ALT_CONFIG_PREFIX  Allow alternate configuration files      │ │
  │ │[X] AUTH_CRAM_MD5      Enable CRAM-MD5 authentication mechanisms│ │
  │ │[X] AUTH_DOVECOT       Enable Dovecot authentication mechanisms │ │
  │ │[X] AUTH_PLAINTEXT     Enalbe 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                 │ │
  │ │[X] 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] 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     │ │
  │ │[X] PASSWD             Enable /etc/passwd lookups               │ │
  │ │[ ] PGSQL              Link against libpq                       │ │
  │ │[ ] READLINE           Enable readline(3) library               │ │
  │ │[ ] SASLAUTHD          Enable use of Cyrus SASL auth daemon     │ │
  │ │[ ] SA_EXIM            SA-Exim support                          │ │
  │ │[X] SPF                Enable Sender Policy Framework checking  │ │
  │ │[ ] SQLITE             Enable SQLite lookups                    │ │
  │ │[ ] SRS                Enable Sender Rewriting Scheme           │ │
  │ │[ ] SRS_ALT            Enable alternative SRS library           │ │
  │ │[X] SUID               Install the exim binary suid root        │ │
  │ │[X] TCP_WRAPPERS       Enable /etc/hosts.allow access control   │ │
  │ │[X] TLS                Link against OpenSSL                     │ │
  │ │[ ] WISHLIST           Include the unsupported patches          │ │
  │ │[ ] XCLIENT            Enable XCLIENT command in exim           │ │
  ├─└────────────────────────────────────────────────────────────────┘─┤
  │                       [  OK  ]       Cancel                        │
  └────────────────────────────────────────────────────────────────────┘
# make install clean</pre>
<p>Пока экзим ставится, создадим ssl-сертификат:</p>
<pre># mkdir -p /etc/ssl/certs
# cd /etc/ssl/certs
# openssl req -x509 -newkey rsa:1024 -keyout mail.pem -out mail.pem -days 9999 -nodes

Country Name (2 letter code) [CA]: UA
State or Province Name (full name) [Quebec]: Kiev
Locality Name (eg, city) [Montreal]: Kiev
Organization Name (eg, company) [Open Network Architecture]: Internet Provider
Organizational Unit Name (eg, section) [Internet Department]: Network Operation Center
Common Name (eg, YOUR name) []: jared.kiev.ua
Email Address []: noc@jared.kiev.ua</pre>
<p>Заполняем соответственно нашим данным поля, особое внимание уделяем полю Common Name (eg, YOUR name) [], тут пишем DNS-имя нашего почтового сервера. Теперь у нас появился файл /etc/ssl/certs/mail.pem, выставим на него хозяина и права, заодно создадим пользователя, под которым у нас будет работать вся связка.</p>
<pre># chmod 440 /etc/ssl/certs/mail.pem
# chgrp mail /etc/ssl/certs/mail.pem
# pw useradd exim -c "Exim" -d /var/spool/mqueue -s /sbin/nologin -g mail
# cat /etc/master.passwd | grep exim</pre>
<p>Получаем строку вида exim:*:1002:6::0:0:Exim:/var/spool/mqueue:/sbin/nologin, из нее запоминаем User ID и Group ID, в примере они равны 1002 и 6 соответственно.</p>
<p>Теперь подсунем экзиму его конфиги. Ложим их в каталог /usr/local/etc/exim/. Т.к. его родной файл configure большой и неудобный в правке, я его разбил на ряд файлов, которые включаются в алфавитном порядке:</p>
<p><span style="color: #0000ff;">100.main.conf</span> &#8212; основная конфигурация сервера: переменные, соединение с БД, логгирование и т.д.<br />
<span style="color: #0000ff;">110.greylist.conf</span> &#8212; скрипты грейлистинга<br />
<span style="color: #0000ff;">200.acl-greylist.conf</span> &#8212; ACL для грейлистинга<br />
<span style="color: #0000ff;">400.acl-check-rcpt-syntax.conf</span> &#8212; ACL-проверки хоста-отправителя<br />
<span style="color: #0000ff;">410.acl-check-rcpt-spam.conf</span> &#8212; ACL для начисления антиспам-баллов по заголовкам письма<br />
<span style="color: #0000ff;">420.acl-check-rcpt-end.conf </span>- конец ACL check_rcpt: задержки, грейлисты, блеклисты<br />
<span style="color: #0000ff;">500.acl-check-data.conf </span>- ACL для проверки содержимого письма: аттачи, Spamassassin, антивирус<br />
<span style="color: #0000ff;">600.routers.conf </span>- роутеры<br />
<span style="color: #0000ff;">610.routers-groups.conf</span> &#8212; роутер для поддержки групп пользователей<br />
<span style="color: #0000ff;">700.transports.conf</span> &#8212; транспорты<br />
<span style="color: #0000ff;">800.retry.conf</span> &#8212; повторная отправка писем<br />
<span style="color: #0000ff;">900.authenticators.conf</span> &#8212; аутентификация<br />
<span style="color: #0000ff;">configure</span> &#8212; основной файл конфигурации, подключает все остальные<br />
<span style="color: #0000ff;">dialup_hosts</span> &#8212; регулярные выражения с описанием хостов, которые нам не нравятся<br />
<span style="color: #0000ff;">system-filter</span> &#8212; действия со спамом: пометить/удалить<br />
<span style="color: #0000ff;">whitelist-hosts</span> &#8212; список хостов, которые не проходят ряд проверок<br />
<span style="color: #0000ff;">whitelist-sender</span> &#8212; список отправителей, которые не проходят ряд проверок</p>
<p style="text-align: justify;">На первый взгляд, выглядит несколько запутано, но я попробую пояснить логику работы Экзима с таким конфигом. При получении письма происходит следующее:</p>
<ul style="text-align: justify;">
<li>проверяется хост-отправитель: синтаксис приветствия, сессии, доменного имени, соответствия имени адресу и т.п. Если обнаружены совсем уже явные ошибки (некорректные символы, попытки выдать себя за другие хосты и т.п.) &#8212; письмо не пропускается, иначе письму начисляются спам-баллы в попугаях;</li>
<li>если хост либо отправитель не внесены в белые списки, срабатывает задержка, потом грейлистинг. Задержка вычисляется по формуле 15с + (кол-во набранных ранее попугаев / 10),  грейлистинг просто если не знает такого хоста, добавляет его в серый список и отсылает ошибку &#171;временная проблема&#187;. Если хост нормальный релей, он пошлет письмо повторно и попадет в белый список (кстати, нормальные хосты готовы прождать и предыдущую задержку, это спамеры торопятся разослать мегатонны писем и ждать им некогда);</li>
<li>письмо разбирается на запчасти. Если в нем есть запрещенные расширения файлов в аттаче или вирусы, оно нещадно рубится. Там же письмо отправляется в Spamassassin, количество набранных там баллов умножается на 2 и прибавляется к попугаям;</li>
<li>Потом письмо отправляется к роутерам, которые решают, что с ним делать: отослать по SMTP, положить в ящик и  т.д. и назначают письму соответствующий транспорт. Роутер с группами &#8212; вообще интересная штука: группа &#8212; это нечто вроде алиаса, но до тех пор пока она не является приватной, писать в нее могут только члены группы;</li>
<li>Транспорты, понятное дело, выполняют то, чего от них хотят роутеры;</li>
<li style="text-align: justify;">Отдельно работает системный фильтр: на основании насчитанных спам-попугаев он либо правит тему письма на что-то вроде &#171;*SPAM* [104 points] Ваш сайт на первой странице google.com.ua&#187;, либо удаляет его совсем, в зависимости от настроек каждого отдельного почтового ящика;</li>
</ul>
<p style="text-align: justify;">Вроде по всему основному прошелся, теперь перейдем к самим конфигам.</p>
<p style="text-align: justify;">configure:</p>
<pre><span style="color: #000000;">######################################################################
#                  Runtime configuration file for Exim               #
######################################################################

</span><span style="color: #000000;"># Инклюдим главные настройки</span>
.include /usr/local/etc/exim/100.main.conf

<span style="color: #000000;"># Инклюдим настройки грейлистинга</span>
.include /usr/local/etc/exim/110.greylist.conf

<span style="color: #000000;">### конфигурация ACL для входящей почты</span>
begin acl

<span style="color: #000000;"># Начало ACL - "рабочий" ACL для грейлистинга</span>
.ifdef USE_GREYLIST

greylist_acl:
.include /usr/local/etc/exim/200.acl-greylist.conf

.endif

<span style="color: #000000;"># Проверка правильности HELO</span>
acl_check_helo:
 accept hosts = +relay_from_hosts
 drop condition = ${if match{$sender_helo_name}{MY_IP}{yes}{no} }
 message   = "Dropped spammer pretending to be us"
 drop condition = ${if match{$sender_helo_name}{^[0-9]\.[0-9]\.[0-9]\.[0-9]}{yes}{no} }
 message   = "Dropped IP-only or IP-starting helo"
accept

<span style="color: #000000;"># Эти правила срабатывают для каждого письма</span>
acl_check_rcpt:

warn set acl_c_lp = $local_part@$domain

<span style="color: #000000;"># acl_check_rcpt - проверки на синтаксическую правильность</span>
.include /usr/local/etc/exim/400.acl-check-rcpt-syntax.conf

<span style="color: #000000;"># acl_check_rcpt - проверки на спам - по хостам и прочему</span>.
.include /usr/local/etc/exim/410.acl-check-rcpt-spam.conf

<span style="color: #000000;"># acl_check_rcpt - блэк-листы, задержки и прочее</span>
.include /usr/local/etc/exim/420.acl-check-rcpt-end.conf

<span style="color: #000000;"># проверка тела письма
</span>acl_check_content:

<span style="color: #000000;"># Инклюдим конфигурацию проверки тела письма</span>
.include /usr/local/etc/exim/500.acl-check-data.conf

<span style="color: #000000;"># Что делаем с почтой</span>
begin routers
<span style="color: #000000;"># Инклюдим конфигурацию роутреров</span>
.include /usr/local/etc/exim/600.routers.conf

<span style="color: #000000;"># начинаются транспорты - как доставляем почту</span>
begin transports
<span style="color: #000000;"># Инклюдим транспорты</span>
.include /usr/local/etc/exim/700.transports.conf

<span style="color: #000000;"># Конфигурация повторов и перезаписи</span>
.include /usr/local/etc/exim/800.retry.conf

<span style="color: #000000;">#begin rewrite</span>

<span style="color: #000000;"># Секция авторизации при отправке писем.</span>
begin authenticators
<span style="color: #000000;"># Аутентификация юзеров.</span>
.include /usr/local/etc/exim/900.authenticators.conf</pre>
<p>100.main.conf, тут настраиваются основные параметры: IP, домены и т.д.:</p>
<pre><span style="color: #000000;"># Устанавливаем переменные</span>
MY_IP           = 123.123.123.123
INTERNAL_IP     = 192.168.1.10

<span style="color: #000000;"># Настройки Vexim</span>
USE_SPF         = true
USE_AV          = true
USE_SPAMD       = true
USE_GREYLIST    = true
TLS             = true

# Белые списки
hostlist whitelist_hosts = net-iplsearch;/usr/local/etc/exim/whitelist-hosts
addresslist whitelist_sender = wildlsearch;/usr/local/etc/exim/whitelist-sender

<span style="color: #000000;"># По IPv6 мы пока не работаем</span>
disable_ipv6=true

<span style="color: #000000;"># Пользователь и группа, от которой будет работать вся связка</span>
exim_user = exim
exim_group = mail

<span style="color: #000000;"># Тут были настройки рассылок, не пользуем - не сетапим</span>
MAILMAN_HOME=/usr/local/mailman
MAILMAN_WRAP=MAILMAN_HOME/mail/mailman
MAILMAN_USER=exim
MAILMAN_GROUP=mail

<span style="color: #000000;"># Вводим данные для подключения к MySQL серверу.
# словечко `hide`, вначале, означает, что при
# вызове проверки конфига командой
# exim -bV config_file эти данные не будут отображаться.
# Если без него - то будут показаны... Формат записи:
# хост/имя_бд/пользователь/пароль</span>
hide mysql_servers = localhost::(/tmp/mysql.sock)/mail/exim/8975f9i7vioyuhg

<span style="color: #000000;"># Интерфейсы, которые слушаем</span>
local_interfaces = MY_IP

<span style="color: #000000;"># Имя хоста. Используется в EHLO.
# Фигурирует в других пунктах, если они не заданы, типа qualify_domain и прочих..
# Если тут ничего не установлено (строка закомментирована), то используется то, что вернёт функция uname()</span>
primary_hostname = jared.kiev.ua

<span style="color: #000000;"># Запросы для выборки информации по доменам</span>
VIRTUAL_DOMAINS = SELECT DISTINCT domain FROM domains WHERE type = 'local' AND enabled = '1' AND domain = '${quote_mysql:$domain}'
RELAY_DOMAINS = SELECT DISTINCT domain FROM domains WHERE type = 'relay'  AND domain = '${quote_mysql:$domain}'
ALIAS_DOMAINS = SELECT DISTINCT alias FROM domainalias WHERE alias = '${quote_mysql:$domain}'

<span style="color: #000000;"># Делаем список локальных доменов. Далее этот список будет фигурировать в виде +local_domains
# В данном случае домены выбираются из БД MySQL. Также можно их просто перечислить через двоеточие.</span>
domainlist local_domains = @ : ${lookup mysql{VIRTUAL_DOMAINS}} : ${lookup mysql{ALIAS_DOMAINS}}
domainlist relay_to_domains = ${lookup mysql{RELAY_DOMAINS}}

<span style="color: #000000;"># Список доверенных сетей, откуда почта будет ходить без ряда проверок</span>
hostlist   relay_from_hosts = localhost : MY_IP : 192.168.100.0/20 : 192.168.80.0/24 

<span style="color: #000000;"># Вводим названия acl`ов для проверки почты.</span>
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_content
acl_smtp_helo = acl_check_helo

<span style="color: #000000;"># Если в настройках сказано проверять почту на вирусы - подключаем</span>
.ifdef USE_AV
av_scanner = clamd:/var/run/clamav/clamd.sock
.endif

<span style="color: #000000;"># Если в настройках сказано проверять почту на спам - подключаем</span>
.ifdef USE_SPAMD
spamd_address = /var/run/spamd.sock
.endif

<span style="color: #000000;"># Если в настройках сказано работать с поддержкой SSL - подключаем</span>
.ifdef TLS
 # SSL/TLS cert and key
 tls_certificate = /etc/ssl/certs/mail.pem
 tls_privatekey = /etc/ssl/certs/mail.pem
 # Advertise TLS to anyone
 tls_advertise_hosts = *
 tls_on_connect_ports=465
.endif

<span style="color: #000000;"># Имя домена добавляемое для локальных отправителей (реальных
# юзеров системы) т.е. почта отправляемая от root, будет от
# root@домен_указанный_здесь. Если пункт не задан, то используется
# имя хоста из `primary_hostname`. </span>
qualify_domain = jared.kiev.ua

<span style="color: #000000;"># Имя хоста для ситуации, обратной предыдущей, - это имя домена, добавляемое к почте для
# системных юзеров, ну и вообще для почты, пришедшей на адрес типа `root` etc...
# Если этоn пункт не задан то используется значение полученное из предыдущего пункта - `qualify_domain`</span>
qualify_recipient = jared.kiev.ua

<span style="color: #000000;"># A это как раз кусок вышеописанного анахронизма - про почту в
# виде user@[222.222.222.222] - принимать её или нет. По дефолту
# (когда строка закомментирована) значение - false. Если захотите
# поставить true то надо будет добавить в список доменов
# комбинацию @[] - она означает `все локальные адреса`</span>
allow_domain_literals = false

<span style="color: #000000;"># запрещаем работу доставки под юзером root - в целях безопасности</span>
never_users = root

<span style="color: #000000;"># Проверяем соответствие прямой и обратной зон для всех хостов.
# Тока зачем это нужно - даже и незнаю... Спам на этом не режется.
# Зато возможны проблемы - если сервер зоны скажет `сервер файлед`
# то почту от этого хоста Вы не получите <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span>
#host_lookup = *
<span style="color: #000000;">
# По дефолту, экзим отфутболивает все `неквалифицированные` адреса,
# состоящие тока из локальной части. Для того чтобы разрешить такие письма
# определённых хостов используются эти директивы:
# для `неквалифицированных` отправителей</span>
#sender_unqualified_hosts = +relay_from_hosts
<span style="color: #000000;">
# для `неквалифицированных` получателей</span>
#recipient_unqualified_hosts = +relay_from_hosts

<span style="color: #000000;"># Если сообщение было не доставлено, то генерится соощение
# об ошибке. Если сообщение об ошибке не удалось доставить
# то оно замораживается на указанный в этом пункте срок,
# после чего снова попытка доставить его. При очередной
# неудаче - сообщение удаляется.</span>
ignore_bounce_errors_after = 1d

<span style="color: #000000;"># Замороженные сообщения, находящиеся в очереди, дольше
# указанного времени удаляются и генерится сообщение
# об ошибке (при условии, что это не было недоставленное
# сообщение об ошибке <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</span>
timeout_frozen_after = 7d

<span style="color: #000000;"># список адресов, через запятую, на которые засылаются
# сообщения о замороженных сообщениях (о замороженых
# уведомлениях о заморозке, сообщения не генерятся. - я
# надеюсь эта строка понятна <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</span>
#freeze_tell = noc@jared.kiev.ua

<span style="color: #000000;"># Через какое время повторять попытку доставки
# замороженного сообщения</span>
auto_thaw = 1h

<span style="color: #000000;"># Приветствие сервера</span>
smtp_banner = "$primary_hostname, ESMTP EXIM $version_number"

<span style="color: #000000;"># Максимальное число одновременных подключений по
# SMTP. Рассчитывать надо исходя из нагрузки на сервер</span>
smtp_accept_max = 500

<span style="color: #000000;"># максимальное число сообщений принимаемое за одно соединение
# от удалённого сервера (или пользователя).</span>
smtp_accept_max_per_connection = 25

<span style="color: #000000;"># максимальное число коннектов с одного хоста</span>
smtp_accept_max_per_host = 20

<span style="color: #000000;"># Если у сообщения много адресатов на удалённых хостах,
# то запускатеся до указанного числа максимально число
# параллельных процессов доставки</span>
remote_max_parallel = 15

<span style="color: #000000;"># при генерации сообщения об ошибке прикладывать
# не всё сообщение, а кусок (от начала) указанного
# размера (иногда полезно и целиком - в таком случае
# просто закомментируйте эту строку)</span>
return_size_limit = 70k

<span style="color: #000000;"># разрешаем неположенные символы в HELO (столкнулся
# с этим случайно - имя фирмы состояло из двух слов
# и какой-то раздолбай домен обозвал my_firme_name
# прям с подчёркиваниями... Виндовые клиенты при
# соединении радостно рапортовали о себе
# `vasya.my_firme_name` ну а экзим их футболил <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</span>
helo_allow_chars = _

<span style="color: #000000;"># Принудительная синхронизация. Если отправитель
# торопится подавать команды, не дождавшись ответа,
# то он посылается далеко и надолго <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Немного,
# спам режется.</span>
smtp_enforce_sync = true

<span style="color: #000000;"># Выбираем, что мы будем логировать
# + - писать в логи,
# - - Не писать в логи.
# +all_parents - все входящие?
# +connection_reject - разорваные соединения
# +incoming_interface - интерфейс (реально - IP)
# +lost_incoming_connections - потеряные входящие
# соединения
# +received_sender - отправитель
# +received_recipients - получатель
# +smtp_confirmation - подтверждения SMTP?
# +smtp_syntax_error - ошибки синтаксиса SMTP
# +smtp_protocol_error - ошибки протокола SMTP
# -queue_run - работа очереди (замороженные мессаги)
#log_selector = \
#       +all \
#       -incoming_port \
#       -incoming_interface \
#       -arguments \
#       -smtp_connection \
#       -lost_incoming_connection \
#       -queue_run
</span>log_selector =  +subject \
                +all_parents \
                +lost_incoming_connection \
                +received_sender \
                +received_recipients \
                +smtp_confirmation \
                +smtp_syntax_error \
                +smtp_protocol_error \
                -queue_run

<span style="color: #000000;"># Системный фильтр, тут можно помечать спам и вообще делать с письмами много чего интересного</span>
system_filter                   = /usr/local/etc/exim/system-filter
system_filter_pipe_transport    = address_pipe
system_filter_user              = exim
system_filter_group             = mail</pre>
<p>110.greylist.conf:</p>
<pre><span style="color: #000000;"># Настройки грейлистинга

# Изначальная задержка после первой попытки отправить письмо</span>
GREYLIST_INITIAL_DELAY = 10 MINUTE

<span style="color: #000000;"># Время жизни серой записи после первой попытки отправить письмо</span>
GREYLIST_INITIAL_LIFETIME = 4 HOUR

<span style="color: #000000;"># Время жизни белой записи</span>
GREYLIST_WHITE_LIFETIME = 36 DAY

<span style="color: #000000;"># Уже не помню, что оно такое, но было нулем <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> )</span>
GREYLIST_BOUNCE_LIFETIME = 0 HOUR

<span style="color: #000000;"># Названия грейлистовых таблиц</span>
GREYLIST_TABLE=exim_greylist
GREYLIST_LOG_TABLE=exim_greylist_log

<span style="color: #000000;"># Настройки логгирования грейлистов</span>
GREYLIST_LOG_ENABLED=no

.ifdef USE_GREYLIST
# database macros
GREYLIST_TEST = SELECT CASE \
   WHEN now() &gt; block_expires \
   OR relay_ip = '127.0.0.1' \
   THEN "accepted"\
   ELSE "deferred" \
 END AS result, id \
 FROM GREYLIST_TABLE \
 WHERE (now() &lt; record_expires) \
   AND (relay_ip    = '${quote_mysql:$sender_host_address}' \
        OR (type='MANUAL' \
            AND (    relay_ip IS NULL \
                  OR relay_ip = substring('${quote_mysql:$sender_host_address}',1,length(relay_ip)) \
                ) \
           ) \
       ) \
 ORDER BY result DESC LIMIT 1

GREYLIST_ADD = INSERT INTO GREYLIST_TABLE \
  (relay_ip, block_expires, \
   record_expires, create_time, type) \
 VALUES ( '${quote_mysql:$sender_host_address}', \
  DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_DELAY), \
  DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_LIFETIME), \
  now(), \
  'AUTO' \
)

GREYLIST_DEFER_HIT = UPDATE GREYLIST_TABLE \
                     SET blockcount=blockcount+1 \
                     WHERE id = $acl_m9

GREYLIST_OK_COUNT = UPDATE GREYLIST_TABLE \
                    SET passcount=passcount+1 \
                    WHERE id = $acl_m9

GREYLIST_OK_NEWTIME = UPDATE GREYLIST_TABLE \
                      SET record_expires = DATE_ADD(now(), INTERVAL GREYLIST_WHITE_LIFETIME) \
                      WHERE id = $acl_m9 AND type='AUTO'

GREYLIST_OK_BOUNCE = UPDATE GREYLIST_TABLE \
                     SET record_expires = DATE_ADD(now(), INTERVAL GREYLIST_BOUNCE_LIFETIME) \
                     WHERE id = $acl_m9 AND type='AUTO'

GREYLIST_LOG = INSERT INTO GREYLIST_LOG_TABLE \
               (listid, timestamp, kind) \
               VALUES ($acl_m9, now(), '$acl_m8')

GREYLIST_CHECK = SELECT greylist from domains where domain = '$domain'

.endif</pre>
<p>200.acl-greylist.conf:</p>
<pre><span style="color: #000000;"># Если для домена значение поля greylist=0, не проверяем вообще</span>
deny    condition       = ${if &lt;{${lookup mysql{GREYLIST_CHECK}}}{1}}

<span style="color: #000000;"># Выставляем внутренние переменные для грейлиста</span>
warn    set acl_m8      = ${lookup mysql{GREYLIST_TEST}{$value}{result=unknown}}
        set acl_m9 = ${extract{id}{$acl_m8}{$value}{-1}}
        set acl_m8 = ${extract{result}{$acl_m8}{$value}{unknown}}

<span style="color: #000000;"># Проверяем, знаем ли такой хост, если нет - вносим в серый список</span>
accept  condition = ${if eq{$acl_m8}{unknown}{1}}
        condition = ${lookup mysql{GREYLIST_ADD}{yes}{no}}

<span style="color: #000000;"># Пишем в лог</span>
.ifdef GREYLIST_LOG_ENABLED
warn    condition = ${lookup mysql{GREYLIST_LOG}}
.endif

<span style="color: #000000;"># Проверка на повторную отправку до перехода в белый список</span>
accept  condition = ${if eq{$acl_m8}{deferred}{1}}
        condition = ${lookup mysql{GREYLIST_DEFER_HIT}{yes}{yes}}

warn    condition = ${lookup mysql{GREYLIST_OK_COUNT}}

<span style="color: #000000;"># use a warn verb to set a new expire time on automatic records,
# but only if the mail was not a bounce, otherwise set to now().</span>
warn    !senders = : postmaster@*
        condition = ${lookup mysql{GREYLIST_OK_NEWTIME}}

warn    senders = : postmaster@*
        condition = ${lookup mysql{GREYLIST_OK_BOUNCE}}

deny</pre>
<p>400.acl-check-rcpt-syntax.conf:</p>
<pre><span style="color: #000000;"># принимать сообщения которые пришли с локалхоста, не по TCP/IP</span>
accept  hosts = :

<span style="color: #000000;"># Запрещаем письма содержащие в локальной части
# символы @; %; !; /; |. Учтите, если у вас было
# `percent_hack_domains` то % надо убрать.
# Проверяются локальные домены</span>
deny    message         = Reject: incorrect symbol in address
        log_message     = REJECT: incorrect symbol in address
        domains         = +local_domains
        local_parts     = ^[.] : ^.*[@%!/|]
        delay           = 30s

<span style="color: #000000;"># Проверяем недопустимые символы для нелокальных получателей:</span>
deny    message         = Reject: incorrect symbol in address
        log_message     = REJECT: incorrect symbol in address
        domains         = !+local_domains
        local_parts     = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
        delay           = 30s

<span style="color: #000000;"># Принимаем почту для постмастеров локальных доменов без
# проверки отправителя (я закомментировал, т.к. это -
# основной источник спама на мой ящик).
</span>#  accept  local_parts   = postmaster
#  domains       = +local_domains

<span style="color: #000000;"># Запрещщаем, если невозможно проверить отправителя
# (отсутствует в списке локальных пользователей)
# У себя я это закоментил, по причине, что некоторые
# железяки (принтеры, &amp; etc) и программы (Касперский, DrWEB)
# умеют слать почту, в случае проблем но не умеют ставить
# нужного отправителя. Такие письма эта проверка не пускает.</span>
#  require verify        = sender

<span style="color: #000000;"># Запрещщаем тех, кто не обменивается приветственными
# сообщениями (HELO/EHLO)</span>
deny    condition       = ${if eq{$sender_helo_name}{}{yes}{no}}
        message         = Reject: HELO/EHLO require by SMTP RFC
        log_message     = REJECT: HELO/EHLO require by SMTP RFC
        delay           = 30s

<span style="color: #000000;"># Принимаем сообщения от тех, кто аутентифицировался:
</span>accept  authenticated = *

<span style="color: #000000;"># Рубаем нах, тех, кто подставляет свой IP в HELO</span>
deny    condition       = ${if isip{$sender_helo_name}{yes}{no}}
        hosts           = !+relay_from_hosts:*
        message         = Reject: We don't allow domain literals, many spam...
        log_message     = REJECT: We don't allow domain literals, many spam...
        delay           = 30s

<span style="color: #000000;"># Рубаем хело с нашим именем</span>
deny    condition       = ${if match_domain{$sender_helo_name} \
                          {$primary_hostname:+local_domains:+relay_to_domains} \
                          {true}{false}}
        message         = Reject: Message was delivered by ratware - own
        log_message     = REJECT: remote host used our name in HELO/EHLO.
        delay   = 30s

<span style="color: #000000;"># Рубаем недопустимые символы в helo</span>
deny    condition       = ${if match{$sender_helo_name}{\N_\N}{yes}{no}}
        message         = Reject: Invalid symbols in HELO
        log_message     = REJECT: Invalid symbols in HELO
        hosts           = !127.0.0.1 : !localhost : !+relay_from_hosts : *

<span style="color: #000000;"># Ограничения эксчейнджа - юзер не может начинаться/заканчиваться точкой.</span>
deny    message         = Reject: Invalid address
        log_message     = REJECT: Dot-starting address
        senders         = \N^\.|\.@\N</pre>
<p>410.acl-check-rcpt-spam.conf:</p>
<pre><span style="color: #000000;">#  # Вводим переменную acl_m0 - в ней будет счётчик,
#  # сколько очков спамерских насчиталось...</span>
 warn    set acl_m0    = 0

<span style="color: #000000;"># Проверяем соответствие HELO и обратной записи DNS для севера:</span>
warn    condition       = ${if !eq{$sender_helo_name}{$sender_host_name}{yes}{no}}
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+20}

<span style="color: #000000;"># Смотрим, нашлась ли обратная запись для этого хоста</span>
warn    condition       = ${if eq{$host_lookup_failed}{1}{yes}{no}}
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+30}

<span style="color: #000000;"># Считем число точек или дефисов в доменном имени. (больше 5 = +40 очков)</span>
warn    condition       = ${if match{$sender_host_name} \
 {\N((?&gt;\w+[\.|\-]){5,})\N}{yes}{no}}
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+40}

<span style="color: #000000;"># Проверяем длину обратного почтовго адреса - пследнее время повадились
# слать с безумными обратными адресами типа Fulbrightbackstage@absacargo.com,
# damsel'stailpipe`s@abbeywindows.co.uk и т.п.</span>
warn    condition       = ${if &gt;{${strlen:$sender_address}}{25}{yes}{no}}
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+10}

<span style="color: #000000;"># Добавляем очков за всякие dialup хосты</span>
warn    condition       = ${lookup{$sender_host_name} \
 wildlsearch{/usr/local/etc/exim/dialup_hosts} \
 {yes}{no}}
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+60}

<span style="color: #000000;"># Проверяем счётчик получателей в письме - нормальные пользователи редко шлют
# сообщения с большим числом получателей, а для крупных почтовых сервисов
# всё сбросится по белому листу серверов, что находится дальше</span>
warn    condition       = ${if &gt;{$recipients_count}{6}{yes}{no}}
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+($recipients_count*20)}

<span style="color: #000000;"># Проверяем существование зоны из HELO (на этом правиле огребают очков все
# уродцы с HELO типа 'friends' или 'localhost.localdomain')</span>
warn    condition       = ${if !eq{${lookup mysql{SELECT 1 FROM \
 `list_top_level_domains` WHERE `zone` = \
 LCASE(CONCAT('.', SUBSTRING_INDEX( \
 '${quote_mysql:$sender_helo_name}', \
 '.', -1)))}}}{1}{yes}{no}}
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+150}

<span style="color: #000000;"># Добавляем очки, если spf не соответствует</span>
warn    spf             = fail
 hosts           = !+relay_from_hosts : *
 set acl_m0      = ${eval:$acl_m0+60}

<span style="color: #000000;"># Устанавливаем переменную, которая видна между ACL-ями</span>
warn    set acl_c_spam = $acl_m0</pre>
<p>420.acl-check-rcpt-end.conf:</p>
<pre><span style="color: #000000;"># Пропускаем письма, если хост или отправитель в белом списке</span>
warn    log_message     = WHITELISTED: host
 hosts           = +whitelist_hosts

warn    log_message     = WHITELISTED: sender
 senders         = +whitelist_sender

warn    set acl_m5      = $local_part@$domain

accept  hosts           = +whitelist_hosts

accept  senders         = +whitelist_sender

<span style="color: #000000;"># Задержка. Режется довольно много не-MTA - спамерских скриптиков.</span>
 warn
 set acl_c0      = 15s

<span style="color: #000000;"># Вычисляем задержку на основании насчитанных за спам очков:</span>
 warn
 condition       = ${if !eq{$acl_m0}{0}{yes}{no}}
 condition       = ${if &gt;{$acl_m0}{150}{yes}{no}}
 set acl_c0      = ${eval:$acl_m0/10}s

 warn
<span style="color: #000000;"> # ставим задержку в 0 секунд своим хостам</span>
 hosts = +relay_from_hosts
 set acl_c0      = 0s

 warn
 delay           = $acl_c0

<span style="color: #000000;"># Рубаем тех, кто в блэк-листах. Серваки перебираются
# сверху вниз, если не хост не найден на первом, то
# запрашивается второй, и т.д. Если не найден ни в одном
# из списка - то почта пропускается.</span>
 deny  message         = "you in blacklist - $dnslist_domain --&gt; \
 $dnslist_text; $dnslist_value"
 log_message     = REJECT: Listed in $dnslist_domain
 hosts           = !+relay_from_hosts
 dnslists        = cbl.abuseat.org : \
 dul.dnsbl.sorbs.net : \
 sbl-xbl.spamhaus.org
 delay           = 30s

<span style="color: #000000;"># Если включены грейлисты - грейлистим всю почту, кроме постмастерской</span>
.ifdef USE_GREYLIST

 defer !senders = : postmaster@*
 acl      = greylist_acl
 message  = GREYLIST: Greylisted, try later.
.endif

<span style="color: #000000;"> # проверяем пользователей из файла альясов (системные)</span>
 accept  domains = +local_domains
 verify  = recipient

<span style="color: #000000;"> # Разрешаем почту от доменов в списке relay_from_hosts</span>
 accept  hosts   = +relay_from_hosts

<span style="color: #000000;"> # приниаем почту для эксчейнджевых доменов</span>
 accept  domains = +relay_to_domains

<span style="color: #000000;"> # Если неподошло ни одно правило - чувак явно ищет
 # открытый релей. Пшёл прочь. <img src='http://jared.kiev.ua/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </span>
 deny          message = "Access deny - this not open relay!"
 log_message     = REJECT: We aren't an open relay
 delay   = 30s</pre>
<p>500.acl-check-data.conf:</p>
<pre><span style="color: #000000;"># Проверяем тело письма

# Распаковываем контейнеры MIME и режем серьезные ошибки</span>
deny    message         = This message contains a MIME error ($demime_reason)
 log_message     = REJECT: Error in MIME
 demime          = *
 condition       = ${if &gt;{$demime_errorlevel}{2}{1}{0}}

<span style="color: #000000;"># Режем типично вирусные расширения файлов</span>
deny    message         = Bad file extension ($found_extension)
 log_message     = REJECT: Bad attachment
 demime          = scr:vbs:bat:lnk:pif

deny    message = Possible CMD file attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = cmd

deny    message = Possible COM file attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = com

deny    message = Possible Microsoft JScript attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = js

deny    message = Possible Windows registry attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = reg

deny    message = Possible compiled Help file-base virus ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = chm

deny    message = Possible SpeedDial attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = cnf

deny    message = Possible Micrsoft HTML archive attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = hta

deny    message = Possible Microsoft Internet Settings attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = ins

deny    message = Possible Windows Explorer Command attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = scf

deny    message = Possible Microsoft Windows Script attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = sct

deny    message = Possible Microsoft VBScript attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = vbs:vbe

deny    message = Possible Microsoft Script Host attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = wsc:wsf:wsh

deny    message = Possible Exchange Shortcut attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = xnk

deny    message = Possible Microsoft Access Shortcut attack ($found_extension)
 log_message     = REJECT: Bad attachment
 demime = mad:maf:mag:mam:maq:mar:mas:mat:mav:maw

<span style="color: #000000;"># Сообщения с NUL-символами</span>
deny    message         = This message contains NUL characters
 log_message     = REJECT: NUL characters!
 condition       = ${if &gt;{$body_zerocount}{0}{1}{0}}

<span style="color: #000000;"># Синтаксис заголовков</span>
deny    message         = Incorrect headers syntax
 log_message     = REJECT: Incorrect header syntax
 hosts           = !+relay_from_hosts:*
 !verify         = header_syntax

<span style="color: #000000;"># Проверки на спам</span>
.ifdef USE_SPAMD

warn set acl_m3 = $acl_c_spam

warn set acl_m5 = $acl_c_lp

warn    message = X-Spam-Report: $spam_report
 spam = exim:true
#        spam = nobody:true

<span style="color: #000000;"># Если SpamAssassin вернул больше +1 балла, добавляем кол-во баллов*20 к общему спам-рейтингу</span>
warn    condition = ${if &gt;{$spam_score_int}{10}{1}{0}}
 set acl_m3 = ${eval:$acl_c_spam+$spam_score_int*2}

<span style="color: #000000;"># На основании общего кол-ва спам-очков и юзерских настроек определяем, помечать письмо спамом или удалять</span>
warn    set acl_m4 = ${lookup mysql{select count(users.on_spamassassin) from users,domains where username = '$acl_m5' \
 and domains.enabled = '1' and users.enabled = '1' and users.sa_tag&gt;0  \
 and users.sa_tag&lt;$acl_m3 and users.domain_id = domains.domain_id}}

warn    set acl_m6 = ${lookup mysql{select count(users.on_spamassassin) from users,domains where username = '$acl_m5' \
 and domains.enabled = '1' and users.enabled = '1' and users.sa_refuse&gt;0 \
 and users.sa_refuse&lt;$acl_m3 and users.domain_id = domains.domain_id}}

warn    condition       = ${if &gt;{$acl_m3}{60}{1}{0}}
 log_message = SPAM: $acl_m3 points

warn    condition       = ${if eq{$acl_m6}{yes}{yes}{no}}
 log_message = SPAM: $acl_m3 points

.endif

<span style="color: #000000;"># Проверяем письмо на вирусы</span>
.ifdef USE_AV
 deny malware = *
 log_message = MALWARE: $malware_name
.endif

<span style="color: #000000;"># Пропускаем остальное</span>
accept</pre>
<p>600.routers.conf:</p>
<pre>dnslookup:
 driver = dnslookup
 domains = ! +local_domains
 transport = remote_smtp
 ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
 no_more

ditch_maxmsgsize:
 driver = redirect
 allow_fail
 condition = ${if &gt;{$message_size}{${lookup mysql{select users.maxmsgsize from users,domains \
 where localpart = '${quote_mysql:$local_part}' \
 and domain = '${quote_mysql:$domain}' \
 and users.maxmsgsize &gt; 0 \
 and users.domain_id=domains.domain_id }{${value}K}fail}} {yes}{no}}
 data = :fail: This user does not accept messages  larger than ${lookup mysql{select users.maxmsgsize from users,domains \
 where localpart = '${quote_mysql:$local_part}' and domain = '${quote_mysql:$domain}' \
 and users.maxmsgsize &gt; 0 and users.domain_id=domains.domain_id}{${value}}fail}Kb.
#  local_part_suffix = -*
#  local_part_suffix_optional
#  retry_use_local_part

ditch_malware:
 driver = redirect
 allow_fail
 data = :blackhole:
 condition = ${if and { {match {$h_X-ACL-Warn:}{.*malware.*}} \
 {eq {${lookup mysql{select users.on_avscan from users,domains \
 where localpart = '${quote_mysql:$local_part}' \
 and domain = '${quote_mysql:$domain}' \
 and users.on_avscan = '1' \
 and users.domain_id=domains.domain_id}}}{1} }} {yes}{no} }

 ditch_spam:
 driver = redirect
 allow_fail
 data = :blackhole:
 condition = ${if &gt;{$spam_score_int}{${lookup mysql{select users.sa_refuse from users,domains \
 where localpart = '${quote_mysql:$local_part}' \
 and domain = '${quote_mysql:$domain}' \
 and users.on_spamassassin = '1' \
 and users.domain_id=domains.domain_id \
 and users.sa_refuse &gt; 0 }{$value}fail}} {yes}{no}}
#  local_part_suffix = -*
#  local_part_suffix_optional
#  retry_use_local_part

ditch_hdrmailer:
 driver = redirect
 allow_fail
 data = :blackhole:
 condition = ${if eq {${lookup mysql{select count(blocklists.block_id) from blocklists,users,domains \
 where blocklists.blockhdr = 'X-Mailer' \
 and LOCATE( blocklists.blockval, '${quote_mysql:$h_x-mailer:}') &gt; 0 \
 and users.localpart = '${quote_mysql:$local_part}' \
 and domains.domain = '${quote_mysql:$domain}' \
 and domains.domain_id=blocklists.domain_id \
 and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
#  local_part_suffix = -*
#  local_part_suffix_optional
 retry_use_local_part

ditch_hdrto:
 driver = redirect
 allow_fail
 data = :blackhole:
 condition = ${if eq {${lookup mysql{select count(blocklists.block_id) from blocklists,users,domains \
 where blocklists.blockhdr = 'To' \
 and LOCATE(blocklists.blockval, '${quote_mysql:$h_to:}')&gt;0 \
 and users.localpart = '${quote_mysql:$local_part}' \
 and domains.domain = '${quote_mysql:$domain}' \
 and domains.domain_id=blocklists.domain_id \
 and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
#  local_part_suffix = -*
#  local_part_suffix_optional
 retry_use_local_part

ditch_hdrfrom:
 driver = redirect
 allow_fail
 data = :blackhole:
 condition = ${if eq {${lookup mysql{select count(blocklists.block_id) from blocklists,users,domains \
 where blocklists.blockhdr = 'From' \
 and LOCATE( blocklists.blockval, '${quote_mysql:$h_from:}') &gt; 0 \
 and users.localpart = '${quote_mysql:$local_part}' \
 and domains.domain = '${quote_mysql:$domain}' \
 and domains.domain_id=blocklists.domain_id \
 and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
#  local_part_suffix = -*
#  local_part_suffix_optional
 retry_use_local_part

ditch_hdrsubject:
 driver = redirect
 allow_fail
 data = :blackhole:
 condition = ${if eq {${lookup mysql{select count(blocklists.block_id) from blocklists,users,domains \
 where blocklists.blockhdr = 'Subject' \
 and LOCATE( blocklists.blockval, '${quote_mysql:$h_subject:}') &gt; 0 \
 and users.localpart = '${quote_mysql:$local_part}' \
 and domains.domain = '${quote_mysql:$domain}' \
 and domains.domain_id=blocklists.domain_id \
 and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
#  local_part_suffix = -*
#  local_part_suffix_optional
 retry_use_local_part

virtual_vacation:
 driver = accept
 condition = ${if and { {!match {$h_precedence:}{(?i)junk|bulk|list}} \
 {eq {${lookup mysql{select users.on_vacation from users,domains \
 where localpart = '${quote_mysql:$local_part}' \
 and domain = '${quote_mysql:$domain}' \
 and users.on_vacation = '1' \
 and users.domain_id=domains.domain_id}}}{1} }} {yes}{no} }
 no_verify
 no_expn
 unseen
 transport = virtual_vacation_delivery

virtual_forward:
 driver = redirect
 check_ancestor
 unseen = ${if eq {${lookup mysql{select unseen from users,domains \
 where localpart = '${quote_mysql:$local_part}' \
 and domain = '${quote_mysql:$domain}' \
 and users.on_forward = '1' \
 and users.domain_id=domains.domain_id}}}{1} {yes}{no}}
 data = ${lookup mysql{select forward from users,domains \
 where localpart='${quote_mysql:$local_part}' \
 and domain='${quote_mysql:$domain}' \
 and users.domain_id=domains.domain_id \
 and on_forward = '1'}}
 # We explicitly make this condition NOT forward mailing list mail!
 condition = ${if and { {!match {$h_precedence:}{(?i)junk}} \
 {eq {${lookup mysql{select users.on_forward from users,domains \
 where localpart = '${quote_mysql:$local_part}' \
 and domain = '${quote_mysql:$domain}' \
 and users.on_forward = '1' \
 and users.domain_id=domains.domain_id}}}{1} }} {yes}{no} }

virtual_domains:
 driver = redirect
 allow_fail
 data = ${lookup mysql{select users.smtp from users,domains \
 where localpart = '${quote_mysql:$local_part}' \
 and domain = '${quote_mysql:$domain}' \
 and domains.enabled = '1' \
 and users.enabled = '1' \
 and users.domain_id = domains.domain_id}}
#  local_part_suffix = -*
#  local_part_suffix_optional
 retry_use_local_part
 file_transport = virtual_delivery
 reply_transport = address_reply
 pipe_transport = address_pipe

.include /usr/local/etc/exim/610.routers-groups.conf

virtual_domains_catchall:
 driver = redirect
 allow_fail
 data = ${lookup mysql{select users.smtp from users,domains where localpart = '*' \
 and domain = '${quote_mysql:$domain}' \
 and users.domain_id = domains.domain_id}}
 retry_use_local_part
 file_transport = virtual_delivery
 reply_transport = address_reply
 pipe_transport = address_pipe_catchall

virtual_domain_alias:
 driver = redirect
 allow_fail
 data = ${lookup mysql{select concat('${quote_mysql:$local_part}@', domains.domain) \
 from domains,domainalias where domainalias.alias = '${quote_mysql:$domain}' \
 and domainalias.domain_id = domains.domain_id}}
 retry_use_local_part</pre>
<p>610.routers-groups.conf</p>
<pre><span style="color: #000000;"># Группа - это список пользователей
#
# Если группа объявлена публичной, кто угодно из интернета может писать ей
# Иначе только члены группы
#
# Если не член непубличной группы пишет в нее, он получит "550 Unknown user"
</span>virtual_dom_groups:
  driver = redirect
  allow_fail
  senders = ${if eq{Y}{${lookup mysql{select g.is_public \
                                      from groups g, domains d \
                                      where d.enabled = '1' and d.domain = '${quote_mysql:$domain}' and \
                                            d.domain_id = g.domain_id and g.enabled = '1' and \
                                            g.name = '${quote_mysql:$local_part}'}}} \
                 {$sender_address} \
                 {${lookup mysql{select u.username \
                                 from domains d, groups g, group_contents c, users u \
                                 where d.enabled = '1' and d.domain = '${quote_mysql:$domain}' and \
                                       d.domain_id = g.domain_id and g.name = '${quote_mysql:$local_part}' and \
                                       g.enabled = '1' and \
                                       g.is_public = 'N' and c.member_id = u.user_id and \
                                       d.domain_id = u.domain_id and u.enabled = '1' \
                                       and u.username = '${quote_mysql:$sender_address}' }}}}
  data = ${lookup mysql{ \
            select u.username \
            from domains d, groups g, group_contents c, users u \
            where d.enabled     = '1'           and \
                  d.domain      = '${quote_mysql:$domain}'   and \
                  d.domain_id   = g.domain_id   and \
                  g.enabled     = '1'           and \
                  g.id          = c.group_id    and \
                  c.member_id   = u.user_id     and \
                  d.domain_id   = u.domain_id   and \
                  u.enabled     = '1'           and \
                  g.name        = '${quote_mysql:$local_part}'} }
  local_part_suffix = -*
  local_part_suffix_optional
  retry_use_local_part
  reply_transport = address_reply
  pipe_transport = address_pipe</pre>
<p>700.transports.conf:</p>
<pre>remote_smtp:
  driver = smtp
  interface = MY_IP

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

virtual_delivery:
  driver = appendfile
  envelope_to_add
  return_path_add
  mode = 0600
  maildir_format = true
  create_directory = true
  directory = ${lookup mysql{select smtp from users,domains \
                where localpart = '${quote_mysql:$local_part}' \
                and domain = '${quote_mysql:$domain}' \
                and users.domain_id = domains.domain_id}}
  user = ${lookup mysql{select users.uid  from users,domains \
                where localpart = '${quote_mysql:$local_part}' \
                and domain = '${quote_mysql:$domain}' \
                and users.domain_id = domains.domain_id}}
  group = ${lookup mysql{select users.gid from users,domains \
                where localpart = '${quote_mysql:$local_part}' \
                and domain = '${quote_mysql:$domain}' \
                and users.domain_id = domains.domain_id}}
  quota = ${lookup mysql{select users.quota from users,domains \
                where localpart = '${quote_mysql:$local_part}' \
                and domain = '${quote_mysql:$domain}' \
                and users.domain_id = domains.domain_id}{${value}M}}
  quota_is_inclusive = false
  #quota_size_regex = ,S=(\d+):
  quota_warn_threshold = 75%
  maildir_use_size_file = false
  quota_warn_message = "To: $local_part@$domain\n\
                        Subject: Mailbox quota warning\n\n\
                        This message was automatically generated by the mail delivery software.\n\n\
                        You are now using over 75% of your allocated mail storage quota.\n\n\
                        If your mailbox fills completely, further incoming messages will be automatically\n\
                        returned to their senders.\n\n\
                        Please take note of this and remove unwanted mail from your mailbox.\n"

virtual_vacation_delivery:
  driver   = autoreply
  from     = "${local_part}@${domain}"
  to       = ${sender_address}
  subject  = "Autoreply from ${local_part}@${domain}"
  text     = ${lookup mysql{select vacation from users,domains \
                where domain='${quote_mysql:$domain}' \
                and localpart='${quote_mysql:$local_part}' \
                and users.domain_id=domains.domain_id}}

mailman_transport:
  driver = pipe
  command = MAILMAN_WRAP \
            '${if def:local_part_suffix \
                  {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
                  {post}}' \
            $local_part
  current_directory = MAILMAN_HOME
  home_directory = MAILMAN_HOME
  user = MAILMAN_USER
  group = MAILMAN_GROUP

address_pipe:
  driver = pipe
  return_output
  user = ${lookup mysql{select users.uid from users,domains where localpart = '${quote_mysql:$local_part}' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}}
  group = ${lookup mysql{select users.gid from users,domains where localpart = '${quote_mysql:$local_part}' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}}

address_pipe_catchall:
  driver = pipe
  return_output
  user = ${lookup mysql{select users.uid from users,domains where localpart = '*' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}}
  group = ${lookup mysql{select users.gid from users,domains where localpart = '*' and domain = '${quote_mysql:$domain}' and users.domain_id = domains.domain_id}}

address_pipe_local:
  driver = pipe
  return_output

address_file:
  driver = appendfile
  delivery_date_add
  envelope_to_add
  return_path_add

address_directory:
    driver = appendfile
    maildir_format

address_reply:
  driver = autoreply</pre>
<p>800.retry.conf:</p>
<pre>begin retry

# Domain               Error       Retries
# ------               -----       -------

*                      *           F,2h,15m; G,16h,1h,1.5; F,14d,6h</pre>
<p>900.authenticators.conf:</p>
<pre>plain_login:
        driver = plaintext
        public_name = PLAIN
        server_condition = ${lookup mysql{SELECT '1' FROM users \
                                WHERE username = '${quote_mysql:$2}' \
                                AND clear = '${quote_mysql:$3}'} {yes}{no}}
        server_set_id = $2

fixed_login:
        driver = plaintext
        public_name = LOGIN
        server_prompts = "Username:: : Password::"
        server_condition = ${lookup mysql{SELECT '1' FROM users \
                                WHERE username = '${quote_mysql:$1}' \
                                AND clear = '${quote_mysql:$2}'} {yes}{no}}
        server_set_id = $1

fixed_cram:
        driver = cram_md5
        public_name = CRAM-MD5
        server_secret = ${lookup mysql{SELECT clear FROM users \
                                WHERE username = '${quote_mysql:$1}'}{$value}fail}
        server_set_id = $1</pre>
<p>dialup_hosts:</p>
<pre># dialup hosts
^\.*dsl\.*
^\.*dialup\.*
^\.*dialin\.*
^\.*pool\.*
^\.*peer\.*
^\.*dhcp\.*
^\.*dynamic\.*
^\.*cable\.*
^\.*ppp\.*

# expressions for digit in hosts
^\d+[-\.]\d+[-\.]\d+[-\.]
^\d{5,}

# by ded3axap
^.*([1-9]+)\\-([0-9]+)\\-([0-9]+)\\-([1-9]+).*
^.*([1-9]+).([0-9]+).([0-9]+).([1-9]+).*
^.*pool.*
^.*dial.*
^.*dyn.*
^.*ppp.*
^.*fbx.*
^.*cable.*
^.*dsl.*
^.*dynamic.*
^.*fibertel.*
^.*broadband.*
^.*hsd1.*
^.*telecable.*
^.*dhcp.*
^.*kabel.*
^.*client.*
^.*in-addr.*
^.*user.*
^.*cpe.*
^.*tampabay.*
^.*phx1.*
^.*static.*
^.*rev.*
^.*speedy.*
^.*genericrev.*
^.*cdma.*
^.*catv.*
^.*customer.*

# optional - by ded3axap
^.*rima-tde\\.net
^.*comcast\\.net
^.*pppoe\\.mtu-net\\.ru
^.*proxad\\.net
^.*bezeqint\\.net
^.*arcor-ip\\.net
^.*novis\\.pt
^.*rr\\.com
^.*verizon\\.net
^.*chello\\.nl
^.*ono\\.com
^.*t-dialin\\.net
^.*telenet\\.be
^.*virtua.com\\.br
^.*veloxzone.com\\.br
^.*tpnet\\.pl
^.*com\\.au
^.*asianet\\.co\\.th
^.*interbusiness\\.it
^.*webandnetworksolutions\\.com
^.*xtra.co\\.nz
^.*atlanticbb\\.net
^.*sinor\\.ru
^.*tiscali\\.fr
^.*wanadoo\\.fr
^.*pacbell\\.net
^.*prodigy\\.net
^.*charter\\.com
^.*barak-online\\.net
^.*qwest\\.net
^.*cm\\.vtr\\.net
^.*link\\.com\\.eg
^.*t-ipconnect\\.de
^.*mindspring\\.com
^.*telesp\\.net\\.br
^.*home\\.nl
^.*cable\\.ntl\\.com
^.*netvision\\.net\\.il
^.*btcentralplus\\.com
^.*surewest\\.net
^.*anteldata\\.net\\.uy
^.*mm\\.pl
^.*euskaltel\\.es
^.*satnet\\.net
^.*kabelbw\\.de
^.*skylink\\.ru
^.*consumerpcinc\\.com
^.*yourhostingaccount\\.com</pre>
<p>system-filter:</p>
<pre>logfile /var/log/exim/mainlog

if $acl_c_spam matches ^\\d+
then
<span style="color: #000000;">        # Строим новую тему письма - если спам
        # Проверяем содержимое переменной со счётчиком спамерских очков.
</span>        headers add "X-Spam-score: $acl_m3"

 <span style="color: #000000;">       # рихтуем хедеры
</span>        if $acl_m4 is above 0
        then
                headers add "Old-Subject: $h_subject:"
                headers remove "Subject"
                headers add "Subject: *SPAM* [$acl_m3 points] $h_old-subject:"
                headers add "X-Spam: YES"
<span style="color: #000000;">                # Старый заголовок оставляем, на всякий случай
</span>                #headers remove "Old-Subject"
        endif

        if $acl_m6 is above 0
        then
                fail text "Scored too much spam points"
                logwrite "SPAM: Spam count = $acl_m3"
        endif
endif</pre>
<p>whitelist-hosts:</p>
<pre>127.0.0.1/32</pre>
<p>whitelist-sender:</p>
<pre>support@microsoft.com</pre>
<p>Создаем базу данных, заливаем дамп:</p>
<pre>CREATE TABLE IF NOT EXISTS `blocklists` (
 `block_id` int(10) unsigned NOT NULL auto_increment,
 `domain_id` mediumint(8) unsigned NOT NULL default '0',
 `user_id` int(10) unsigned default NULL,
 `blockhdr` varchar(192) NOT NULL default '',
 `blockval` varchar(192) NOT NULL default '',
 `color` varchar(8) NOT NULL default '',
 PRIMARY KEY  (`block_id`)
) TYPE=MyISAM ;

CREATE TABLE IF NOT EXISTS `domainalias` (
 `domain_id` mediumint(8) unsigned NOT NULL default '0',
 `alias` varchar(64) default NULL
) TYPE=MyISAM;

CREATE TABLE IF NOT EXISTS `domains` (
 `domain_id` mediumint(8) unsigned NOT NULL auto_increment,
 `domain` varchar(64) NOT NULL default '',
 `maildir` varchar(128) NOT NULL default '',
 `uid` smallint(5) unsigned NOT NULL default '1002',
 `gid` smallint(5) unsigned NOT NULL default '6',
 `max_accounts` int(10) unsigned NOT NULL default '0',
 `quotas` int(10) unsigned NOT NULL default '0',
 `type` varchar(5) default NULL,
 `avscan` tinyint(1) NOT NULL default '0',
 `blocklists` tinyint(1) NOT NULL default '0',
 `complexpass` tinyint(1) NOT NULL default '0',
 `enabled` tinyint(1) NOT NULL default '1',
 `mailinglists` tinyint(1) NOT NULL default '0',
 `maxmsgsize` mediumint(8) unsigned NOT NULL default '0',
 `pipe` tinyint(1) NOT NULL default '0',
 `spamassassin` tinyint(1) NOT NULL default '0',
 `greylist` tinyint(4) NOT NULL default '1',
 `sa_tag` smallint(5) unsigned NOT NULL default '0',
 `sa_refuse` smallint(5) unsigned NOT NULL default '0',
 PRIMARY KEY  (`domain_id`),
 UNIQUE KEY `domain` (`domain`),
 KEY `domain_id` (`domain_id`),
 KEY `domains` (`domain`)
) TYPE=MyISAM ;

INSERT INTO `domains` (`domain_id`, `domain`, `maildir`, `uid`, `gid`, `max_accounts`, `quotas`, `type`, `avscan`, `blocklists`, `complexpass`, `enabled`, `mailinglists`, `maxmsgsize`, `pipe`, `spamassassin`, `greylist`, `sa_tag`, `sa_refuse`) VALUES
(1, 'admin', '', 1002, 6, 0, 0, NULL, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0);

CREATE TABLE IF NOT EXISTS `exim_greylist` (
 `id` bigint(20) NOT NULL auto_increment,
 `relay_ip` varchar(80) default NULL,
 `block_expires` datetime NOT NULL default '0000-00-00 00:00:00',
 `record_expires` datetime NOT NULL default '9999-12-31 23:59:59',
 `create_time` datetime NOT NULL default '0000-00-00 00:00:00',
 `type` enum('AUTO','MANUAL') NOT NULL default 'MANUAL',
 `passcount` bigint(20) NOT NULL default '0',
 `blockcount` bigint(20) NOT NULL default '0',
 PRIMARY KEY  (`id`)
) TYPE=MyISAM ;

CREATE TABLE IF NOT EXISTS `exim_greylist_log` (
 `id` bigint(20) NOT NULL auto_increment,
 `listid` bigint(20) NOT NULL default '0',
 `timestamp` datetime NOT NULL default '0000-00-00 00:00:00',
 `kind` enum('deferred','accepted') NOT NULL default 'deferred',
 PRIMARY KEY  (`id`)
) TYPE=MyISAM ;

CREATE TABLE IF NOT EXISTS `groups` (
 `id` int(10) NOT NULL auto_increment,
 `domain_id` mediumint(8) unsigned NOT NULL,
 `name` varchar(64) NOT NULL,
 `is_public` char(1) NOT NULL default 'Y',
 `enabled` tinyint(1) NOT NULL default '1',
 PRIMARY KEY  (`id`),
 UNIQUE KEY `group_name` (`domain_id`,`name`)
) TYPE=MyISAM ;

CREATE TABLE IF NOT EXISTS `group_contents` (
 `group_id` int(10) NOT NULL,
 `member_id` int(10) NOT NULL,
 PRIMARY KEY  (`group_id`,`member_id`)
) TYPE=MyISAM;

CREATE TABLE IF NOT EXISTS `list_top_level_domains` (
 `unic_id` int(3) NOT NULL auto_increment,
 `zone` varchar(15) binary NOT NULL default '',
 `description` varchar(64) binary NOT NULL default '',
 PRIMARY KEY  (`unic_id`),
 UNIQUE KEY `zone` (`zone`)
) TYPE=MyISAM ;

INSERT INTO `list_top_level_domains` (`unic_id`, `zone`, `description`) VALUES
(1, '.ac', 'Ascension Island'),
(2, '.ad', 'Andorra'),
(3, '.ae', 'United Arab Emirates'),
(4, '.af', 'Afghanistan'),
(5, '.ag', 'Antigua and Barbuda'),
(6, '.ai', 'Anguilla'),
(7, '.al', 'Albania'),
(8, '.am', 'Armenia'),
(9, '.an', 'Netherlands Antilles'),
(10, '.ao', 'Angola'),
(11, '.aq', 'Antarctica'),
(12, '.ar', 'Argentina'),
(13, '.as', 'American Samoa'),
(14, '.at', 'Austria'),
(15, '.au', 'Australia'),
(16, '.aw', 'Aruba'),
(17, '.ax', 'Aland Islands'),
(18, '.az', 'Azerbaijan'),
(19, '.ba', 'Bosnia and Herzegovina'),
(20, '.bb', 'Barbados'),
(21, '.bd', 'Bangladesh'),
(22, '.be', 'Belgium'),
(23, '.bf', 'Burkina Faso'),
(24, '.bg', 'Bulgaria'),
(25, '.bh', 'Bahrain'),
(26, '.bi', 'Burundi'),
(27, '.bj', 'Benin'),
(28, '.bm', 'Bermuda'),
(29, '.bn', 'Brunei Darussalam'),
(30, '.bo', 'Bolivia'),
(31, '.br', 'Brazil'),
(32, '.bs', 'Bahamas'),
(33, '.bt', 'Bhutan'),
(34, '.bv', 'Bouvet Island'),
(35, '.bw', 'Botswana'),
(36, '.by', 'Belarus'),
(37, '.bz', 'Belize'),
(38, '.ca', 'Canada'),
(39, '.cc', 'Cocos (Keeling) Islands'),
(40, '.cd', 'Congo, The Democratic Republic o'),
(41, '.cf', 'Central African Republic'),
(42, '.cg', 'Congo, Republic of'),
(43, '.ch', 'Switzerland'),
(44, '.ci', 'Cote d''Ivoire'),
(45, '.ck', 'Cook Islands'),
(46, '.cl', 'Chile'),
(47, '.cm', 'Cameroon'),
(48, '.cn', 'China'),
(49, '.co', 'Colombia'),
(50, '.cr', 'Costa Rica'),
(51, '.cu', 'Cuba'),
(52, '.cv', 'Cape Verde'),
(53, '.cx', 'Christmas Island'),
(54, '.cy', 'Cyprus'),
(55, '.cz', 'Czech Republic'),
(56, '.de', 'Germany'),
(57, '.dj', 'Djibouti'),
(58, '.dk', 'Denmark'),
(59, '.dm', 'Dominica'),
(60, '.do', 'Dominican Republic'),
(61, '.dz', 'Algeria'),
(62, '.ec', 'Ecuador'),
(63, '.ee', 'Estonia'),
(64, '.eg', 'Egypt'),
(65, '.eh', 'Western Sahara'),
(66, '.er', 'Eritrea'),
(67, '.es', 'Spain'),
(68, '.et', 'Ethiopia'),
(69, '.eu', 'European Union'),
(70, '.fi', 'Finland'),
(71, '.fj', 'Fiji'),
(72, '.fk', 'Falkland Islands (Malvinas)'),
(73, '.fm', 'Micronesia, Federated States of'),
(74, '.fo', 'Faroe Islands'),
(75, '.fr', 'France'),
(76, '.ga', 'Gabon'),
(77, '.gb', 'United Kingdom'),
(78, '.gd', 'Grenada'),
(79, '.ge', 'Georgia'),
(80, '.gf', 'French Guiana'),
(81, '.gg', 'Guernsey'),
(82, '.gh', 'Ghana'),
(83, '.gi', 'Gibraltar'),
(84, '.gl', 'Greenland'),
(85, '.gm', 'Gambia'),
(86, '.gn', 'Guinea'),
(87, '.gp', 'Guadeloupe'),
(88, '.gq', 'Equatorial Guinea'),
(89, '.gr', 'Greece'),
(90, '.gs', 'South Georgia and the South Sand'),
(91, '.gt', 'Guatemala'),
(92, '.gu', 'Guam'),
(93, '.gw', 'Guinea-Bissau'),
(94, '.gy', 'Guyana'),
(95, '.hk', 'Hong Kong'),
(96, '.hm', 'Heard and McDonald Islands'),
(97, '.hn', 'Honduras'),
(98, '.hr', 'Croatia/Hrvatska'),
(99, '.ht', 'Haiti'),
(100, '.hu', 'Hungary'),
(101, '.id', 'Indonesia'),
(102, '.ie', 'Ireland'),
(103, '.il', 'Israel'),
(104, '.im', 'Isle of Man'),
(105, '.in', 'India'),
(106, '.io', 'British Indian Ocean Territory'),
(107, '.iq', 'Iraq'),
(108, '.ir', 'Iran, Islamic Republic of'),
(109, '.is', 'Iceland'),
(110, '.it', 'Italy'),
(111, '.je', 'Jersey'),
(112, '.jm', 'Jamaica'),
(113, '.jo', 'Jordan'),
(114, '.jp', 'Japan'),
(115, '.ke', 'Kenya'),
(116, '.kg', 'Kyrgyzstan'),
(117, '.kh', 'Cambodia'),
(118, '.ki', 'Kiribati'),
(119, '.km', 'Comoros'),
(120, '.kn', 'Saint Kitts and Nevis'),
(121, '.kp', 'Korea, Democratic People''s Repub'),
(122, '.kr', 'Korea, Republic of'),
(123, '.kw', 'Kuwait'),
(124, '.ky', 'Cayman Islands'),
(125, '.kz', 'Kazakhstan'),
(126, '.la', 'Lao People''s Democratic Republic'),
(127, '.lb', 'Lebanon'),
(128, '.lc', 'Saint Lucia'),
(129, '.li', 'Liechtenstein'),
(130, '.lk', 'Sri Lanka'),
(131, '.lr', 'Liberia'),
(132, '.ls', 'Lesotho'),
(133, '.lt', 'Lithuania'),
(134, '.lu', 'Luxembourg'),
(135, '.lv', 'Latvia'),
(136, '.ly', 'Libyan Arab Jamahiriya'),
(137, '.ma', 'Morocco'),
(138, '.mc', 'Monaco'),
(139, '.md', 'Moldova, Republic of'),
(140, '.me', 'Montenegro'),
(141, '.mg', 'Madagascar'),
(142, '.mh', 'Marshall Islands'),
(143, '.mk', 'Macedonia, The Former Yugoslav R'),
(144, '.ml', 'Mali'),
(145, '.mm', 'Myanmar'),
(146, '.mn', 'Mongolia'),
(147, '.mo', 'Macao'),
(148, '.mp', 'Northern Mariana Islands'),
(149, '.mq', 'Martinique'),
(150, '.mr', 'Mauritania'),
(151, '.ms', 'Montserrat'),
(152, '.mt', 'Malta'),
(153, '.mu', 'Mauritius'),
(154, '.mv', 'Maldives'),
(155, '.mw', 'Malawi'),
(156, '.mx', 'Mexico'),
(157, '.my', 'Malaysia'),
(158, '.mz', 'Mozambique'),
(159, '.na', 'Namibia'),
(160, '.nc', 'New Caledonia'),
(161, '.ne', 'Niger'),
(162, '.nf', 'Norfolk Island'),
(163, '.ng', 'Nigeria'),
(164, '.ni', 'Nicaragua'),
(165, '.nl', 'Netherlands'),
(166, '.no', 'Norway'),
(167, '.np', 'Nepal'),
(168, '.nr', 'Nauru'),
(169, '.nu', 'Niue'),
(170, '.nz', 'New Zealand'),
(171, '.om', 'Oman'),
(172, '.pa', 'Panama'),
(173, '.pe', 'Peru'),
(174, '.pf', 'French Polynesia'),
(175, '.pg', 'Papua New Guinea'),
(176, '.ph', 'Philippines'),
(177, '.pk', 'Pakistan'),
(178, '.pl', 'Poland'),
(179, '.pm', 'Saint Pierre and Miquelon'),
(180, '.pn', 'Pitcairn Island'),
(181, '.pr', 'Puerto Rico'),
(182, '.ps', 'Palestinian Territory, Occupied'),
(183, '.pt', 'Portugal'),
(184, '.pw', 'Palau'),
(185, '.py', 'Paraguay'),
(186, '.qa', 'Qatar'),
(187, '.re', 'Reunion Island'),
(188, '.ro', 'Romania'),
(189, '.rs', 'Serbia'),
(190, '.ru', 'Russian Federation'),
(191, '.rw', 'Rwanda'),
(192, '.sa', 'Saudi Arabia'),
(193, '.sb', 'Solomon Islands'),
(194, '.sc', 'Seychelles'),
(195, '.sd', 'Sudan'),
(196, '.se', 'Sweden'),
(197, '.sg', 'Singapore'),
(198, '.sh', 'Saint Helena'),
(199, '.si', 'Slovenia'),
(200, '.sj', 'Svalbard and Jan Mayen Islands'),
(201, '.sk', 'Slovak Republic'),
(202, '.sl', 'Sierra Leone'),
(203, '.sm', 'San Marino'),
(204, '.sn', 'Senegal'),
(205, '.so', 'Somalia'),
(206, '.sr', 'Suriname'),
(207, '.st', 'Sao Tome and Principe'),
(208, '.su', 'Soviet Union (being phased out)'),
(209, '.sv', 'El Salvador'),
(210, '.sy', 'Syrian Arab Republic'),
(211, '.sz', 'Swaziland'),
(212, '.tc', 'Turks and Caicos Islands'),
(213, '.td', 'Chad'),
(214, '.tf', 'French Southern Territories'),
(215, '.tg', 'Togo'),
(216, '.th', 'Thailand'),
(217, '.tj', 'Tajikistan'),
(218, '.tk', 'Tokelau'),
(219, '.tl', 'Timor-Leste'),
(220, '.tm', 'Turkmenistan'),
(221, '.tn', 'Tunisia'),
(222, '.to', 'Tonga'),
(223, '.tp', 'East Timor'),
(224, '.tr', 'Turkey'),
(225, '.tt', 'Trinidad and Tobago'),
(226, '.tv', 'Tuvalu'),
(227, '.tw', 'Taiwan'),
(228, '.tz', 'Tanzania'),
(229, '.ua', 'Ukraine'),
(230, '.ug', 'Uganda'),
(231, '.uk', 'United Kingdom'),
(232, '.um', 'United States Minor Outlying Isl'),
(233, '.us', 'United States'),
(234, '.uy', 'Uruguay'),
(235, '.uz', 'Uzbekistan'),
(236, '.va', 'Holy See (Vatican City State)'),
(237, '.vc', 'Saint Vincent and the Grenadines'),
(238, '.ve', 'Venezuela'),
(239, '.vg', 'Virgin Islands, British'),
(240, '.vi', 'Virgin Islands, U'),
(241, '.vn', 'Vietnam'),
(242, '.vu', 'Vanuatu'),
(243, '.wf', 'Wallis and Futuna Islands'),
(244, '.ws', 'Samoa'),
(245, '.ye', 'Yemen'),
(246, '.yt', 'Mayotte'),
(247, '.yu', 'Yugoslavia'),
(248, '.za', 'South Africa'),
(249, '.zm', 'Zambia'),
(250, '.zw', 'Zimbabwe'),
(251, '.com', 'operated by VeriSign Global Registry Services'),
(252, '.net', 'operated by VeriSign Global Registry Services'),
(253, '.biz', 'restricted to businesses'),
(254, '.org', ' intended to serve the noncommercial community, but all are elig'),
(255, '.aero', 'reserved for members of the air-transport industry'),
(256, '.cat', 'reserved for the Catalan linguistic and cultural community'),
(257, '.coop', 'reserved for cooperative associations'),
(258, '.info', 'operated by Afilias Limited'),
(259, '.jobs', 'reserved for human resource managers'),
(260, '.mobi', 'reserved for consumers and providers of mobile products and serv'),
(261, '.muzeum', 'reserved for museums'),
(262, '.name', 'reserved for individuals'),
(263, '.pro', 'restricted to credentialed professionals and related entities'),
(264, '.travel', 'reserved for entities whose primary area of activity is in the t'),
(265, '.edu', 'reserved for postsecondary institutions accredited by an agency '),
(266, '.mil', 'reserved exclusively for the United States Military'),
(267, '.int', 'used only for registering organizations established by internati'),
(268, '.gov', 'reserved exclusively for the United States Government');

CREATE TABLE IF NOT EXISTS `users` (
 `user_id` int(10) unsigned NOT NULL auto_increment,
 `domain_id` mediumint(8) unsigned NOT NULL default '0',
 `localpart` varchar(192) NOT NULL default '',
 `username` varchar(255) NOT NULL default '',
 `clear` varchar(255) default NULL,
 `crypt` varchar(48) default NULL,
 `uid` smallint(5) unsigned NOT NULL default '1002',
 `gid` smallint(5) unsigned NOT NULL default '6',
 `smtp` text,
 `pop` varchar(255) default NULL,
 `type` enum('local','alias','catch','fail','piped','admin','site') NOT NULL default 'local',
 `admin` tinyint(1) NOT NULL default '0',
 `on_avscan` tinyint(1) NOT NULL default '0',
 `on_blocklist` tinyint(1) NOT NULL default '0',
 `on_complexpass` tinyint(1) NOT NULL default '0',
 `on_forward` tinyint(1) NOT NULL default '0',
 `on_piped` tinyint(1) NOT NULL default '0',
 `on_spamassassin` tinyint(1) NOT NULL default '0',
 `on_vacation` tinyint(1) NOT NULL default '0',
 `enabled` tinyint(1) NOT NULL default '1',
 `flags` varchar(16) default NULL,
 `forward` varchar(255) default NULL,
 `unseen` bool default '0',
 `maxmsgsize` mediumint(8) unsigned NOT NULL default '0',
 `quota` int(10) unsigned NOT NULL default '0',
 `realname` varchar(255) default NULL,
 `sa_tag` smallint(5) unsigned NOT NULL default '0',
 `sa_refuse` smallint(5) unsigned NOT NULL default '0',
 `tagline` varchar(255) default NULL,
 `vacation` varchar(255) default NULL,
 PRIMARY KEY  (`user_id`),
 UNIQUE KEY `username` (`localpart`,`domain_id`),
 KEY `local` (`localpart`)
) TYPE=MyISAM ;

INSERT INTO `users` (`user_id`, `domain_id`, `localpart`, `username`, `clear`, `crypt`, `uid`, `gid`, `smtp`, `pop`, `type`, `admin`, `on_avscan`, `on_blocklist`, `on_complexpass`, `on_forward`, `on_piped`, `on_spamassassin`, `on_vacation`, `enabled`, `flags`, `forward`, `maxmsgsize`, `quota`, `realname`, `sa_tag`, `sa_refuse`, `tagline`, `vacation`) VALUES
(1, 1, 'siteadmin', 'siteadmin', '123465', MD5('123465'), 65535, 65535, '', '', 'site', 1, 0, 0, 0, 0, 0, 0, 0, 1, NULL, NULL, 0, 0, 'SiteAdmin', 60, 600, NULL, NULL);</pre>
<p>В дампе предварительно надо поправить значения пользователя и группы, под которыми будет работать Exim (мы раньше их записали, получилось 1002 и 6 соответственно). Останавливаем Sendmail, правим /etc/rc.conf:</p>
<pre># /etc/rc.d/sendmail stop
# echo sendmail_enable=\"NONE\" &gt;&gt; /etc/rc.conf
# echo exim_enable=\"YES\" &gt;&gt; /etc/rc.conf</pre>
<p>И переходим к <a href="http://jared.kiev.ua/2010/01/isp-mailserver-2-clam-assassin/" target="_self">следующей части</a> нашего сетапа.</p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/">Почтовый сервер как у провайдера, часть 1: Exim</a></p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-2-clam-assassin/">Почтовый сервер как у провайдера, часть 2: ClamAV, SpamAssassin, Dovecot</a></p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-3-vexim/">Почтовый сервер как у провайдера, часть 3: Vexim</a></p>
<p class="post-title"><a href="http://jared.kiev.ua/2010/01/isp-mailserver-4-start/">Почтовый сервер как у провайдера, часть 4: взлетаем</a></p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">
<h3 class="r"><a class="l" onmousedown="return rwt(this,'','','res','1','AFQjCNHx6FkTqE_D4QcCXfdoqNwDJZjiXA','&amp;sig2=AnQ-tyhaql6QArpKRWVHpA','0CAsQFjAA')" href="../2010/01/exim-vexim-spamassassin-greylisting-whitelisting/"><em>Exim</em> + <em>Vexim</em> + Spamassassin +  Greylisting + Whitelisting</a></h3>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jared.kiev.ua/2010/01/isp-mailserver-1-exim/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Served from: jared.kiev.ua @ 2012-05-20 01:08:17 -->
