И так, почтовый сервер у нас уже имеется, его настройка описывалась в этой статье. Теперь прикрутим к этому почтовику фильтры. Работать это будет следующим образом: при получении письма postfix отдаёт его amavis, amavis отдаёт письмо clamav для проверки на вирусы, clamav проверяет и говорит свой вердикт, с вирусом письмо или без, если с вирусом то письмо блокируется и ни кому ни каких сообщений не отсылается (нефиг вирусы слать 8-) ), если без вируса письмо передаётся для проверки dspam, dspam даёт заключение спам это или нет, если нет то письмо возвращается postfix для доставки пользователю, если спам то в тему письма добавляется тег говорящий о том что письмо является спамом и возвращается postfix для доставки пользователю. У пользователя в клиенте настроен фильтр который перемещает все письма с тегом спам в отдельную папку. Обучение dspam осуществляется силами пользователей путём пересылки сообщений на специальные ящики spam@example.com для спама и notspam@example.com для не спама. Проверка сообщений на спам и переобучение dspam будет осуществляться от пользователя amavis, в результате база dspam будет общей для всех пользователей.

Для начала необходимо создать два почтовых ящика spam@example.com и notspam@example.com для того чтоб пользователи могли обучать спам фильтр. Можно конечно было и не создавать отдельные почтовые ящики а решить это другими методами, но так проще. Пересылаемое сообщение на адреса spam@example.com и notspam@example.com должно быть в виде вложения, так так сигнатура dspam будет находиться в заголовке сообщения.

Приступаем к настройке.

Все действия в этой статье выполняются от пользователя root.

1. Настройка Amavisd-new

Устанавливаем необходимые пакеты

apt-get install amavisd-new clamav-daemon
apt-get install arj cabextract cpio lha nomarch pax rar unrar unzip zip p7zip unrar-free

Добавим пользователя clamav в группу amavis

adduser clamav amavis

Приступаем к настройке amavis

Редактируем файл /etc/amavis/conf.d/15-content_filter_mode раскоментировав в нём следующие строки

@bypass_virus_checks_maps = (
   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);

@bypass_spam_checks_maps = (
   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);

Теперь редактируем файл /etc/amavis/conf.d/20-debian_defaults

$final_virus_destiny      = D_DISCARD;  # (что делать с письмами содержащими вирус, D_DISCARD -
# блокировать, никаких уведомлений не отсылать)
$final_banned_destiny     = D_BOUNCE;   # (что делать с письмами содержащими запрещённые типы
# вложений, D_ BOUNCE - блокировать, отправить уведомление отправителю письма)
$final_spam_destiny       = D_PASS; # (что делать со спам письмами, разбором спам писем у меня
# занимается thunderbird поэтому D_ PASS — пропустить письмо)
$final_bad_header_destiny = D_PASS;     # (что делать с письмами содержащими не правильные
# заголовки, D_ PASS — пропустить письмо)
$sa_spam_subject_tag = '***SPAM*** ';
$sa_tag_level_deflt  = 10.0;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 10.0; # add 'spam detected' headers at that level
$sa_kill_level_deflt = 50.0; # triggers spam evasive actions
$sa_dsn_cutoff_level = 50;   # spam level beyond which a DSN is not sent

Всё остальное я оставил по умолчанию.

Теперь переходим в каталог /usr/sbin/

cd /usr/sbin/

И редактируем файл amavisd-new Находим в нём строки

@spam_scanners = (
     ['SpamAssassin', 'Amavis::SpamControl::SpamAssassin' ],
  # ['SpamdClient',  'Amavis::SpamControl::SpamdClient' ],
  # ['DSPAM',  'Amavis::SpamControl::ExtProg', $dspam,
  #   [ qw(--stdout --classify --deliver=innocent,spam
  #        --mode=tum --tokenizer=chained,noise
  #        --user), $daemon_user ],
  #   # use option --feature instead of --tokenizer with dspam < 3.8.0
  #   mail_body_size_limit => 64000, score_factor => 0.1,
  # ],
  # ['CRM114', 'Amavis::SpamControl::ExtProg', 'crm',
  #   [ qw(-u /var/amavis/home/.crm114 mailreaver.crm
  #        --dontstore --report_only --stats_only
  #        --good_threshold=10 --spam_threshold=-10) ],
  #   mail_body_size_limit => 65000, score_factor => -0.20,
  # ],
  );

Исходя из этих строк можно сделать вывод что для того чтобы включить dspam достаточно закоментировать строку с SpamAssassin и раскоментировать строки связанные с dspam. Но как оказалось не всё так просто. Переменные $dspam и $daemon_user почему-то оказались пустыми, не смотря на то что значения в conf файлах им присвоены, я не силён в pyton поэтому не стал разбираться в причинах а просто заменил переменные на реальные значения. Также опции которые используются для запуска dspam рассчитаны на то что dspam будет дополнительным фильтром и будет просто анализировать сообщения и отвечать считает он сообщение спамом или нет. В таком режиме нет возможности обучать dspam силами пользователей так как сигнатура dspam не будет вставляться в сообщение. В результате необходимо изменить опции запуска dspam. В конечном итоге выше указанные строки должны иметь вид:

@spam_scanners = (
  # ['SpamAssassin', 'Amavis::SpamControl::SpamAssassin' ],
  # ['SpamdClient',  'Amavis::SpamControl::SpamdClient' ],
     ['DSPAM',  'Amavis::SpamControl::ExtProg', '/usr/bin/dspam',
       [ qw(--stdout --process --deliver=innocent,spam --user), 'amavis' ],
       mail_body_size_limit => 204800, score_factor => 1.0,
     ],
  # ['CRM114', 'Amavis::SpamControl::ExtProg', 'crm',
  #   [ qw(-u /var/amavis/home/.crm114 mailreaver.crm
  #        --dontstore --report_only --stats_only
  #        --good_threshold=10 --spam_threshold=-10) ],
  #   mail_body_size_limit => 65000, score_factor => -0.20,
  # ],
  );

Добавим наш домен в белый список amavis Для этого отредактируем файл /etc/amavis/conf.d/40-policy_banks добавив в него строку example.com' ⇒ 'WHITELIST',

…
example.com' => 'WHITELIST',
} );

2. Настройка DSPAM

Теперь приступаем к настройке Dspam.

На данном этапе существует 2-а способа установки dspam:

1. Установка старой версии 3.6.8 из репозитория ubuntu

2. Установка последней версии 3.9.1-RC1 из исходников

В данной статье я опишу оба способа, выбирайте кому какой больше нравится. Стоит отметить что в последней версии присутствует русифицированный web интерфейс. Остальные различия думаю найдёте сами 8-)

2.1. Установка dspam из репозитория ubuntu

Устанавлмваем необходимые пакеты

apt-get install dspam dspam-webfrontend libdspam7-drv-mysql

В процессе установки вас спросят создавать ли базу для dspam, соглашаемся, необходимо будет указать root пароль от mysql и пароль для пользователя от которого будет работать dspam с mysql.

Переходим в каталог /etc/dspam и приступаем к редактированию dspam.conf Ниже я приведу свой конфиг dspam с некоторыми коментариями

# Домашняя директория dspam, мне нужно было чтоб она была в home вы можете оставить
# поумолчанию, но если меняете не забудьте дать права пользователю и группе dspam
Home /home/dspam
# Драйвер для подключения к базе mysql
StorageDriver /usr/lib/dspam/libmysql_drv.so
# Агент для доставки писем, нам он не понадобиться, так как dspam не будет заниматься доставкой
TrustedDeliveryAgent "/usr/bin/procmail"
# Возвращать ошибку при неудачной доставке
OnFail error
# Доверенные пользователи dspam
Trust root
Trust dspam
Trust mail
Trust mailnull 
Trust smmsp
Trust daemon
# Обязательно добавляем пользователя amavis, иначе amavis не сможет запустить dspam для
# проверки сообщений
Trust amavis
# Режим обучения, teft — обучаться на всех письмах
TrainingMode teft
TestConditionalTraining on
# Один из принципов обработки сообщений, но что он делает сказать не могу, во многих примерах он
# включен
Feature noise
# Включаем поддержку «цепочек», когда учитываются не только отдельные слова, но и
# группы слов
Feature chained
#  Автоматический белый список, после того как от конкретного отправителя пришло N сообщений и
# все они не являются спамом то данный отправитель заносится в белый список и сообщения от него
# не обрабатываются dspam. N поумолчанию равно 10, но можно изменить. Параметр который за
# это отвечает смотреть ниже.
Feature whitelist
# Алгоритм проверки на spam
Algorithm graham burton
PValue graham
# Пользовательские настройки по умолчанию
# При обнаружениии что это spam — добавить тег в тему сообщения
Preference "spamAction=tag"
# Cигнатуру проверки поместить в заголовок письма или внутрь сообщения, в данном случае это не
# имеет ни какого значения т.к. dspam запускается amavis для анализа и в письмо попадут только
# заголовки dspam
Preference "signatureLocation=headers"  # 'message' or 'headers'
# Тег добавляемый в тему сообщения если сообщения классифицировано как спам, этот параметр
# тоже не учитывается в нашем случае тег в тему будет добавлять amavis
Preference "spamSubject=[SPAM]"
# Кол-во не спам сообщений от одного отправителя после которых отправитель заносится в белый
# список
Preference "whitelistThreshold=50"
# Не указывать какой фактор принес сколько очков вероятности спама в заголовке сообщения
Preference "showFactors=off"
# Разрешаем пользователям изменять определенные настройки
AllowOverride trainingMode
AllowOverride spamAction spamSubject
AllowOverride statisticalSedation
AllowOverride enableBNR
AllowOverride enableWhitelist
AllowOverride signatureLocation
AllowOverride showFactors
AllowOverride optIn optOut
AllowOverride whitelistThreshold
# С этими опциями я не разбирался, просто оставил как есть
HashRecMax              98317
HashAutoExtend          on  
HashMaxExtents          0
HashExtentSize          49157
HashMaxSeek             100
HashConnectionCache     10
# Указываем какие заголовки сообщений необходимо игнорировать, проанализируйте сообщения
# которые вам приходят и включите их заголовки в данный список, зачем это нужно читать здесь
# http://kb.etarea.com/2009/10/05/dspam-%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D1%8B-%D0%B8-%D0%BE%D0%B1%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D1%87%D0%B0%D1%81%D1%82%D1%8C-2/

IgnoreHeader X-Spam-Status
IgnoreHeader X-Spam-Scanned
IgnoreHeader X-Virus-Scanned
# Не отсылать сообщения пользователям
Notifications   off
# С этими опциями я не разбирался, оставил как есть
PurgeSignatures 14          # Stale signatures
PurgeNeutral    90          # Tokens with neutralish probabilities
PurgeUnused     90          # Unused tokens
PurgeHapaxes    30          # Tokens with less than 5 hits (hapaxes)
PurgeHits1S     15          # Tokens with only 1 spam hit
PurgeHits1I     15          # Tokens with only 1 innocent hit
LocalMX 127.0.0.1
# Собирать статистику
SystemLog on
UserLog   on
# Параметр Opt. Об этом параметре я расскажу немного по подробней, так как из за него я потерял 
# день прежде чем понял что он виноват в том что dspam не хочет обрабатывать сообщения.
# И так параметр Opt отвечает за то будет или не будет обрабатываться сообщение от данного
# пользователя. Opt принимает два значения in и out.
# Opt in означает что сообщения будут обрабатываться только для тех пользователей для которых
# созданы файлы «имя_пользователя.dspam» в каталоге «home_dspam/opt-in/domain/» в
# случае если опция --user содержит имя пользователя в формате user_name@domain или в каталоге
# «dspam_home/opt-in/local/» в случае если  опция --user содержит имя пользователя в формате
# user_name. К примеру, если Opt установлена в in а --user содержит test@example.com то
# обязательно должен существовать файл «home_dspam/opt-in/example.com/test.dspam» в противном
# случае сообщения от данного пользователя обрабатываться не будут. Данный файл необходимо
# создать самому.
# Opt out означает что сообщения будут обрабатываться от всех пользователей кроме тех для 
# которых созданы файлы «имя_пользователя.nodspam» в каталоге «home_dspam/opt-out/domain/» в
# случае если опция --user содержит имя пользователя в формате user_name@domain или в каталоге
# «dspam_home/opt-in/local/» в случае если  опция --user содержит имя пользователя в формате
# user_name. К примеру, если Opt установлена в out а --user содержит test@example.com то
# обязательно должен существовать файл «home_dspam/opt-out/example.com/test.nodspam» в 
# противном случае сообщения от данного пользователя будут обрабатываться dspam. Данный файл 
# необходимо создать самому.
Opt out 
# Порт на котором работает dspam, обязательно измените этот параметр, по умолчанию порт равен 24
# данный порт является привилегированным в убунту и убунта не позволяет запускать на нём
# приложения
ServerPort      11124
# Остальные опции выставил по примерам из интернета, единственное ServerIdent поставил
# hostname -f данного сервера
ServerQueueSize 32
ServerPID       /var/run/dspam/dspam.pid
ServerMode auto
ServerParameters        "--deliver=innocent -d %u"
ServerIdent             "mail.example.com"
ServerDomainSocketPath  "/var/run/dspam/dspam.sock"
ClientHost      "/var/run/dspam/dspam.sock"
ProcessorBias on
# Подключаем файлы из директории /etc/dspam/dspam.d/
Include /etc/dspam/dspam.d/

Приступаем к настройке web интерфейса dspam

Создаём файл .htpasswd в каталоге /var/www/dspam/ и запишем в него пароль для пользователя amavis

htpasswd -nbm amavis secret > /var/www/dspam/.htpasswd
(вместо secret поставьте ваш пароль)

Даём права группе www-data на этот файл

chown www-data:www-data /var/www/dspam/.htpasswd

Теперь создаём файл dspam в каталоге /etc/apache2/conf.d/

>/etc/apache2/conf.d/dspam

и вставляем в него следующее содержимое

SuexecUserGroup dspam dspam
Addhandler cgi-script .cgi
Options +ExecCGI -Indexes
Alias /dspam /var/www/dspam/
<Directory /var/www/dspam/>
    Addhandler cgi-script .cgi
    Options +ExecCGI -Indexes
    DirectoryIndex dspam.cgi
    AuthUserFile /var/www/dspam/.htpasswd
    AuthGroupFile /dev/null
    AuthType Basic
    AllowOverride None
    AuthName "DSPAM Control Center"
    Require valid-user
</Directory>

Установим недостающий модуль для apache и активируем его

apt-get install apache2-suexec
a2enmod suexec

Перезагружаем apache

/etc/init.d/apache2 restart

Устанавливаем пользователя amavis в качестве админа в web интерфейсе dspam

echo "amavis" > /etc/dspam/admins

Теперь необходимо отредактировать файл /etc/dspam/webfrontend.conf заменив значение одной строки на свой домен

$CONFIG{'LOCAL_DOMAIN'} = "example.com";

Далее редактируем файл /etc/dspam/conf.d/mysql.conf убрав коментарий с параметра MySQLUIDInSignature

MySQLUIDInSignature    on

И разрешим доступ к этому файлу группе amavis

chown :amavis /etc/dspam/dspam.d/mysql.conf

Отредактируем файл /etc/default/dspam заменив в нём значение параметра START с no на yes.

2.2. Установка dspam из исходников

Установим необходимые пакеты для сборки dspam

apt-get build-dep dspam

Установим procmail (используется в качестве доставщика в dspam)

apt-get install procmail

Добавим пользователя dspam

useradd -b /bin/false -M dspam

Переходим в каталог /usr/src и скачиваем последнюю версию dspam (версия 3.9.1-RC1 последняя на момент написания статьи)

cd /usr/src && wget http://garr.dl.sourceforge.net/project/dspam/dspam/dspam-3.9.1-RC1/dspam-3.9.1-RC1.tar.gz

Распаковываем полученный архив

tar xzf dspam-3.9.1-RC1.tar.gz

Переходим в папку dspam-3.9.1-RC1

cd ./dspam-3.9.1-RC1

Конфигурируем dspam

./configure --prefix=/usr --includedir=/usr/include --mandir=/usr/share/man \
--infodir=/usr/share/info --with-logdir=/var/log/dspam/ --localstatedir=/var --libexecdir=/usr/lib/dspam \
--with-dspam-home=/home/dspam --sysconfdir=/etc/dspam --enable-domain-scale \
--enable-signature-headers --with-delivery-agent=/usr/bin/procmail --enable-daemon \
--with-mysql-includes=/usr/include/mysql --with-mysql-libraries=/usr/lib --with-storage-driver=mysql_drv,hash_drv \
--enable-ldap --enable-debug --enable-virtual-users --enable-preferences-extension \
--enable-clamav --with-dspam-home-owner=dspam --with-dspam-home-group=dspam \
--with-dspam-owner=dspam --with-dspam-group=dspam

Запускаем сборку

make

Если всё прошло нормально то устанавливаем

make install

Добавляем базу dspam в mysql

mysqladmin create dspam -p
здесь необходимо будет указать пароль root от mysql

Создаём таблицы в БД dspam

mysql dspam < ./src/tools.mysql_drv/mysql_objects-4.1.sql -p
mysql dspam < ./src/tools.mysql_drv/virtual_users.sql -p

Заходим в mysql

mysql -u root -p

и добавляем пользователя dspam, так же даём этому пользователю все права на БД dspam

grant all on dspam.* to dspam@localhost identified by 'здесь_укажите_ваш_пароль';

Для выхода набираем

\q

Назначаем права на запуск dspam

chown root:root /usr/bin/dspam
chmod 755 /usr/bin/dspam

Переходим к установке web интерфейса

Создадим необходимый каталог и установим на него права

mkdir /var/www/dspam
chown dspam:dspam /var/www/dspam/

Копируем файлы web интерфейса в созданный каталог, назначаем права на скопированные файлы

cp -r ./webui/cgi-bin/* /var/www/dspam/
cp -r ./webui/htdocs /var/www/dspam/
chown -R dspam:dspam /var/www/dspam

Удаляем make файлы, они нам не нужны

find /var/www/dspam/ -name 'Makefile*' | while read s; do rm -f $s; done

Создаём символическую ссылку на файл пользовательских настроек по умолчанию, в каталог /etc/dspam, для того чтоб эти настройки были видны демону dspam

ln -s /var/www/dspam/default.prefs /etc/dspam/default.prefs

Создаём файл .htpasswd в каталоге /var/www/dspam/ и запишем в него пароль для пользователя amavis

htpasswd -nbm amavis secret > /var/www/dspam/.htpasswd
(вместо secret поставьте ваш пароль)

Даём права группе www-data на этот файл

chown www-data:www-data /var/www/dspam/.htpasswd

Теперь создаём файл dspam в каталоге /etc/apache2/conf.d/

>/etc/apache2/conf.d/dspam

и вставляем в него следующее содержимое

SuexecUserGroup dspam dspam
Addhandler cgi-script .cgi
Options +ExecCGI -Indexes
Alias /dspam /var/www/dspam/
<Directory /var/www/dspam/>
    Addhandler cgi-script .cgi
    Options +ExecCGI -Indexes
    DirectoryIndex dspam.cgi
    AuthUserFile /var/www/dspam/.htpasswd
    AuthGroupFile /dev/null
    AuthType Basic
    AllowOverride None
    AuthName "DSPAM Control Center"
    Require valid-user
</Directory>

Установим недостающий модуль для apache и активируем его

apt-get install apache2-suexec
a2enmod suexec

Устанавливаем дополнительные пакеты для того чтоб в web интерфейсе отображались графики

apt-get install libgd-gd2-noxpm-perl libgd-graph3d-perl ttf-dejavu

Перезагружаем apache

/etc/init.d/apache2 restart

Устанавливаем пользователя amavis в качестве админа в web интерфейсе dspam

echo "amavis" > /var/www/dspam/admins

Теперь необходимо отредактировать файл /var/www/dspam/configure.pl

В следующей строке укажите ваш домен

$CONFIG{'LOCAL_DOMAIN'} = "example.com";

Следующие строки отредактируйте как в примере, убрав комментарии и заменив значения на те что показаны ниже

$CONFIG{'WEB_ROOT'}     = "./htdocs";
$CONFIG{'GRAPHS_X_LABEL_FONT'} = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf";
$CONFIG{'GRAPHS_Y_LABEL_FONT'} = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf";
$CONFIG{'GRAPHS_LEGEND_FONT'}  = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf";

Разрешим доступ к конфигурационному файлу dspam группе amavis

chown :amavis /etc/dspam/dspam.conf

Переходим в каталог /etc/dspam и редактируем файл dspam.conf Ниже приведен мой конфиг. Этот конфиг во многом совпадает с конфигом который описывался выше для версии из убунтовского репозитория, Начиная с версии 3.8.0 в dspam появился параметр Tokenizer, более подробно читайте о нём здесь

Вот конфиг:

Home /home/dspam
StorageDriver /usr/lib/dspam/libmysql_drv.so
TrustedDeliveryAgent "/usr/bin/procmail"
OnFail error
Trust root
Trust dspam
Trust apache
Trust mail
Trust mailnull 
Trust smmsp
Trust daemon
Trust amavis
TrainingMode teft
TestConditionalTraining on
Feature noise
Feature whitelist
Algorithm graham burton
Tokenizer chain
PValue bcr
WebStats on
Preference "trainingMode=TEFT"          # { TOE | TUM | TEFT | NOTRAIN } -> default:teft
Preference "spamAction=tag"             # { quarantine | tag | deliver } -> default:quarantine
Preference "spamSubject=[SPAM]"         # { string } -> default:[SPAM]
Preference "statisticalSedation=5"      # { 0 - 10 } -> default:0
Preference "enableBNR=on"               # { on | off } -> default:off
Preference "enableWhitelist=on"         # { on | off } -> default:on
Preference "signatureLocation=headers"  # { message | headers } -> default:message
Preference "tagSpam=off"                # { on | off }
Preference "tagNonspam=off"             # { on | off }
Preference "showFactors=off"            # { on | off } -> default:off
Preference "optIn=off"                  # { on | off }
Preference "optOut=off"                 # { on | off }
Preference "whitelistThreshold=50"      # { Integer } -> default:10
Preference "makeCorpus=off"             # { on | off } -> default:off
Preference "storeFragments=off"         # { on | off } -> default:off
Preference "localStore="                # { on | off } -> default:username
Preference "processorBias=on"           # { on | off } -> default:on
Preference "fallbackDomain=off"         # { on | off } -> default:off
Preference "trainPristine=off"          # { on | off } -> default:off
Preference "optOutClamAV=off"           # { on | off } -> default:off
Preference "ignoreRBLLookups=off"       # { on | off } -> default:off
Preference "RBLInoculate=off"           # { on | off } -> default:off
Preference "notifications=off"          # { on | off } -> default:off
AllowOverride enableBNR
AllowOverride enableWhitelist
AllowOverride fallbackDomain
AllowOverride ignoreGroups
AllowOverride ignoreRBLLookups
AllowOverride localStore
AllowOverride makeCorpus
AllowOverride optIn
AllowOverride optOut
AllowOverride optOutClamAV
AllowOverride processorBias
AllowOverride RBLInoculate
AllowOverride showFactors
AllowOverride signatureLocation
AllowOverride spamAction
AllowOverride spamSubject
AllowOverride statisticalSedation
AllowOverride storeFragments
AllowOverride tagNonspam
AllowOverride tagSpam
AllowOverride trainPristine
AllowOverride trainingMode
AllowOverride whitelistThreshold
AllowOverride dailyQuarantineSummary
AllowOverride notifications
MySQLServer             /var/run/mysqld/mysqld.sock
MySQLUser               dspam
MySQLPass               dspam
MySQLDb                 dspam
MySQLReconnect          true
MySQLUIDInSignature     on
HashRecMax              98317
HashAutoExtend          on  
HashMaxExtents          0
HashExtentSize          49157
HashPctIncrease         10
HashMaxSeek             10
HashConnectionCache     10
IgnoreHeader X-Spam-Status
IgnoreHeader X-Spam-Scanned
IgnoreHeader X-Virus-Scanner-Result
Notifications   off
PurgeSignatures 14      # Stale signatures
PurgeNeutral    90      # Tokens with neutralish probabilities
PurgeUnused     90      # Unused tokens
PurgeHapaxes    30      # Tokens with less than 5 hits (hapaxes)
PurgeHits1S     15      # Tokens with only 1 spam hit
PurgeHits1I     15      # Tokens with only 1 innocent hit
LocalMX 127.0.0.1
SystemLog       on
UserLog         on
Opt out
ServerPort              11124
ServerQueueSize 32
ServerPID               /var/run/dspam/dspam.pid
ServerMode auto
ServerParameters        "--deliver=innocent -d %u"
ServerIdent             "mail.example.com"
ServerDomainSocketPath  "/var/run/dspam/dspam.sock"
ClientHost      "/var/run/dspam/dspam.sock"
ProcessorURLContext on
ProcessorBias on
StripRcptDomain off

Создадим каталог /var/run/dspam и назначим ему права

mkdir /var/run/dspam && chown dspam:dspam /var/run/dspam

Совсем не обязательно запускать dspam в качестве демона, так как amavis сам при каждой проверки запускает dspam с необходимыми параметрами, но если вы всё таки хотите чтоб dspam стартовал в качестве демона при загрузке сервера вам необходимо выполнить следующее:

создать два файла

>/etc/default/dspam

в этот файл запишите

START=yes
# User that runs dspam.
USER=dspam
# Options for dspam.
#OPTIONS="--debug"

и создать скрипт запуска в /etc/init.d (скрипт взят из пакета dspam в репозитории ubuntu)

>/etc/init.d/dspam

содержимое этого скрипта

#!/bin/sh
### BEGIN INIT INFO
# Provides:          skeleton
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: initscript for dspam
# Description:       dspam is a scalable, fast and statistical anti-spam filter
### END INIT INFO
#
# Author:       Matthijs Mohlmann <matthijs@cacholong.nl>.
#
# Based on the init script of pdns-recursor
#
 
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DESC="DSPAM Statistical anti-spam filter"
NAME=dspam
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/dspam/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
 
# Gracefully exit if the package has been removed.                                                                                                                                  
test -x $DAEMON || exit 0                                                                                                                                                           
 
# Read config file if it is present.                                                                                                                                                
if [ -r /etc/default/$NAME ]; then                                                                                                                                                  
        . /etc/default/$NAME                                                                                                                                                        
fi                                                                                                                                                                                  
 
# Create directory for PIDFILE, if it does not exist and change ownership.                                                                                                          
test -d $(dirname $PIDFILE) || mkdir -p -m 755 $(dirname $PIDFILE)                                                                                                                  
chown $USER $(dirname $PIDFILE)                                                                                                                                                     
 
OPTIONS="--daemon $OPTIONS"                                                                                                                                                         
 
# Start the daemon                                                                                                                                                                  
d_start() {                                                                                                                                                                         
# Return                                                                                                                                                                            
#  0 if daemon has been started                                                                                                                                                     
#  1 if daemon was already running                                                                                                                                                  
#  2 if daemon could not be started                                                                                                                                                 
  start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER --exec $DAEMON --test > /dev/null || return 1                                                                  
  start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER --exec $DAEMON -- $OPTIONS || return 2
}
 
# Stop the daemon
d_stop() {
# Return
#  0 if daemon has been stopped
#  1 if daemon was already stopped
#  2 if daemon could not be stopped
#  other if a failure occured
  start-stop-daemon --stop --quiet --retry=TERM/5/KILL/5 --pidfile $PIDFILE --name $NAME
  RETVAL="$?"
  [ "$RETVAL" = 2 ] && return 2
  start-stop-daemon --stop --quiet --oknodo --retry=KILL/5 --exec $DAEMON
  [ "$?" = 2 ] && return 2
  rm -f $PIDFILE
  return "$RETVAL"
}
 
case "$1" in
  start)
    if [ "$START" != "yes" ]; then
      echo "Not starting $DESC -- disabled."
      exit 0
    fi
    echo -n "Starting $DESC: $NAME"
    d_start
    case "$?" in
      0)
        echo "."
        exit 0
        ;;
      1)
        echo " (already running)."
        exit 0
        ;;
      *)
        echo " (failed)."
        exit 1
        ;;
    esac
    ;;
  stop)
    # Always try to stop the daemon.
    echo -n "Stopping $DESC: $NAME"
    d_stop
    case "$?" in
      0)
        echo "."
        exit 0
        ;;
      1)
        echo " (not running)."
        exit 0
        ;;
      *)
        echo " (failed)."
        exit 1
    esac
    ;;
  restart|force-reload)
    if [ "$START" != "yes" ]; then
      $0 stop
      exit 0
    fi
    echo -n "Restarting $DESC: $NAME"
    d_stop
    case "$?" in
      0|1)
        d_start
        case "$?" in
          0)
            echo "."
            exit 0
            ;;
          1)
            echo " (failed -- old process still running)."
            exit 1
            ;;
          *)
            echo " (failed to start)."
            exit 1
            ;;
        esac
        ;;
      *)
        echo " (failed to stop)."
        exit 1
        ;;
    esac
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
    exit 1
    ;;
esac
 
exit 0

Установите права на скрипт

chown root:root /etc/init.d/dspam
chmod 755 /etc/init.d/dspam

Создайте символические ссылки на скрипт в rcX.d для автоматического запуска dspam при загрузке сервера.

ln -s /etc/init.d/dspam /etc/rc0.d/K21dspam
ln -s /etc/init.d/dspam /etc/rc1.d/K21dspam
ln -s /etc/init.d/dspam /etc/rc2.d/S21dspam                                                                                                                      
ln -s /etc/init.d/dspam /etc/rc3.d/S21dspam                                                                                                                       
ln -s /etc/init.d/dspam /etc/rc4.d/S21dspam                                                                                                                       
ln -s /etc/init.d/dspam /etc/rc5.d/S21dspam                                                                                                                       
ln -s /etc/init.d/dspam /etc/rc6.d/K21dspam

2.3 Настройка автоматической очистки базы dspam от устаревших записей

Копируем необходимые sql файлы

cp -r /usr/src/dspam-3.9.1-RC1/src/tools.mysql_drv/ /usr/share/dspam/tools.mysql_drv/

Создаём файл с названием dspam

> dspam

следующего содержания:

#!/bin/sh
#
# Clean up the mysql databases
 
DSPAMCONF=/etc/dspam/dspam.conf
MYSQLCONF=/etc/dspam/dspam.conf
PURGE=/usr/share/dspam/tools.mysql_drv/purge-4.1.sql
MYSQLCONF_PASSWD=/var/run/dspam-mysql.cron.passwd
 
if grep -q "^StorageDriver.*mysql_drv.so" $DSPAMCONF; then
  if [ -x /usr/bin/mysql ]; then
    MYSQL_USER="`grep "^MySQLUser" $MYSQLCONF | awk '{print $2}'`"
    MYSQL_PASS="`grep "^MySQLPass" $MYSQLCONF | awk '{print $2}'`"
    MYSQL_DB="`grep "^MySQLDb" $MYSQLCONF | awk '{print $2}'`"
    MYSQL_HOST="`grep "^MySQLServer" $MYSQLCONF | awk '{print $2}'`"
 
    UMASK_OLD="`umask`"
    umask 077
    [ -e "$MYSQLCONF_PASSWD" ] && rm "$MYSQLCONF_PASSWD"
    printf "[client]\npassword=$MYSQL_PASS" > "$MYSQLCONF_PASSWD"
    umask "$UMASK_OLD"
 
    # If host is empty or starting with a / assume it's localhost.
    if [ -z "$MYSQL_HOST" ] || \
       [ ` echo "${MYSQL_HOST}" | cut -c1 ` = "/" ]; then
        /usr/bin/mysql --defaults-file=$MYSQLCONF_PASSWD \
                       --user=$MYSQL_USER $MYSQL_DB < $PURGE
    else
        /usr/bin/mysql --defaults-file=$MYSQLCONF_PASSWD --host=$MYSQL_HOST --user=$MYSQL_USER < $PURGE
    fi
 
    rm "$MYSQLCONF_PASSWD"
 
  fi
fi
 
exit 0

и кладём этот скрипт в /etc/cron.daily

Устанавливаем права на скрипт

chmod 755 /etc/cron.daily/dspam

2.4 Настройка ротации логов dspam

Создаём файл с названием dspam

> dspam

следующего содержания:

/var/log/dspam/dspam.debug {
        monthly
        missingok
        rotate 7
        compress
}

и кладём его в /etc/logrotate.d

Вот собственно и всё, настройка dspam законченна.

3. Подключение amavis и dspam в postfix

Конфигурируем main.cf

postconf -e 'content_filter = smtp-amavis:[127.0.0.1]:10024'
postconf -e 'transport_maps = hash:/etc/postfix/transports'

редактируем master.cf добавив в конец файла следующие строки

smtp-amavis     unix    -       -       -       -       2       smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
        -o max_use=20
127.0.0.1:10025 inet    n       -       -       -       -       smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_delay_reject=no
        -o smtpd_client_restrictions=permit_mynetworks,reject
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=reject_unauth_pipelining
        -o smtpd_end_of_data_restrictions=
        -o mynetworks=127.0.0.0/8
        -o smtpd_error_sleep_time=0
        -o smtpd_soft_error_limit=1001
        -o smtpd_hard_error_limit=1000
        -o smtpd_client_connection_count_limit=0
        -o smtpd_client_connection_rate_limit=0
        -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
dspam-retrain         unix    -       n       n       -      10     pipe
  flags=Rhq user=dspam argv=/usr/bin/dspam --class=$nexthop --user amavis --source=error

Создаём файл /etc/postfix/transports и записываем в него

spam@example.com       dspam-retrain:spam
notspam@example.com    dspam-retrain:innocent

Преобразуем данный файл в базу данных

postmap /etc/postfix/transports

Запускаем dspam

/etc/init.d/dspam start
Если не создавали скрипт запуска dspam то эту команду выполнять не нужно

Перезагружаем amavis

/etc/init.d/amavis restart

Перезагружаем postfix

/etc/init.d/postfix restart

На всякий случай проверяем статус clamav-daemon

/etc/init.d/clamav-daemon status

если * clamd is running то всё ок если нет то запускаем

/etc/init.d/clamav-daemon start

4. Добавление пользователя amavis в базу dspam.

Создадим файл message.txt с произвольным содержанием

cd /tmp && echo "Hello dspam" > message.txt

И выполним команду

dspam --deliver=innocent --user amavis -- %u < message.txt

После чего в домашнем каталоге dspam должна появится папка

/data/local/amavis/

внутри которой будут файлы amavis.log, amavis.stats.

Установим права на домашний каталог dspam и всё его содержимое

chown -R dspam:amavis /home/dspam

Всё, настройка amavis + dspam + clamav закончена.

5. Тестирование

Теперь отправим тестовое сообщение через telnet, откроем данное сообщение для просмотра, на сервере в папке пользователя, в нём должны быть заголовки

X-DSPAM-Result:
X-DSPAM-Processed:
X-DSPAM-Confidence:
X-DSPAM-Probability:
X-DSPAM-Signature:
X-Virus-Scanned:
X-Spam-Flag:
X-Spam-Score:
X-Spam-Level: 
X-Spam-Status:

Если они присутствуют, то всё работает нормально.

Более подробно о настройке amavis читайте здесь:

http://it.vcore.ru/?tag=spamassassin

http://spherix.jeka.ru/index.php?page=2&prnt=727

Обсудить данную статью можно на форуме.

6. Материалы используемые при написании данной статьи

7. Статьи по теме