Почтовый сервер — в каждый дом. Exim+Dovecot+SpamAssasin+ClamAV+PostfixAdmin

Date February 20th, 2010 Author Vitaly Agapov

“А если вы на него бочку катите, то это уже контейнерная перевозка. Этим Трансагентство занимается.”
— Печкин

exim

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

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

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

И всё это добро будет у нас стоять на Ubuntu 9.10.

Подготовка

Итак, ставим основной необходимый софт (само собой предполагая, что 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:

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

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

<VirtualHost *:81>
  ServerName postfixadmin
  DocumentRoot /var/www/postfixadmin
  <Directory /var/www/postfixadmin>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>
  ErrorLog /var/log/apache2/error_postfixadmin.log
  LogLevel warn
  CustomLog /var/log/apache2/access_postfixadmin.log combined
</VirtualHost>

В файле 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
    # Если надо открыть доступ снаружи, то надо указать *:143
}
# POP3 слушаем на 110-м порту
protocol pop3 {
    listen = 127.0.0.1:110
    # Если надо открыть доступ снаружи, то надо указать *: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'
# Вышеуказанные команды представлены для случая, если в поле username указаны целиком почтовые ящики в виде username@domain. При этом можно устраивать несколько почтовых доменов на одном сервере, но и для аутентификации придётся предоставлять этот username целиком. Если в поле username в базе содержатся только логины, то команды можно переделать так:
# password_query = SELECT username as user, password, concat('/var/vmail/',domain,'/%n') as userdb_home, concat('maildir:/var/vmail/',domain,'/%n') as userdb_mail, 1150 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = '%n' AND active = '1'
# user_query = SELECT concat('/var/vmail/',domain,'/%n') as home, concat('maildir:/var/vmail/',domain,'/%n') as mail, 1150 AS uid, 8 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = '%n' 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/password

# Задаём список локальных доменов. В данном случае спрашиваем у 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, можно сделать несколько полезных проверок.
Для начала можно проверить роутинг. В этом поможет команда exim -bt:

$ exim -bt webmaster@mail.ru
webmaster@mail.ru
router = dnslookup, transport = remote_smtp
host mxs.mail.ru [94.100.176.20] MX=10
$ exim -bt webmaster@mydomain.ru
webmaster@mydomain.ru
<-- webmaster@mydomain.ru
router = dovecot_user, transport = dovecot_delivery

Здесь всё правильно. Для внешнего ящика 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 записи указать доменное имя того самого первого домена с обраткой.

Tags: , , ,
Category: Linux | 28 Comments »

Comments

28 комментариев на “Почтовый сервер — в каждый дом. Exim+Dovecot+SpamAssasin+ClamAV+PostfixAdmin”

  1. Сергей

    Подскажите адрес репозитория, из которого забирается exim 4.71, поскольку исполняя apt-get install exim4 exim4-base exim4-config exim4-daemon-heavy, я получаю exim 4.69

  2. Vitaly Agapov

    В репозиториях Ubuntu 10.04 Lucid Lynx вовсю доступна версия Exim 4.71. Так что если не терпится (как мне), то можно изменить в sources.list karmic на lucid и сделать apt-get update:

    # apt-cache showpkg exim4
    Package: exim4
    Versions:
    4.71-3ubuntu1 (/var/lib/apt/lists/ru.archive.ubuntu.com_ubuntu_dists_lucid_main_binary-i386_Packages)

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

  3. GerasikM

    Попробовал настроить как Вы написали, на этапе проверки exim выдает ошибку:
    LOG: MAIN
    <= root@testserver.ru U=root P=local S=357
    root@Test-Server:~# delivering 1OHy98-0000Sf-8N
    LOG: MAIN
    == webmaster@testserver.ru R=dovecot_user T=dovecot_delivery defer (0): Child process of dovecot_delivery transport returned 75 (could mean temporary error) from command: /usr/lib/dovecot/deliver
    В логе dovecot:
    deliver(webmaster@testserver.ru): Error: userdb lookup: connect(/var/run/dovecot/auth-master) failed: No such file or directory
    Не подскажите где может быть ошибка?

  4. Vitaly Agapov

    Могу только гадать.
    Судя по всему, dovecot не может найти сокет auth-master. Вообще, он должен его создавать при первом старте. Так что, если сам dovecot запущен, но файла нет, то нужно проверить права – может ли процесс dovecot создать директорию в /usr/local и может ли создавать файлы в этой директории, если она уже есть. Если сам сокет есть, то можно проверить его права на чтение.
    В общем, покажите вывод команд
    ls -l /var/run/dovecot/
    ls -ld /var/run/dovecot/

  5. Vitaly Agapov

    Кстати, в версии Dovecot, начиная с 1.2 параметр ssl_disable заменён на ssl.
    Так что строку ssl_disable = yes надо заменить на ssl = no.

  6. Алекс

    Не подскажете, как донастроить dovecot чтоб почта забиралась у хостера?

    У хостера все складывается в один ящик. Необходимо чтоб почтовый сервер в офисе забирал с него и рассортировывал по пользователям.

  7. Vitaly Agapov

    Ничем подобным заниматься не приходилось к сожалению. Но думаю, что надо смотреть в сторону fetchmail.
    http://ru.wikipedia.org/wiki/Fetchmail

  8. kui

    что вводить в почтовой клиент для подключения. в сервер imap, pop, smtp, главное какие порты?

  9. Vitaly Agapov

    Вводить параметры надо те, которые указаны в соотвествующем конфиге. Для POP3 и IMAP – в конфиге Довекота. По умолчанию это, соответственно, 110 и 143. Стандартные порты могут быть переопределены директивами protocol в dovecot.conf.
    Порты, по которым почту можно отдавать из клиента по SMTP, прописаны в exim4.conf директивой daemon_smtp_ports. По умолчанию это всегда 25.

    Механизмы проверки подлинности также можно смотреть в конфигах. В dovecot.conf это задается директивой mechanisms. Врочем, клиенты обычно достатончо умны, чтобы самостоятельно определить тип проверки пароль/Digest-MD5/Cram-MD5 etc.

    Адрес сервера – по обстоятельствам.

    Имя пользователя и пароль – какой задали. Единственная тонкость – в зависимости от конфигурации и структуры базы данных имя пользователя может потребоваться в виде login@domain. Про это немного написано в коде конфига dovecot-sql.conf. Если не хочется долго разбираться, то можно просто попробовать так и эдак.

  10. Александр

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

  11. Игорь

    Ах да я тут накнулся на 1 темку про почту :
    установка связки Postfix+LDAP(MySQL)+SpamAssassin+ClamAV+AmaViS+Dovecot+RoundCube
    работает из коробки, прост в управлении, возможность изменить кофигурацию как угодно
    http://www.iredmail.ru

    короче скрипт сам скачивает что надо и потом тупо задает вопросы о доменом имени и т.п.

  12. Игорь

    ну как бы это не панацея, но все же если надо быстро розвенуть а времени в обрез, ну иль нет знаний в этой области почтовиков, то можно развернуть а потом сесть и поразбиратся…

  13. Игорь

    Собственно у меня такая проблема, попал мне сервак на Ubuntu 10.04 + стоит почтовый сервер iredmail но проблема с почтой т.е почта приходит минут через 15-20 получателю, предыдущий админ ссылается на провайдера. Но после долгого поиска на форумах это бок iredmail. Я в Linux-e новичок.

  14. Сергей

    Каким образом появятся таблицы?

    После установки в нашей базе данных появятся таблицы:

    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)

  15. Vitaly Agapov

    После установки открываем в браузере http://что-то-там/setup.php. Здесь надо просто следовать инструкциям.
    В результате PostfixAdmin создаст необходимые таблицы.

  16. Сергей

    Спасибо, не знал что PostfixAdmin создает таблицы.

  17. Алексей

    первый раз настраивал Exim и с помощью данного ХауТу настроил. Огромное спасибо.
    Наткнулся вот на какие грабли.
    1. Конфиг Dovecot претерпел изменения, про ssl тут уже говорилось, но есть и ещё другие грабли
    Во первых изменился синтаксис описания сервисов.
    Вам поможет исправить это команда:
    doveconf -n > dovecot-new.conf
    потом отредактируйте нужные настройки.
    Часть настроек вообще не используется.
    Так же в логах выскакивали ошибки на сервис auth-worker, на то что его uid не соответствует тому который стоит на папке vmail
    Пришлось в конфиг dovecot.conf добавить:

    service auth-worker {
    unix_listener auth-worker {
    group = vmail
    mode = 0600
    user = vmail
    }
    user = vmail
    }

    После этого почта стала ходить нормально.

    Пока вроде всё. Огромное спасибо за How-To.

    Вопрос ещё – как к этому прикрутить TLS или включить ssl и этого хватит?
    может ссылку какую на это дадите?

  18. Алексей

    Единственный момент – не работает spamassasin.
    тестовую строку пропускает.

    и спам всё равно приходит,

  19. Артем

    Алексей нужна Ваша помощь
    свяжитесь со мной
    kasper-colomna@mail.ru

  20. Артем

    не могу побороть dovecot
    _____________________

    2012-07-30 16:30:04 imap-login: Error: Timeout waiting for handshake from auth server. my pid=1642, input bytes=0
    2012-07-30 16:30:04 imap-login: Error: Timeout waiting for handshake from auth server. my pid=1641, input bytes=0
    2012-07-30 16:30:04 pop3-login: Error: Timeout waiting for handshake from auth server. my pid=1650, input bytes=0
    2012-07-30 16:30:04 pop3-login: Error: Timeout waiting for handshake from auth server. my pid=1638, input bytes=0
    2012-07-30 16:30:04 pop3-login: Error: Timeout waiting for handshake from auth server. my pid=1640, input bytes=0
    2012-07-30 16:30:04 imap-login: Error: Timeout waiting for handshake from auth server. my pid=1643, input bytes=0
    2012-07-30 16:30:04 auth: Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth
    2012-07-30 16:30:04 auth: Fatal: Unknown database driver ‘mysql’
    2012-07-30 16:30:04 master: Error: service(auth): command startup failed, throttling

  21. visaversa

    А что значит ошибка dovecota
    Error: userdb lookup: connect(/var/run/dovecot/auth-master) failed: Connection refused

    Дал chmod -R 777 /var/run/dovecot
    и все равно…

  22. Vitaly Agapov

    Попробуйте:
    sudo apt-get install dovecot-sieve dovecot-managesieved libsieve2-1

  23. Nurlan

    можно ли создать почтовый сервер если айпи динамически?

  24. Vitaly Agapov

    Есть такой замечательный сервис – DyDNS (http://dyn.com/dns/). Он позволяет привязать домен к динамическому ip. Дальше уже можно экспериментировать.

  25. Nurlan

    проверяю ptr запись 2 командами, в 1 пишет что нет, а в другой что есть?! что за фигня? ах да, почтовый сервер сделал локальный 127,0,0,1 ( пишу письма самому себе)
    root@nurlan:/home/nurlan# host -t ptr nurlan.kz
    nurlan.kz has no PTR record

    root@nurlan:/home/nurlan# host 127.0.0.1
    1.0.0.127.in-addr.arpa domain name pointer nurlan.kz.

  26. Иван

    Не могли бы выложить пример конфига с изменениями не как не могу разобраться какие изменения.

  27. solution

    Всем, у кого ошибка Error: userdb lookup: connect(/var/run/dovecot/auth-master) failed: No such file or directory

    Решение:

    Внутри секции auth default {..
    socket listen {
    …. <—- сюда вставить…
    }
    }

    …вот это (комментарии в нужных местах снять)
    #master {
    # Master socket provides access to userdb information. It's typically
    # used to give Dovecot's local delivery agent access to userdb so it
    # can find mailbox locations.
    #path = /var/run/dovecot/auth-master
    #mode = 0600
    # Default user/group is the one who started dovecot-auth (root)
    #user =
    #group =
    #}

  28. Max

    при настройке MySQL пользователь получается postmaster , а не mail. Исправьте пжл.

    Спасибо, за статью

    Здесь запоминаем логин и пароль для доступа к созданной базе данных mail. В данном случае логин – mail, папроль – password. – See more at: http://agapoff.name/exim-dovecot.html#sthash.EgwLRkVM.dpuf

    Здесь запоминаем логин и пароль для доступа к созданной базе данных mail. В данном случае логин – mail, папроль – password. – See more at: http://agapoff.name/exim-dovecot.html#sthash.EgwLRkVM.dpuf

Leave a comment

 Comment Form