Мир невозможно удержать силой. Его можно достичь лишь пониманием.

Полноценный почтовый сервер

Автор | Апрель 20, 2010 | в Linux

Как ясно из названия — мы будем заниматься организацией собственного почтового сервера, главным компонентом которого будет MTA Exim, который будет заниматься приемом-отправкой почты и скармливанием её различным фильтрам и MUA Dovecot. Почему именно Exim? Это вопрос скорее философский. Мне недавно подсказали, что он хорош. Я его потрогал, и он действительно оказался хорош. Он хорошо задокументирован (хотя на русском языке инфы мало, здесь правит бал всё-таки Postfix), секьюрен, производителен, лёгок в настройке. В общем, правильный выбор.

Данные о пользователях и вспомогательные таблицы будут храниться в MySQL. Для управления доменами и виртуальными почтовыми аккаунтами будем использовать postfixadmin. Да и структуру базы данных будем использовать от этого проекта. Postfixadmin, конечно, предназначен обычно для работы с MTA Postfix, но это непринципиально. Он даже и догадываться у нас не будет, что подоткнут к Exim’у. Он достаточно удобен и лёгок в настройке.

После того, как всё заработает, подключим SpamAssassin и ClamAV для проверки на спам и вирусы.

Данная статья подходит для поднятия сервера, как на Ubuntu, так и на Debian. Пользователи других дистрибутивов тоже смогут подчеркнуть что-нибудь полезное.

Подготовка

Итак, ставим основной необходимый софт (само собой предполагая, что MySQL и Apache уже стоят и работают).

apt-get install exim4 exim4-base exim4-config exim4-daemon-heavy
apt-get install dovecot-common dovecot-imapd dovecot-pop3d
apt-get install php5-imap

Создадим юзера для работы с почтой и хранилище для почты:

useradd -r -u 1150 -g mail -d /var/vmail -s /sbin/nologin -c 'Virtual Mailbox' vmail
mkdir -p /var/vmail
chown vmail:mail /var/vmail
chmod 770 /var/vmail

Создадим базу данных для почты.

$ mysql -u root -p
Enter password:

mysql>CREATE DATABASE mail;
mysql>GRANT ALL PRIVILEGES ON mail.* TO postmaster@localhost IDENTIFIED BY 'password';

Здесь запоминаем логин и пароль для доступа к созданной базе данных mail. В данном случае логин – mail, папроль – password. Эти значения потребуются при настройке exim, postfixadmin и dovecot.

Postfixadmin

Качаем архив с Postfixadmin с оффсайта postfixadmin.sourceforge.net. На текущий момент последняя версия – 2.3. Скачанный архив кладём в /var/www, распаковываем его и меняем владельца на пользователя, от которого работает Apache:

$wget http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin_2.3.tar.gz
$ tar -xzvf postfixadmin_2.3.tar.gz
$ cat /etc/apache2/apache2.conf | grep User www-data
$ sudo chown -R www-data:www-data /var/www/postfixadmin
$ sudo chmod -R 700 postfixadmin

Далее в конфиге Apache создаём (как вариант) virtual host для доступа к Postfixadmin. Также полезным будет прикрыть доступ сюда с помощью .htaccess.


ServerName postfixadmin
DocumentRoot /var/www/postfixadmin

Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all

ErrorLog /var/log/apache2/error_postfixadmin.log
LogLevel warn
CustomLog /var/log/apache2/access_postfixadmin.log combined

В файле config.inc.php редактируем параметры для подключения к базе (адрес, порт, те самые логин и пароль), потом ставим

$CONF['configured'] = true;

На этом этапе ещё надо обратить внимание, на строку

$CONF['encrypt'] = ‘md5crypt’;
Она задаёт, в каком виде будут храниться пароли в базе данных. Само собой, в открытом виде хранить их не следует, но и md5crypt – не единственный вариант. Это вообще внутренний формат md5 для Postfix. А мне он достался в наследство от постоявшего здесь немного Postfix’а. Уж очень не хочется переделывать базу и конфиги. Впрочем, особых проблем это не принесёт. Всегда можно будет аутентифицироваться либо с помощью Exim’овского crypteq, либо через сокет Dovecot SASL, который хорошо поддерживает md5crypt. Есть ещё кое-что, о чём стоит задуматься. Шифрование паролей в базе, по всей видимости, сделает недоступной аутентификацию через механизм CRAM-MD5, требующий самою своею сутью доступ к plaintext-паролю. Ну да и бог с ним.
Открываем в браузере http://localhost:81/setup.php. Здесь надо просто следовать инструкциям.
В версии 2.3 после установки не обязательно удалять setup.php – можно просто указать пароль. Веб гуй нам отдаст хэш, мы его пропишем в конфиг в $CONF['setup_password']. Но надо не забыть после установки сразу же здесь создать админскую учётную запись – без неё войти в админку Postfixadmin не получится.
После установки в нашей базе данных появятся таблицы:

mysql> show tables;
+———————–+
| Tables_in_mail |
+———————–+
| admin |
| alias |
| alias_domain |
| config |
| domain |
| domain_admins |
| fetchmail |
| log |
| mailbox |
| quota |
| quota2 |
| vacation |
| vacation_notification |
+———————–+
13 rows in set (0,00 sec)

Сразу же можно создать парочку тестовых почтовых ящиков.

Dovecot

Следующим шагом поднимем IMAP/POP3 сервер. Ранее мы установили Dovecot, который и будет отвечать за эту часть нашего почтового сервера. Он достаточно прост в настройке, к тому же изначально рассчитан на максимальную безопасность и надежность. Dovecot может обслуживать запросы пользователей с помощью протоколов imap, imaps, pop3, pop3s. Еще один плюс этой связки: пользователи Exim 4.64+ при отправке сообщения могут быть аутентифицированы непосредственно с помощью средств Dovecot (в частности SASL – Simple Authentication and Security Layer) без привлечения дополнительных библиотек вроде Cyrus SASL. Это, естественно, упрощает настройку и повышает общую надежность всей системы.

У Dovecot два основных конфигурационного файла: dovecot.conf и dovecot-sql.conf. Отредактируем их:

$ vim /etc/dovecot/dovecot.conf

# Директория для временных файлов
base_dir = /var/run/dovecot/

# Протоколы, по которым обслуживаем пользователей. Доступны еще imaps и pop3s (SSL).
protocols = imap pop3

# IMAP слушаем на 143-м порту
protocol imap {
listen = 127.0.0.1:143
}
# POP3 слушаем на 110-м порту
protocol pop3 {
listen = 127.0.0.1:110
}

# Здесь можем отключить аутентификаию открытым текстом, если не включён SSL/TLS
# С локалхоста, впрочем, он всё равно будет разрешать такую аутентификацию
disable_plaintext_auth = no

# Убивать все процессы IMAP и POP3 при закрытии родительского процесса dovecot
shutdown_clients = yes

# Логфайл вместо syslog()
log_path = /var/log/dovecot.log

# Сюда пишутся информационные и дебаг-сообщения
info_log_path = /var/log/dovecot.log

# Формат таймстэмпа (strftime()) для записи в лог
log_timestamp = "%Y-%m-%d %H:%M:%S "

# Чем будем логиниться в syslog()
syslog_facility = mail

# Отключаем SSL/TLS. Все равно оно нужно только если используем pop3s и imaps
ssl_disable = yes

# Директория где аутентификационный процесс размещает UNIX сокеты
# которые требуются для процесса логина. Сокеты создаются от суперпользователя,
# поэтому можно не беспокоится насчёт прав. При старте dovecot всё
# содержимое этой директории удаляется.
login_dir = /var/run/dovecot/login

# Делаем chroot для процесса аутентификации dovecot
login_chroot = yes

# Юзер, использующийся в процессе логина
login_user = dovecot

# Каждый логин должен быть обработан своим собственным процессом ('yes'),
# или один процесс может обрабатывать несколько соединений ('no'). 'yes' более
# секьюрно, особенно если включено SSL/TLS. 'no' быстрее работает, ибо нет
# необходимости создавать процесс на каждое соединение
login_process_per_connection = yes

# Число запускаемых процессов логина. Если 'login_process_per_connection'
# равно 'yes', то это число свободных процессов ожидающих подключения
# пользователей.
login_processes_count = 3

# Максимальное число соединений разрешённых в сосоянии 'логина'. Когда
# достигается указанный тут лимит, самые старые связи разрываются
login_max_processes_count = 128

# Приветственное сообщение для клиентов.
login_greeting = Dovecot ready on mydomain.ru.

# Разделённый пробелами лист элементов, которые будут записаны в лог. Непустые
# элементы будут объединены через запятую.
login_log_format_elements = user=<%u> method=%m rip=%r lip=%l %c

# Расположение пользовательских ящиков
mail_location = maildir:/var/vmail/%d/%u

# Группа, которой разрешены некоторые привилегированные операции
mail_privileged_group = mail

# Включаем режим дебага, на первых порах очень полезно
mail_debug = yes

#Разрешённый диапазон UIDов для пользователей.
#Так мы защитимся от подключения демонов или системных пользователей.
#Как root подключиться не получится в любом случае
first_valid_uid = 1150
last_valid_uid = 1150

protocol imap {
# Месторасположение исполняемого файла авторизации
login_executable = /usr/lib/dovecot/imap-login
# Исполняемый файл IMAP
mail_executable = /usr/lib/dovecot/imap
imap_max_line_length = 65536
}
protocol pop3 {
login_executable = /usr/lib/dovecot/pop3-login
mail_executable = /usr/lib/dovecot/pop3
pop3_uidl_format = %08Xu%08Xv
}
protocol lda {
# Куда слать письмо об отказах и превышении квот
postmaster_address = webmaster@mydomain.ru
hostname = mydomain.ru
sendmail_path = /usr/lib/sendmail
# Путь к сокету для поиска пользователей
auth_socket_path = /var/run/dovecot/auth-master
}

# Парметры для дебага
auth_verbose = yes
auth_debug = yes
auth_debug_passwords = yes

auth default {
# Список требуемых механизмов аутентификации, разделённый пробелами
#   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi
mechanisms = plain login digest-md5 cram-md5

passdb sql {
# Путь к файлу, где у нас прописаны все параметры базы данных
args = /etc/dovecot/dovecot-sql.conf
}
userdb sql {
# Path for SQL configuration file
args = /etc/dovecot/dovecot-sql.conf
}

# Юзер, от которого будет работать процесс аутентификации
user = nobody

socket listen {
master {
path = /var/run/dovecot/auth-master
mode = 0600
user = vmail
group = mail
}
client {
# Этот сокет мы будем использовать для аутентификации Exim
path = /var/run/dovecot/auth-client
mode = 0660
}
}
}
dict {
}
plugin {
}

$ vim /etc/dovecot/dovecot-sql.conf

driver = mysql
connect = host=localhost dbname=mail user=postmaster password=mypassword
# Об этом выше уже говорилось. Здесь указываем механизм шифрования паролей
default_pass_scheme = MD5-CRYPT
password_query = SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, 'maildir:/var/vmail/%d/%n' as userdb_mail, 1150 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = '%u' AND active = '1'
user_query = SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n' as mail, 1150 AS uid, 8 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1'

Exim

Exim это довольно быстрый в работе и простой в настройке Mail Transport Agent. Пакет установлен, его конфигурационные файлы находятся в /etc/exim4. В Ubuntu он по умолчанию стартует сразу после установки, так что есть возможность сразу его проверить:

$ telnet localhost 25

Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
220 deus ESMTP Exim 4.71 Mon, 15 May 2010 22:38:02 +0300

Сразу конфигурим основные параметры:

$ sudo dpkg-reconfigure exim4-config

1. Тип конфигурации
интернет-сайт; приём и отправка почты напрямую, используя SMTP

2. Почтове имя
mydomain.ru

3. Список IP-адресов, с которых Exim ожидает подключение
Оставляем пустым – ждем почту с любых адресов

4. Список доменов получателей
mydomain.ru;mydomain2.ru

5. Домены для релея
Оставляем пустым – не будем релеить почту.

6. IP-адреса, с которых разрешён релей.
Оставляем пустым.

7. Сокращать кол-во DNS-запросов до минимума
Нет

8. Место доставки локальной почты
mbox формат в /var/mail/

9. Разделить конфигурацию на маленькие файлы
Нет

10. Получатель почты, адресованной root и postmaster
root

После внесения изменений, они сразу вступают в силу:
* Stopping MTA for restart [ OK ]
* Restarting MTA [ OK ]

Всё это можно прописать и вручную в файл /etc/exim4/update-exim4.conf.conf. Но чтобы изменения вступили в силу, надо сгенерировать мастер-файл /var/lib/exim4/config.autogenerated с помощью команды

$ sudo update-exim4.conf

Теперь открываем конфиг /etc/exim4/exim4.conf (если его нет, то создаем или копируем из template) и редактируем его:


# Имя хоста. Используется в EHLO.
# Фигурирует в других пунктах, если они не заданы
# По умолчанию используется то, что вернёт функция uname()
primary_hostname = mydomain.ru

# Данные для подключения к базе данных
# hide в начале означает, то нерутовые пользователи командой exim -bV не увидят
# этих значений
hide mysql_servers = localhost/mail/postmaster/ApN40Sy_t

# Задаём список локальных доменов. В данном случае спрашиваем у MySQL

DOMAIN_QUERY    = SELECT domain FROM domain WHERE \
domain='${domain}' AND active='1'
domainlist local_domains = ${lookup mysql{DOMAIN_QUERY}}

# Таким же образом задаём список доменов, с которых разрешён релей.
domainlist relay_to_domains = ${lookup mysql{DOMAIN_QUERY}}

# Список хостов, с которых разрешён релей без авторизации.
hostlist   relay_from_hosts = localhost:127.0.0.1/8:192.168.0.0/24

# Списки ACL для проверки почты
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data

# Здесь указываем сокет внешнего антивируса ClamAV. Пока что оставим закомменченным
# Включим его позже
# av_scanner = clamd:/var/run/clamav/clamd.ctl
# Здесь укажем TCP/IP сокет для SpamAssassin
# spamd_address = 127.0.0.1 783

# Порт, на котором SMTP демон будет слушать входящие подключения
daemon_smtp_ports = 25 : 465

# Имя домена добавляемое для локальных отправителей (реальных
# юзеров системы) т.е. почта отправляемая от root, будет от
# root@домен_указанный_здесь. Если пункт незадан, то используется
# имя хоста из primary_hostname.
qualify_domain = mydomain.ru

# Имя домена добавляемое для локальных получателей
qualify_recipient = mydomain.ru

# запрещаем работу доставки под юзером root - в целях безопасности
never_users = root

# Проверяем соответствие прямой и обратной зон для всех хостов.
# При необходимости лучше раскомментировать это позже
#host_lookup = *

# Здесь можно включить запросы ident на входящие SMTP запросы.
# Вещь ненужная и неактуальная. Отключаем
#rfc1413_hosts = *
rfc1413_query_timeout = 0s

# Период повторных попыток доставки сообщений об ошибке
ignore_bounce_errors_after = 1d

# Через пару недель удалим то, что так и не смогли доставить
timeout_frozen_after = 14d

# Выбираем, что мы будем логировать
# + - писать в логи,
# - - Не писать в логи.
# +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_parents \
+connection_reject \
+incoming_interface \
+lost_incoming_connection \
+received_sender \
+received_recipients \
+smtp_confirmation \
+smtp_syntax_error \
+smtp_protocol_error \
-queue_run

begin acl

# Правила для всех получателей. Выше мы включили этот ACL

acl_check_rcpt:

# Сразу принять то, что пришло с локалхоста не по TCP/IP
accept  hosts = :

# Запрещаем письма для локальных доменов, содержащие в локальной части
# символы @; %; !; /; |.
deny    message       = Restricted characters in address
domains       = +local_domains
local_parts   = ^[.] : ^.*[@%!/|]

# Проверяем недопустимые символы для
# нелокальных получателей:
deny    message       = Restricted characters in address
domains       = !+local_domains
local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./

# Принимать почту на постмастера, не проверяя отправителя.
# Может использоваться для спама
accept  local_parts   = postmaster
domains       = +local_domains

# Здесь можно запретить отправку от непроверенных пользователей
# Если нужно отправлять почту от logwatch etc., то лучше убрать

require verify        = sender

accept  hosts         = +relay_from_hosts
control       = submission
require message = relay not permitted
domains = +local_domains : +relay_to_domains
require verify = recipient

# Все, что сюда дошло, пропускаем
accept

# Здесь мы проверяем тело сообщения

acl_check_data:
# Здесь проверка на вирусы
warn    malware    = *
message    = This message contains a virus ($malware_name).

# А здесь - проверка на спам
warn    spam       = nobody
add_header = X-Spam-Flag: YES\n\
X-Spam_score: $spam_score\n\
X-Spam_score_int: $spam_score_int\n\
X-Spam_bar: $spam_bar\n\
X-Spam_report: $spam_report

# Остальное пропускаем
accept

begin routers

# Поиск маршрута к хосту в DNS. Если маршрут не найден в DNS -
# то это `унроутабле аддресс`. Не проверяются локальные
# домены, 0.0.0.0 и 127.0.0.0/8
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more

# смотрим альясы

system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{SELECT goto FROM alias WHERE \
address='${quote_mysql:$local_part@$domain}' OR \
address='${quote_mysql:@$domain}'}}

# Всё что осталось - это локальные адресаты.
# Доставляем почту в dovecot
dovecot_user:
driver = accept
condition = ${lookup mysql{SELECT goto FROM \
alias WHERE \
address='${quote_mysql:$local_part@$domain}' OR \
address='${quote_mysql:@$domain}'}{yes}{no}}
transport = dovecot_delivery

begin transports

# На удалённые хосты доставляем по SMTP

remote_smtp:
driver = smtp

# Доставка локальным адресатам - в dovecot
# Надо заметить что тут использовалась ранее прямая доставка
# в директорию, но щас с портами стал-таки устанавливаться deliver
# программа dovecot занимающаяся доставкой мессаг.
# Соответственно юзаем его.
dovecot_delivery:
driver = pipe
command = /usr/lib/dovecot/deliver -d $local_part@$domain
message_prefix =
message_suffix =
delivery_date_add
envelope_to_add
return_path_add
log_output
user = vmail

# Доставка через пайп

address_pipe:
driver = pipe
return_output

# Транспорт для автоответов

address_reply:
driver = autoreply

begin retry

# Правила для повторных попыток доставки
# Сначала попытки раз 15 мин в течение 2 часов, потом, начиная с
# интервала в 1 час, увеличивая его в 1.5 раза, пытаемся доставить 16 часов.
# Потом раз в 6 часов, до истечения 4 суток

# Address or Domain    Error       Retries
# -----------------    -----       -------

*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h

# Преобразование адресов нам не нужно

begin rewrite

begin authenticators

# Здесь разные механизмы авторизации для разных клиентов
auth_plain:
driver = plaintext
public_name = PLAIN
server_prompts = Username:: : Password::
server_condition = ${if crypteq{$auth3}{${lookup mysql{SELECT password FROM \
mailbox WHERE username = '${quote_mysql:$auth2}'}}}{yes}{no}}
server_set_id = $auth2

auth_login:
driver = plaintext
public_name = LOGIN
server_condition = ${if crypteq{$auth2}{${lookup mysql{SELECT password FROM \
mailbox WHERE username = '${quote_mysql:$auth1}'}}}{yes}{no}}
server_prompts = Username:: : Password::
server_set_id = $auth1

# А вот так мы можем передать аутентификацию на Dovecot SASL.
# Впрочем, CRAM-MD5 все равно не прокатит
auth_cram_md5:
driver = dovecot
public_name = CRAM-MD5
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth2

Здесь всё правильно. Для внешнего ящика Exim выбрал транспорт remote_smtp и определил адрес сервера, а для локального ящика он выбрал другую судьбу – Dovecot.

Дальше проверим, как Exim отдаст почту в Dovecot:

$ exim -v webmaster
To: webmaster@mydomain.ru
From: root@mydomain.ru
Subj: test
test
^D
LOG: MAIN
<= root@mydomain.ru U=root P=local S=329  delivering 1Ni6i6-00061j-T4 LOG: MAIN   => webmaster  R=dovecot_user T=dovecot_delivery
LOG: MAIN
Completed

Из Exim ушло. Смотрим в лог Dovecot:

deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: auth input: home=/var/vmail/mydomain.ru/webmaster
deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: auth input: mail=maildir:/var/vmail/mydomain.ru/webmaster
deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: auth input: uid=1150
deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: auth input: gid=8
deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: auth input: quota=dirsize:storage=0
dovecot: 2010-02-18 16:47:03 Info: auth-worker(default): mysql: Connected to localhost (mail)
dovecot: 2010-02-18 16:47:03 Info: auth-worker(default): sql(webmaster@mydomain.ru): SELECT '/var/vmail/mydomain.ru/webmaster' as home, 'maildir:/var/vmail/mydomain.ru/webmaster' as mail, 1150 AS uid, 8 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = 'webmaster@mydomain.ru' AND active = '1'
dovecot: 2010-02-18 16:47:03 Info: auth(default): master out: USER	1	webmaster@mydomain.ru	home=/var/vmail/mydomain.ru/webmaster	mail=maildir:/var/vmail/mydomain.ru/webmaster	uid=1150	gid=8	quota=dirsize:storage=0
deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: maildir: data=/var/vmail/mydomain.ru/webmaster
deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: maildir++: root=/var/vmail/mydomain.ru/webmaster, index=, control=, inbox=/var/vmail/mydomain.ru/webmaster
deliver(webmaster@mydomain.ru): 2010-02-18 16:47:03 Info: msgid=: saved mail to INBOX

Здесь всё отлично. Dovecot почту получил и положил в нужное место. Само собой, все эти проверки пройдут, если заранее создать в postfixadmin почтовый ящик.
Теперь эту почту можно попробовать забрать. Если мы включали поддержку IMAP, то делаем так:

$ telnet localhost 143
Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
* OK Dovecot ready on mydomain.ru.
a login webmaster@mydomain.ru password
a OK Logged in.
b select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 1 EXISTS
* 1 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1266412906] UIDs valid
* OK [UIDNEXT 10] Predicted next UID
b OK [READ-WRITE] Select completed.
a fetch 1:1 body[header.fields (date from subject)]
* 1 FETCH (FLAGS (\Seen) BODY[HEADER.FIELDS (DATE FROM SUBJECT)] {94}
Subject: test
From: root@mydomain.ru
Date: Thu, 18 Feb 2010 16:47:02 +0300

)
a OK Fetch completed.
a logout
* BYE Logging out
a OK Logout completed.
Connection closed by foreign host.

Вот. Письмо преспокойно лежит себе в почте.

Вот ещё несколько команд, которые могут оказаться полезными:

exim -bd -d+all
Если какие-то проверки не проходят, то этой командой можно запустить Exim в debug-режиме. Для этого, правда, сначала придётся загасить основной процесс. Иногда полезно.

exim -bP
Выведет единой портянкой все заданные конфигурационные значения.

exim -bV
Выведет информацию о версии и ещё кое-что. Заодно проверяет синтаксис конфигурации.

SpamAssassin

Для защиты от спама будем использовать spamassassin.

# apt-get install spamassassin

После установки он по умолчанию выключен. Поэтому открываем файл /etc/default/spamassassin и меняем строку:

ENABLED=1

ClamAV
Для защиты от вирусов будем использовать ClamAV. С ним придётся повозиться чуть побольше.

# apt-get install clamav-daemon clamav-freshclam clamav-testfiles

Для начала надо дать ему права на доступ к временной директории Exim, так как по умолчанию доступ туда есть только у пользователя Debian-exim.

# ls -ld /var/spool/exim4/
drwxr-x— 5 Debian-exim Debian-exim 4096 2010-02-15 22:36 /var/spool/exim4/

# adduser clamav Debian-exim
# chmod -R g+w /var/spool/exim4
# chmod -R g+s /var/spool/exim4

Всё. Рестартим ClamAV. Если ClamAV не запущен, то запускаем:

# /etc/init.d/clamav-daemon restart

С помощью команды freshclam можно обновлять вирусные базы. Можно запуск этой команды засунуть в cron.

Опять Exim

Возвращаемся к конфигу exim4.conf и прописываем интерфейсы к ClamAV и к SpamAssassin в основной части конфига:

av_scanner = clamd:/var/run/clamav/clamd.ctl
spamd_address = 127.0.0.1 783

Далее прокручиваем конфиг в секцию ACL и дописываем правила для писем со спамом или вирусами:

acl_check_data:

deny    malware    = *
message    = This message contains a virus ($malware_name).

warn    spam       = Debian-exim:true
add_header = X-Spam-Flag: YES\n\
X-Spam_score: $spam_score\n\
X-Spam_score_int: $spam_score_int\n\
X-Spam_bar: $spam_bar\n\
X-Spam_report: $spam_report

accept

Сохраняем, перезагружаем конфиг. Смотрим.
Надо проверить, как у нас работает ClamAV и SpamAssassin.

Для проверки ClamAV пытаемся заслать письмо с текстом

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

И смотрим при этом в /var/log/clamav/clamav.log:

$ tail -f /var/log/clamav/clamav.log
Sat Feb 20 14:34:50 2010 -> /var/spool/exim4/scan/1Ninbm-0002F8-EZ/1Ninbm-0002F8-EZ.eml: Eicar-Test-Signature FOUND

Письмо при этом режектится Exim'ом.

А для проверки SpamAssassin пытаемся заслать письмо с текстом

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

При этом в режиме дебага Exim напишет нам следующее:

14:47:18  9217 processing "warn"
14:47:18  9217 check spam = nobody
14:47:18  9217 trying server 127.0.0.1, port 783
14:47:18  9217 waiting for data on socket
14:47:33  9217 waiting for data on socket
14:47:33  9217 waiting for data on socket
14:47:33  9217 expanding: X-Spam-Flag: YES\nX-Spam_score: $spam_score\nX-Spam_score_int: $spam_score_int\nX-Spam_bar: $spam_bar\nX-Spam_report: $spam_report
14:47:33  9217    result: X-Spam-Flag: YES
14:47:33  9217 X-Spam_score: 1001.5
14:47:33  9217 X-Spam_score_int: 10015
14:47:33  9217 X-Spam_bar: +++++++++++++++++++++++++++++++++++++++++++++++++++
14:47:33  9217 X-Spam_report: Spam detection software, running on the system "deus", has
14:47:33  9217 	identified this incoming email as possible spam.  The original message
14:47:33  9217 	has been attached to this so you can view it (if it isn't spam) or label
14:47:33  9217 	similar future email.  If you have any questions, see
14:47:33  9217 	the administrator of that system for details.
14:47:33  9217 	Content preview:  XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
14:47:33  9217 	[...]
14:47:33  9217 	Content analysis details:   (1001.5 points, 5.0 required)
14:47:33  9217 	pts rule name              description
14:47:33  9217 	—- ———————- ————————————————–

DNS
Если планируется, что почтовый сервер будет смотреть в интернет, то есть смысл задуматься о добавлении MX и PTR-записей в DNS, ибо для уменьшения объёмов нежелательной корреспонденции почти все почтовые серверы-получатели проверяют наличие PTR записи для хоста, с которого происходит отправка, а при отправке почты на домен запрашивают в DNS MX запись нужного домена. Предполагается, что PTR запись в обратной зоне для IP адреса должна соответствовать имени отправляющего почтового сервера, которым он представляется в процессе SMTP сессии. Если это условие не выполняется, то наш IP-адрес очень скоро пополнит дружный коллектив адресов в серых списках.

Итак, проверим MX запись:

$ host -t mx mydomain.ru
mydomain.ru has no MX record

Такой нету.

Значит, нужно обратиться к администратору своей зоны (если вы с ним одно лицо, то вообще замечательно) и попросить прописать MX для доменного имени. Часто регистраторы позволяют самостоятельно через web-интерфейс добавлять новые записи.

$ host -t mx mydomain.ru
mydomain.ru mail is handled by 10 mydomain.ru.

Вот. А это то, что нужно.

Теперь PTR проверяем такой командой:

$ host -t ptr <my.ip.add.ress>
или
$ dig -x <my.ip.add.ress>

Само собой, ответ не тот, который нам нужен. Опять же надо обращаться к администратору DNS, но на этот раз к владельцу пула адресов, то есть к провайдеру. Здесь тоже не должны возникать проблемы.

Выполнив все эти процедуры, можно очень надолго забыть о любых проблемах с почтой. Но прежде, чем окончить разговор о DNS, хочу уточнить, что, если на этом почтовом сервере потребуется обслуживать несколько доменов, то PTR запись лучше указать только для одного из них, а для всех остальных в MX записи указать доменное имя того самого первого домена с обраткой.

Оставить Ответ

Вы можете войти чтобы написать комментарий.

Halfi в сети