Сам себе почтальон: настраиваем свой SMTP/IMAP-сервер (часть 1)

В свете последних разоблачений о том, что АНБ читает нашу почту (кто б сомневался), у публичных email-сервисов стало еще одним плюсом меньше.
Ну а раз плюсов стало меньше, то мыслей стало больше. Например о том, что неплохо было бы иметь свой собственный, валидный на все сто почтовый сервер с доступом из любой точки мира, поддержкой шифрования – чтобы, значит, все как у взрослых.
На первый взгляд все просто – ставим sendmail Postfix, прикручиваем к нему dovecot в качестве MDA – и дело в шляпе! Или нет?
Как оказалось, почти все руководства написаны в эпоху dovecot 1.x. В wheezy же предлагается уже dovecot2. Формат конфиг-файла при этом у них значительно отличается – до полной невозможности использования.

Ну а раз информация не находится в гугле за пять минут – надо написать howto, чтобы не тратить время в следующий раз.

Процесс установки описывать не буду. Нам понадобятся postfix, postfix admin и dovecot(будем считать, что в качестве СУБД у нас MySQL, и все нужное для LAMP уже стоит):

# sudo apt-get install postfix postfix-mysql libsasl2-modules libsasl2-modules-sql postfixadmin php5-fpm php5-imap php5-mysql php5-mcrypt php5-intl ssl-cert mysqmail-dovecot-logger dovecot-sieve dovecot-mysql dovecot-managesieved dovecot-lmtpd dovecot-imapd dovecot-common dovecot-antispam
.

Первым делом настраиваем postfix. Открываем в любимом редакторе /etc/postfix/main.cf:
/etc/postfix/main.cf

myhostname = mail.nixman.info
mydomain = nixman.info
myorigin = /etc/mailname
inet_interfaces = all
inet_protocols = ipv4
mynetworks_style = host
smtpd_banner = $myhostname ESMTP $mail_name
biff = no
append_dot_mydomain = no
delay_warning_time = 4h
readme_directory = no
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname localhost.$mydomain, localhost localhost.localdomain
relayhost =
mynetworks = 127.0.0.0/8
mailbox_size_limit = 0
recipient_delimiter = +
#local_transport = virtual
#local_recipient_maps = $virtual_mailbox_maps
strict_rfc821_envelopes = yes
disable_vrfy_command = yes
queue_directory = /var/spool/postfix
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 15
smtpd_error_sleep_time = 20
anvil_rate_time_unit = 60s
smtpd_client_connection_count_limit = 20
smtpd_client_connection_rate_limit = 30
smtpd_client_message_rate_limit = 30
smtpd_client_event_limit_exceptions = 127.0.0.0/8
smtpd_client_connection_limit_exceptions = 127.0.0.0/8

maximal_queue_lifetime = 1d
bounce_queue_lifetime = 1d
queue_run_delay = 300s
minimal_backoff_time = 300s

Секция настройки почтовых ящиков.
Настройки берем из БД postfixadmin, с помощью которого будем создавать/удалять/менять ящики, почтовые домены и алиасы.

# ---------------------- VIRTUAL DOMAINS START ----------------------
virtual_alias_maps = mysql:/etc/postfix/virtual-alias-maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/virtual-mailbox-maps.cf
virtual_mailbox_limit = 104857600
virtual_mailbox_base = /var/vmail
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
mailbox_size_limit = 0
message_size_limit = 52428800
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
# ----------------------- VIRTUAL DOMAINS END -----------------------

настройки SASL аутентификации

# ------------------------- SASL PART START -------------------------
broken_sasl_auth_clients = yes
smtpd_helo_required = yes
smtpd_delay_reject = yes
smtpd_tls_ciphers = high
smtpd_client_restrictions = permit_sasl_authenticated
smtpd_sender_restrictions = permit_sasl_authenticated
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth-client
# -------------------------- SASL PART END --------------------------

Настройки TLS

# -------------------------- TLS PART START -------------------------
smtp_use_tls = yes
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_CAfile = /etc/ssl/certs/rootCA.crt
smtpd_tls_cert_file = /etc/ssl/certs/postfix.crt
smtpd_tls_key_file = /etc/ssl/private/postfix.key
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3
smtpd_tls_received_header = yes
smtpd_tls_loglevel = 1
smtpd_tls_security_level = may
tls_random_source = dev:/dev/urandom
smtpd_tls_exclude_ciphers = aNULL, DES, 3DES, MD5, DES+MD5, RC4
smtpd_tls_protocols = TLSv1, SSLv3, SSLv2
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_session_cache_timeout = 3600s

# --------------------------- TLS PART END --------------------------

Настройки отправки почты (разрешения и ограничения)

# ------------------ SMTPD RESTRICTIONS PART START ------------------
disable_vrfy_command = yes
non_fqdn_reject_code = 450
invalid_hostname_reject_code = 450
maps_rbl_reject_code = 450
unverified_sender_reject_code = 550
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
reject_invalid_hostname,
reject_invalid_helo_hostname,
warn_if_reject reject_non_fqdn_helo_hostname,
warn_if_reject reject_unknown_helo_hostname,
warn_if_reject reject_unknown_client,
reject_unauth_pipelining,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
permit

smtpd_sender_restrictions = reject_unknown_sender_domain,
check_sender_mx_access pcre:/etc/postfix/regex_blacklist,
check_sender_access pcre:/etc/postfix/regex_blacklist,
check_sender_ns_access pcre:/etc/postfix/regex_blacklist,
permit

smtpd_data_restrictions =
permit_mynetworks,
reject_unauth_pipelining,
reject_multi_recipient_bounce,
permit
# ------------------- SMTPD RESTRICTIONS PART END --------------------

Теперь создаем конфиг-файлы, которые расскажут postfix-у, из какой базы и как именно брать конфигурацию наших пользователей.
/etc/postfix/virtual-alias-maps.cf

# Такие же настройки нужно будет позже указать для postfixadmin
user = postfixadmin
password = postfixpass
hosts = 127.0.0.1
dbname = postfixadmin
query = select `goto` from `alias` where `address` = '%s'

/etc/postfix/virtual-mailbox-domains.cf

# Такие же настройки нужно будет позже указать для postfixadmin
user = postfixadmin
password = postfixpass
hosts = 127.0.0.1
dbname = postfixadmin
query = select `domain` from `domain` where `domain` = '%s'

/etc/postfix/virtual-mailbox-maps.cf

# Такие же настройки нужно будет позже указать для postfixadmin
user = postfixadmin
password = postfixpass
hosts = 127.0.0.1
dbname = postfixadmin
query = select `maildir` from `mailbox` where `username` = '%s'

Теперь открываем master.cf и делаем примерно так:
/etc/postfix/master.cf

smtpd pass - - n - - smtpd
smtp inet n - n - - smtpd
smtps inet n - - - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
587 inet n - - - - smtpd
tlsproxy unix - - n - 0 tlsproxy
dnsblog unix - - n - 0 dnsblog
pickup fifo n - - 60 1 pickup
cleanup unix n - - - 0 cleanup
qmgr fifo n - n 300 1 qmgr
tlsmgr unix - - - 1000? 1 tlsmgr
rewrite unix - - - - - trivial-rewrite
bounce unix - - - - 0 bounce
defer unix - - - - 0 bounce
trace unix - - - - 0 bounce
verify unix - - - - 1 verify
flush unix n - - 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - - - - smtp
relay unix - - - - - smtp
showq unix n - - - - showq
error unix - - - - - error
retry unix - - - - - error
discard unix - - - - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - - - - lmtp
anvil unix - - - - 1 anvil
scache unix - - - - 1 scache

dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

Создаем пользователя, от чьего имени будет рулиться почта:

# sudo groupadd -g 5000 vmail
# sudo useradd -g vmail -u 5000 vmail -d /dev/null -s /bin/false -M

Добавляем юзера postfix в группу sasl

adduser postfix sasl

Создаем две пары сертификатов, в процессе отвечаем на несколько простых вопросов:

# openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/dovecot.pem -keyout /etc/ssl/private/dovecot.pem
# chmod o= /etc/ssl/private/dovecot.pem


# openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/certs/postfix.pem -keyout /etc/ssl/private/postfix.pem
# chmod o= /etc/ssl/private/postfix.pem

Готовим папку для ящиков:

# sudo mkdir /var/vmail
# sudo chown vmail:vmail /var/vmail

Теперь настраиваем dovecot. Как я уже сказал, идеология его настройки изменилась – теперь конфиг-файл разбит на несколько частей.
Для начала, сохраняем всю конфигурацию по умолчанию в какое-нибудь надежное место – на всякий случай.

Настройки работы с БД, в которой будут храниться учетки пользователей:
/etc/dovecot/dovecot-sql.conf

driver = mysql
connect = host=127.0.0.1 dbname=postfixadmin user=postfixadmin password=postfixpass
default_pass_scheme = CRAM-MD5
password_query = SELECT username as user, password FROM mailbox WHERE username = '%u'
#Еще один хинт, без которого ничего не взлетит. Почему-то неправильно определяется home
#И из-за этого не создавалась папка пользователя.
user_query = SELECT concat('/var/vmail/',`maildir`) AS `home`, 5000 as uid, 5000 as gid FROM mailbox WHERE username = '%u'

/etc/dovecot/dovecot.conf

#С pop3 работать не будем
protocols = imap
listen = *

instance_name = dovecot

# Greeting message for clients.
login_greeting = Dovecot ready.

# Завершать все дочерние процессы, если завершен мастер-процесс
shutdown_clients = yes

default_internal_user = vmail
!include conf.d/*.conf

Настройки аутентификации
/etc/dovecot/conf.d/10-auth.conf

!include auth-sql.conf.ext

# Владелец почтовых папок (vmail)
mail_uid = 5000
mail_gid = 5000

# uid/gid нашего пользователя vmail
first_valid_uid = 5000
last_valid_uid = 5000

disable_plaintext_auth = no

service auth {
user = root

unix_listener auth-userdb {
mode = 0666
user = $default_internal_user
group = $default_internal_user
}

# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth-client {
mode = 0666
user = postfix
group = postfix
}
}

service auth-worker {
user = $default_internal_user
}

Небольшой конфиг. где мы указываем, где и как хранить пароли пользователей.
/etc/dovecot/conf.d/auth-sql.conf.ext

auth_mechanisms = plain login cram-md5

# Аутентификация пользователей запросом к базе.
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}

# запрос параметров почтовых пользователей из базы
# актуально если необходимы персональные настройки
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}

Настройки логирования
/etc/dovecot/conf.d/10-logging.conf

##
## Log destination.
##

log_path = syslog
syslog_facility = mail

##
## Logging verbosity and debugging.
##

auth_verbose = no
#auth_verbose_passwords = yes
auth_debug = no
auth_debug_passwords = no

mail_debug = no
verbose_ssl = no

##
## Log formatting.
##

log_timestamp = "%Y-%m-%d %H:%M:%S "

# Format to use for logging mail deliveries. You can use variables:
# %$ - Delivery status message (e.g. "saved to INBOX")
# %m - Message-ID
# %s - Subject
# %f - From address
# %p - Physical size
# %w - Virtual size
deliver_log_format = msgid=%m: %$

Настройки почтовых ящиков
/etc/dovecot/conf.d/10-mail.conf

##
## Mailbox locations and namespaces
##

#mail_location = maildir:~/Maildir
# Расположение и формат файлов почты (%d - домен, %n - имя пользователя).
# Обязательно проверьте права на папку - они должны совпадать
# с тем, что указано ниже
mail_location = maildir:/var/vmail/%d/%n
mail_privileged_group = vmail
mail_access_groups = vmail
mmap_disable = yes

namespace inbox {
inbox = yes

mailbox Drafts {
special_use = \Drafts
}

mailbox Spam {
special_use = \Junk
}

mailbox Trash {
special_use = \Trash
}

mailbox Sent {
special_use = \Sent
}
}

Шифрование
/etc/dovecot/conf.d/10-ssl.conf

SSL/TLS support: yes, no,
ssl = yes

# файлы сертификатов в кодировке pem
ssl_cert =

Настройки Local Delivery Agent. Потребуется для LMTP (см. ниже)
/etc/dovecot/conf.d/15-lda.conf

##
## LDA specific settings (also used by LMTP)
##

postmaster_address = postmaster@nixman.info
hostname = mail.nixman.info

rejection_subject = Rejected: %s
rejection_reason = Message <%t> was rejected:%n%r

lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes

protocol lda {
log_path = syslog
mail_plugins = $mail_plugins sieve
mail_fsync = optimized
}

Настройки IMAP
/etc/dovecot/conf.d/20-imap.conf

#
## IMAP specific settings
##

protocol imap {
mail_max_userip_connections = 512
imap_idle_notify_interval = 24 mins
mail_plugins = $mail_plugins
}

service imap-login {
# enabled if you want non-ssl imap
#inet_listener imap {
# port = 143
#}

inet_listener imaps {
port = 993
ssl = yes
}

}

service imap {
# process_limit = 64
}

Настройки локальной доставки почты (потребуется для корректной работы антиспама)
/etc/dovecot/conf.d/20-lmtp.conf

##
## LMTP specific settings
##

protocols = $protocols lmtp

protocol lmtp {
#auth_socket_path = director-userdb
mail_fsync = optimized
mail_plugins = $mail_plugins sieve
}

service lmtp {
user = vmail

unix_listener lmtp {
mode = 0666
}

inet_listener lmtp {
address = 127.0.0.1
port = 24
}

}

Правила управления почтой (перемещение, обработка). Нужно для антиспама.
/etc/dovecot/conf.d/20-managesieve.conf

##
## ManageSieve specific settings
##

# Service configuration
protocols = $protocols sieve

protocol sieve {
#managesieve_max_line_length = 65536
}

# Service definitions
service managesieve-login {
inet_listener sieve {
port = 4190
}

inet_listener sieve_deprecated {
port = 2000
}
}

service managesieve {
# process_count = 32
}

plugin {
# The path to the user's main active script. If ManageSieve is used, this the
# location of the symbolic link controlled by ManageSieve.
sieve = ~/.dovecot.sieve
sieve_default = /etc/dovecot/sieve/sieve.default
sieve_dir = ~/sieve
sieve_global_dir = /etc/dovecot/sieve
sieve_before = /etc/dovecot/sieve/sieve.before

sieve_max_actions = 1024
}

Перезагружаем сервисы, смотрим логи:

# sudo service postfix restart
# sudo service dovecot restart

Логи, в которых можно найти кучу всего интересного:

/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/dovecot.log

Если все в порядке, дебаг можно отключить.

# sudo sed -i 's/\(.*_debug.* = \).*/\1no/' /etc/dovecot/dovecot.conf # sed -i 's/\(auth_verbose = \).*/\1no/' /etc/dovecot/dovecot.conf

На этом первая часть настройки закончена. Теперь настраим веб-интерфейс для доступа к ящику и управления сервером.