Интеграция почтового сервера Exim c MS Active Directory
(mail exim samba domain windows ldap freebsd dbmail)


Версии ПО:

ОС: FreeBSD 6.2
Почтовый сервер: exim 4.63
СУБД: mysql-server-5.0.27
POP3 и IMAP сервер, с хранением почты в СУБД: dbmail-2.2.2_1
Антиспам-фильтр: dspam-3.6.8_1
Антивирусное ПО: clamav-0.90_3
ПО авторизации: cyrus-sasl-saslauthd-2.1.22, cyrus-sasl-ldapdb-2.1.22
Библиотека ПО для работы с графикой: gd-2.0.33_4,1
Веб-сервер: apache-2.0.59, mod_perl2-2.0.3_1,3
CPAN-модули для работы с графикой: bsdpan-GD-2.35, bsdpan-GD-Graph3d-0.63, bsdpan-GDGraph-1.4308

Все программное обеспечение было установленно из портов ОС FreeBSD 6.2, за исключением нескольких CPAN-модулей.

Установка вышеперечисленного ПО производилась в следующем порядке:

1. почтовый сервер;
2. ПО авторизации;
3. СУБД;
4. POP3 и IMAP сервер;
5. антивирус;
6. антиспам-фильтр;
7. веб-сервер.
1. Установка почтового сервера.

Перед установкой почтового сервера в папке /usr/ports/mail/exim создал файл sys.mk со следующим содержимым:
WITH_CONTENT_SCAN = yes
WITH_MYSQL = yes
WITH_MYSQL_VER = 50
WITH_SASLAUTHD = yes
WITH_OPENLDAP = yes
WITH_OPENLDAP_VER = 23
WITH_AUTH_SASL = yes

Ну а далее просто make install clean или portinstall mail/exim.
Потом начинаем править конфигурационный файл /usr/local/etc/exim/configure:
<...skip...>
######################################################################
# MAIN CONFIGURATION SETTINGS #
######################################################################
# 192.168.0.1 - это адрес вашего контроллера домена, где LDAP-сервер
# доступен по 3268 порту.
ldap_default_servers = <; 192.168.0.1:3268
# В Active Directory нужно создать пользователя "Exim" с паролем "password".
# Стоит обратить внимание на то, что свойство "Выводимое имя"
# пользователя должно быть именно "Exim", иначе почтовый сервер не сможет
# авторизоваться в LDAP-сервере контроллера домена.
LDAP_AD_BINDDN = "CN=Exim,CN=Users,DC=domain,DC=com"
LDAP_AD_PASS = password
LDAP_AD_BASE_DN = "CN=Users,DC=domain,DC=com"
# Макрос для организации запросов к LDAP-серверу.
LDAP_AD_MAIL_RCPT =
user=LDAP_AD_BINDDN
pass=LDAP_AD_PASS
ldap:///DC=domain,DC=com?mail?sub?(&(|(objectClass=top)(objectClass=user)
(objectClass=organizationalPerson)(objectClass=person))
(mail=${quote_ldap:${local_part}@${domain}}))

# Скрываем версию ПО
smtp_banner = "$primary_hostname, ESMTP EXIM"

# Некоторые почтовые клиенты в HELO радостно пишут имя windows-машин
# со знаком "_" и тут же отпинываются почтовым сервером. Разрешаем использование
# этого знака.
helo_allow_chars = _

# Пишем логи по дням - удобно для последующего "разбора полетов".
log_file_path = /var/log/exim/exim-%s-%D.log
log_selector = +all
SYSLOG_LONG_LINES = yes

# ourdomain.ru - это доменная зона, куда будут приходить ваши письма.
primary_hostname = mail.ourdomain.ru
domainlist local_domains = ourdomain.ru
hostlist relay_from_hosts = 127.0.0.1
qualify_domain = ourdomain.ru

# Пытаемся распознать имя только тех хостов которые не в локальной сети.
host_lookup = !192.168.0.0/24

# Объявление блока для проверки имени хоста
acl_smtp_connect = acl_check_host

# Объявление блока для проверки HELO отправителя
acl_smtp_helo = acl_check_helo

# Делаем этот параметр равный нулю, чтобы сервер не пытался опросить ident хоста.
rfc1413_query_timeout = 0s

<...skip...>

######################################################################
# ACL CONFIGURATION #
# Specifies access control lists for incoming SMTP mail #
######################################################################

begin acl
### Проверка HELO отправителя
acl_check_helo:
accept hosts = 192.168.0.0/24 : 127.0.0.1
accept hosts = wildlsearch;/usr/local/etc/exim/list/white-hosts

# Отпинываем пользователей, указавших в HELO числа
drop message = Invalid HELO/EHLO data
condition = ${if match {$sender_helo_name}{N^-?[0-9]+$N}{yes}{no}}

# Отпинываем пользователей, указавших в HELO ip-address
drop message = HELO/EHLO should not be the ip-address
condition = ${if match
{$sender_helo_name}{N^(d+.){3}d+$N}{yes}{no}}

# Отпинываем пользователей, указавших в HELO адреса, подпадающих
# под список /usr/local/etc/exim/list/spam-hosts
drop message = Spam blocking
condition = ${lookup {$sender_helo_name}wildlsearch{/usr/local/etc/exim/list/spam-hosts}{yes}{no}}
accept

### Проверка имени хоста отправителя
acl_check_host:
# Правило разрешающее указанные в списке хосты
accept hosts = wildlsearch;/usr/local/etc/exim/list/white-hosts

# Отпинываем пользователей с хостами, подпадающими
# под список /usr/local/etc/exim/list/spam-hosts
drop message = Spam blocking
hosts = !192.168.0.0/24 : !127.0.0.1 :
wildlsearch;/usr/local/etc/exim/list/spam-hosts

# Отпинываем пользователей с хостами, подпадающими
# под список ip-адресов /usr/local/etc/exim/list/net.blocked
drop message = This ip-address in our blacklist
hosts = net32-lsearch;/usr/local/etc/exim/list/net.blocked

drop message = This ip-address in our blacklist
hosts = net24-lsearch;/usr/local/etc/exim/list/net.blocked

drop message = This ip-address in our blacklist
hosts = net16-lsearch;/usr/local/etc/exim/list/net.blocked

accept

<...skip...>

# В блоке проверки получателя (acl_check_rcpt) раскомментируем строку
require verify = csa

# И после него добавляем правило, запрещающее без авторизации отправлять
# письма от имени наших пользователей
deny !authenticated = *
condition = ${if eq{$sender_address_domain}{ourdomain.ru}{yes}{no}}
message = Sorry, authorization required

<...skip...>

# В блоке проверки содержимого письма (acl_check_data) добавляем правило,
# блокирующее письма с потенциально опасным содержимым
deny message = Contains ".$found_extension" file (blacklisted).
demime = exe:com:vbs:bat:pif:scr:js:cab:wsh:msi:hta:
vb:vbe:jse:cpl:reg:msp:msi:mst

<...skip...>

######################################################################
# ROUTERS CONFIGURATION #
# Specifies how addresses are handled #
######################################################################
# THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT! #
# An address is passed to each router in turn until it is accepted. #
######################################################################

begin routers

<...skip...>

# Теперь добавляем роутеры для проверки пользователей в Active Directory
# Этот роутер должен стоять после "dnslookup".
adsi_check:
driver = redirect
domains = +local_domains
allow_fail
allow_defer
# forbid_file
# forbid_pipe

# Проверяем наличие запрошенного ящика в Active Directory
data = ${lookup ldap {LDAP_AD_MAIL_RCPT}
{${local_part}@${domain}} {:fail: User unknown}}
redirect_router = local_adsi_user

local_adsi_user:
driver = accept
# local_part_suffix = +* : -*
# local_part_suffix_optional
transport = local_adsi_delivery
cannot_route_message = Unknown user

<...skip...>

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

<...skip...>

# Тут порядок размещения транспортов уже не играет роли
### Local delivery
local_adsi_delivery:
driver = appendfile
file = /var/mail/$local_part
delivery_date_add
envelope_to_add
return_path_add
group = mail
user = mailnull
mode = 0660
no_mode_fail_narrower

Примеры файлов со списками, которые были упомянуты в конфигурационном
файле:
# cat > /usr/local/etc/exim/list/white-hosts

*.rmt.ru
smtp-9.masterhost.ru

# cat > /usr/local/etc/exim/list/spam-hosts

N^[a-fA-F0-9]{10,}(.[^.]+){2,}N
N^d+.d+.d+.d+.w+N
N^.*?[wd]+[.-](w*d+[-x]){2,}w*d+.[wd]N
N^w+d{5,}[w]*[.-]N
N^d+.ya1.ruN
nat.sitc.ru
N^(d+[-.]){2,}[dw]+N
N^.*?(client|dial(ed)?|vpn|modem|dhcp|[dD]ynamic|[iI][pP]|pool|catv|ppp|cable|[xav]?dsl)(d+w*)?(.[^.]+){2,}$N
*.comcast.net
N^([xav]?dsl|client|ppp|dial(ed)?|vpn|dhcp|di(al)?up|[xav]?dsl|modem|pool|catv|tomts|host|[uU][sS][eE][rR])[d]*[-.]?d+.N
*.merr.com
*.wanadoo.fr
N^(w+d+[-.]){2,}N
N^w+d+.neoline.com.br$N
rsveg.plus.com
*.virtua.com.br
*.door.net
*.utoronto.ca
*.venti.pl
*.t-dialin.net
N^([dw]+[-.]){2,}d+[-.]N
*.fortech.lv
*.tpnet.pl
*.1000lecie.pl
*.superb.net
*.chello.nl
*.mobille.tv
*.upc.cz
*.wroc.pl
*.vnet.ee
*.astral.ro
*.bellnexxia.net
*.mynet.net
*.sgci.com
*.shawcable.com
*.ne.jp
*.co.jp
*.oleane.fr
*.wanadoo.co.uk
*.pppool.de
*.bah-bonn.de
*.unict.it
*.interpc.pl
*.retevision.es
*.contactel.cz
*.ufmg.br
*.racsa.co.cr
mail.holzmann.de
*.hananet.net

В этом файле следующий формат данных. Маски сетей пишутся по одному на
строку в формате AAA.BBB.CCC.DDD/XX,
где XX - должен быть кратным восьми и больше восьми. Примеры:
AAA.BBB.0.0/16, AAA.BBB.CCC.0/24 или AAA.BBB.CCC.DDD/32
# cat > /usr/local/etc/exim/list/net.blocked

219.128.0.0/16
219.129.0.0/16
219.130.0.0/16
219.131.0.0/16
219.132.0.0/16
219.133.0.0/16
219.134.0.0/16
219.135.0.0/16
219.136.0.0/16
219.137.0.0/16

Настраиваем профили пользователей в домене - пишем их электронные адреса в соответствующем поле. Тут надо заметить что в моем случае надо чтобы имя пользователя электронного адреса совпадало с его именем входа - т.е. если в домене он demiurg то адрес должен быть как demiurg@ourdomain.ru. Иначе в будущем могут быть глюки.

Потом проверяем конфигурацию почтового сервера командой exim -bh 80.73.64.248 (под root). Почтовый сервер начнет имитировать SMTP-диалог с указанным хостом и одновременно выводить отладочную информацию о ходе обработки команд и данных.

Например такой диалог:
*< Ответ сервера
*> Наши команды
# exim -bh 80.73.64.248
**** SMTP testing session as if from host 80.73.62.248
**** but without any ident (RFC 1413) callback.
**** This is not for real!

>>> host in hosts_connection_nolog? no (option unset)
LOG: SMTP connection from [80.73.62.248]
>>> host in host_lookup? yes (end of list)
... skip ...
>>> accept: condition test succeeded
*< 220 mail.dbki.ru, ESMTP EXIM
*> HELO sakha.ru
>>> sakha.ru in helo_lookup_domains? no (end of list)
>>> using ACL "acl_check_helo"
>>> processing "accept"
>>> check hosts = 192.168.0.0/24 : 127.0.0.1
... skip ...
*< 250 mail.dbki.ru Hello sakha.ru [80.73.62.248]

# Вводим фиктивный адрес отправителя
*> MAIL FROM: demiurg@sakha.ru
*< 250 OK

# Вводим РЕАЛЬНЫЙ адрес получателя
*> RCPT TO: demiurg@ourdomain.ru
>>> using ACL "acl_check_rcpt"
... skip ...
>>> processing "accept"
>>> accept: condition test succeeded

# Если все правильно настроили то должно выйти "250 Accepted",
# если иное - то начинаем проверять конфиг.
*< 250 Accepted

# Выходим
*> QUIT

2. Установка ПО авторизации.

Настраиваем SMTP-авторизацию для этого ставим cyrus-sasl-saslauthd-2.1.22
# portinstall security/cyrus-sasl2-saslauthd

После установки создаем конфигурационный файл
# cat > /usr/local/etc/saslauthd.conf
ldap_servers: ldap://192.168.0.1:3268/
ldap_bind_dn: CN=Exim,CN=Users,DC=domain,DC=com
ldap_bind_pw: password
ldap_version: 3
ldap_search_base: CN=Users,DC=domain,DC=com
ldap_filter: (sAMAccountName=%u)
#ldap_filter: (mail=%u)
ldap_debug: -1

Правим конфиг почтового сервера /usr/local/etc/exim.configure:
######################################################################
# AUTHENTICATION CONFIGURATION #
######################################################################
begin authenticators

### Добавляем
plain:
driver = plaintext
public_name = PLAIN
server_condition = ${if saslauthd{{$2}{$3}}{1}{0}}
server_set_id = $2

login:
driver = plaintext
public_name = LOGIN
server_prompts = "Username:: : Password::"
server_condition = ${if saslauthd{{$1}{$2}}{1}{0}}
server_set_id = $1

в /etc/rc.conf добавляем:
sendmail_enable="NO"
sendmail_submit_enable="NO"
exim_enable="YES"
saslauthd_enable="YES"
saslauthd_flags="-a ldap"

Также правим файл /etc/mail/mailer.conf:
sendmail /usr/local/sbin/exim
send-mail /usr/local/sbin/exim
mailq /usr/local/sbin/exim -bp
newaliases /usr/local/sbin/exim -bi
hoststat /usr/local/sbin/exim
purgestat /usr/local/sbin/exim

3. Установка СУБД.

Подробности установки СУБД MySQL 5.0 расписывать не буду, так как она
стандартна.

4. Установка POP3 и IMAP сервера.

Следующим шагом ставим DBMail 2.2.2
# cd /usr/ports/mail/dbmail
# make config

отмечаем:

[X] MYSQL Build with MySQL support (хранение почты в mySQL)
[X] SIEVE Build w. support for Sieve mail sorting language (на всякий случай :)
[X] LDAP Build with support for LDAP authentication (ищем пользователей в Active Directory)

и далее
# make install clean

Создаем БД в MySQL:
$ mysql -u root -p
mysql> create database dbmail;
mysql> GRANT SELECT,INSERT,DELETE,UPDATE ON `dbmail`.* to
'dbmail'@'localhost' IDENTIFIED BY 'password';
mysql> use dbmail;
mysql> source /usr/local/share/dbmail/mysql/create_tables.mysql
mysql> flush privileges;

Меняем настройки в конфигурационном файле /usr/local/etc/dbmail.conf:
driver = mysql
authdriver = ldap
sqlsocket = /var/run/mysql.sock

user = dbmail
pass = password
db = dbmail

[LDAP]
# Секция описана полностью, на всякий случай.
PORT = 3268
VERSION = 3
HOSTNAME = 192.168.0.1
BASE_DN = cn=Users,dc=domain,dc=com
BIND_DN = cn=Exim,cn=Users,dc=domain,dc=com

BIND_PW = password
SCOPE = SubTree
USER_OBJECTCLASS = top,person,organizationalPerson,user
#USER_OBJECTCLASS = top,account,dbmailUser
#FORW_OBJECTCLASS = top,account,dbmailForwardingAddress
CN_STRING = sAMAccountName
FIELD_PASSWD = userPassword
FIELD_UID = sAMAccountName
FIELD_NID = uSNCreated
MIN_NID = 10000
MAX_NID = 15000
FIELD_CID = primaryGroupID
MIN_CID = 10000
MAX_CID = 15000
FIELD_MAIL = mail
#FIELD_QUOTA = mailQuota
#FIELD_FWDTARGET = mailForwardingAddress

не забываем про /etc/rc.conf и добавляем туда:
dbmail_imapd_enable="YES"

Снова правим /usr/local/etc/exim/configure:
# Меняем роутер adsi_check
adsi_check:
driver = redirect
domains = +local_domains
allow_fail
allow_defer
forbid_file
forbid_pipe

data = ${lookup ldap {LDAP_AD_MAIL_RCPT}
{${local_part}@${domain}} {:fail: User unknown}}
redirect_router = dbmailuser

# После роутера adsi_check добавляем
dbmailuser:
driver = accept
condition = ${lookup ldap {LDAP_AD_MAIL_RCPT} {yes}{no}}
transport = dbmail_delivery
cannot_route_message = Unknown user

# Добавляем транспорт dbmail_delivery
dbmail_delivery:
driver = pipe
delivery_date_add
envelope_to_add
return_path_add
check_string =
command = /usr/local/sbin/dbmail-smtp -d $local_part@$domain
group = mail
message_prefix = ""
message_suffix = ""
path="/bin:/sbin:/usr/local/bin:/usr/local/sbin"

Теперь запускаем exim, saslauthd и dbmail:
# /usr/local/etc/rc.d/saslauthd start
# /usr/local/etc/rc.d/exim.sh start
# /usr/local/etc/rc.d/dbmail-imapd start

и пробуем отправить/принять почту (не забывайте про SMTP-авторизацию).
Если не получается смотрим в логи и устраняем причину.

5. Установка антивирусного ПО.

На данном этапе все должно работать без уговоров :) Теперь будем прикручивать антивирус Clamav, распространяемый под свободной лицензией.
# cd /usr/ports/security/clamav
# make all install clean

Правим конфигурационный файл /usr/local/etc/exim/configure:
# Правим av_scanner
av_scanner = clamd:/var/run/clamav/clamd

# В блоке проверки контента (acl_check_data) добавляем
deny malware = *
message = This message contains a virus ($malware_name).

Правим конфигурационный файл /usr/local/etc/clamd.conf:
LogFile /var/log/clamav/clamd.log
PidFile /var/run/clamav/clamd.pid
DatabaseDirectory /var/db/clamav
LocalSocket /var/run/clamav/clamd
FixStaleSocket yes
User mailnull
AllowSupplementaryGroups yes
AlgorithmicDetection yes
ScanPE yes
ScanELF yes
DetectBrokenExecutables yes
ScanOLE2 yes
ScanMail yes
MailFollowURLs no
ScanHTML yes
ScanArchive yes

Правим конфигурационный файл /usr/local/etc/freshclam.conf:
DatabaseDirectory /var/db/clamav
UpdateLogFile /var/log/clamav/freshclam.log
PidFile /var/run/clamav/freshclam.pid
DatabaseOwner mailnull
AllowSupplementaryGroups yes
DatabaseMirror database.clamav.net
NotifyClamd /usr/local/etc/clamd.conf

Теперь меняем владельца некоторых папок антивируса:
# chown -R mailnull:mail /var/log/clamav /var/db/clamav /var/run/clamav

И добавляем в /etc/rc.conf:
clamav_clamd_enable="YES"
clamav_freshclam_enable="YES"

Запускаем антивирус (clamd и freshclam), рестартуем почтовый сервер и
наслаждаемся жизнью :)

6. Установка антиспам-фильтра.

Ставим антиспам-фильтр:
# cd /usr/ports/mail/dspam
# make config

и отмечаем: SYSLOG, DEBUG, DAEMON, MYSQL50, HASH, VIRT_USERS, LONG_USERNAMES, EXIM_LDA, CGI
и далее:
# make all install clean

Создаем базу данных для dspam:
$mysql -u root -p
mysql> create database dspam;
mysql> use dspam;
mysql> grant all on dspam.* to dspam@'localhost' identified by 'password';
mysql> source
/usr/local/share/examples/dspam/mysql/mysql_objects-speed.sql
mysql> source /usr/local/share/examples/dspam/mysql/virtual_users.sql
mysql> flush privileges;

Правим конфиг /usr/local/etc/dspam.conf:
StorageDriver /usr/local/lib/libmysql_drv.so
StorageDriver /usr/local/lib/libhash_drv.so
TrustedDeliveryAgent "/usr/local/sbin/exim -oMr spam-scanned" # Exim
Trust root
Trust dspam
Trust mail
Trust mailnull
Feature noise
Feature chained
Preference "signatureLocation=headers"
Preference "showFactors=on"
Preference "spamAction=tag"
Preference "spamSubject=SPAM"
MySQLServer /tmp/mysql.sock
MySQLUser dspam
MySQLPass password
MySQLDb dspam
MySQLConnectionCache 1000
HashConnectionCache 10
HashConnectionCache 100
IgnoreHeader X-Spam-Status
IgnoreHeader X-Spam-Score
IgnoreHeader X-Spam-Report
IgnoreHeader X-Spam-Scanned
IgnoreHeader X-Virus-Scanner-Result
IgnoreHeader Date
IgnoreHeader Envelope-to
IgnoreHeader Delivery-date
IgnoreHeader Received
IgnoreHeader User-Agent
IgnoreHeader Content-Type
IgnoreHeader Content-Transfer-Encoding
IgnoreHeader To
TrainPristine on

Потом создаем группу и пользователя dspam:
# pw add group dspam
# pw add user dspam -s /bin/nologin -g dspam -d /nonexistent

Теперь добавляем добавляем пользователя ghost в Active Directory, также и как пользователя Exim.

и создаем файл /var/db/dspam/group с таким содержанием:
primary:classification: ghost@ourdomain.ru

Далее меняем владельца папок dspam
#chown -R dspam:dspam /var/db/dspam /var/log/dspam /usr/local/bin/dspam

И правим в последний раз конфиг
/usr/local/etc/exim/configure:
# Добавляем перед роутером adsi_check новые роутеры
### Spam checking
dspam_addspam_router:
driver = accept
domains = +local_domains
local_part_prefix = spam-
transport = dspam_addspam_transport
dspam_notspam_router:
driver = accept
domains = +local_domains
local_part_prefix = notspam-
transport = dspam_notspam_transport

dspam_spamscan_router:
driver = accept
domains = +local_domains
no_verify
condition = "${if and {{!eq {$received_protocol}{spam-scanned}} {!eq {$received_protocol}{local}} } {1}{0}}"
transport = dspam_spamcheck_transport
require_files = /usr/local/bin/dspam
address_test = false

local_delivery_spam_router:
driver = accept
domains = +local_domains
condition = ${if match{$h_X-DSPAM-Result:}{Spam}}
transport = local_delivery_spam_transport
no_more

# Также в конфиг добавляем новый транспорт
### Spam transport
dspam_addspam_transport:
driver = pipe
command = "/usr/local/bin/dspam --user $local_part --class=spam --source=error"
return_path_add = false
return_fail_output = true
log_output = true
home_directory = "/var/db/dspam"
current_directory = "/var/db/dspam"
user = dspam
group = dspam

dspam_notspam_transport:
driver = pipe
command = "/usr/local/bin/dspam --user $local_part --class=innocent --source=error --deliver=innocent %u"
return_path_add = false
return_fail_output = true
log_output = true
home_directory = "/var/db/dspam"
current_directory = "/var/db/dspam"
user = dspam
group = dspam

dspam_spamcheck_transport:
driver = pipe
command = /usr/local/bin/dspam --deliver=innocent --user "$local_part" -- %u
user = dspam
group = dspam
return_path_add = false
log_output = true
return_fail_output = true
headers_remove = X-DSPAM-Result

# Тут создается специальная папка, доступная пользователю по IMAP,
# куда складывается помеченный спам для
# последующего осмотра и разбора.
local_delivery_spam_transport:
driver = pipe
command = /usr/local/sbin/dbmail-smtp -d $local_part@$domain -m 'Spam'
message_prefix =
message_suffix =
delivery_date_add
envelope_to_add
return_path_add

Рестартуем exim и снова радуемся жизни :) Если порадоваться не получилось - читаем от начала и все проверяем.

7. Установка веб-сервера apache2 и веб-интерфейса dspam.

Запускаем
# cd /usr/ports/www/apache20
# make WITH_SUEXEC_MODULES=yes all install clean
# cd /usr/ports/www/mod_perl2; make install clean

Этот порт нужен для авторизации в веб-интерфейсе
# cd /usr/ports/www/mod_auth_imap2; make install clean

Cтавим порт /usr/ports/graphics/gd и недостающие CPAN-модули (чтобы веб-интерфейс dspam мог рисовать графики)
# cpan -i GD::Graph3D
# cpan -i GD::Graph

Не знаю почему, но при установке dspam веб-интерфейс не инсталлировался. Хотя видимо так случилось от того, что веб-сервер еще не был установлен. :) Поэтому её пришлось вручную вытаскивать из тарбалла и копировать в папку /usr/local/www/data/dspam. В итоге у меня в папке оказались следующие файлы и папки:
admin.cgi
configure.pl
graph.cgi
admingraph.cgi
default.prefs
rgb.txt
admins
dspam-logo-small.gif
templates
base.css
dspam.cgi

Правим файл configure.pl:
$CONFIG{'LOCAL_DOMAIN'} = "ourdomain.ru";

После копирования меняем владельца папки - иначе SUEXEC будет активно
ругаться и не даст запустить скрипты:
# chown -R dspam:dspam /usr/local/www/data/dspam

А в конфиг /usr/local/etc/apache2/httpd.conf добавляем:
# Активируем модуль авторизации по IMAP
LoadModule auth_imap_module libexec/apache2/mod_auth_imap.so

# Активируем модуль SUEXEC
LoadModule suexec_module libexec/apache2/mod_suexec.so
#
SuexecUserGroup dspam dspam

<Directory "/usr/local/www/data/dspam">
Auth_IMAP_Enabled on
AuthName "Authorization"
AuthType basic
Require valid-user
# Параметры для авторизации пользователей по IMAP
Auth_IMAP_Authoritative on
Auth_IMAP_Server 127.0.0.1
Auth_IMAP_Port 143
Auth_IMAP_Log on

Options FollowSymLinks ExecCGI
AllowOverride All
Order allow,deny
Allow from all
DirectoryIndex admin.cgi
AddHandler cgi-script .cgi
<IfModule mod_perl.c>
PerlSendHeader On
AddHandler perl-script .cgi
PerlHandler Apache::Registry
</IfModule>
</Directory>

Запускаем apache2 и радуемся жизни :)
Всё.

http://faqman.ru

Обновлено: 12.03.2015