Этот документ описывает процедуру установки почтового сервера на базе Ubuntu 10.04 LTS. В документе использовано следующее форматирование:

строки с таким выделением

это команды, которые мы задаем в терминале.

строки с таким выделением

это ответы, которые мы получаем на введенные нами команды

строки с таким выделением

это содержимое различного рода конфигурационных файлов.

Будьте предельно внимательны при копировании команд!

Вся процедура создания почтового сервера проверена, однако, естественно, в документе возможны ошибки и неточности. Если у Вас что-то не получается, или получается не так, как следует/описано, то:

  • еще раз проверьте, все ли Вы делаете правильно
  • анализируйте соответствующие лог-файлы, расположенные в /var/log/
  • ищите решение Ваших проблем в гугле
  • консультируйтесь на форуме (старайтесь быть как можно более конкретным, и точно сообщите, в чем именно у Вас возникла проблема)

В процессе создания документа использована куча различного рода информации, доступной в Интернет. К сожалению, не представляется возможным перечислить все источники информации, однако хочется выразить признательность всем авторам, чья работа так или иначе была использована при написании этого документа.

Постановка задачи

Мы установим на чистую машину на Ubuntu 10.04 LTS server почтовый сервер на базе postfix. Для «забора» почты по протоколам pop3/imap будем использовать dovecot с поддержкой квот для почтовых ящиков пользователей. На нашем сервере будет располагаться почта для двух разных доменов - aaa.ru (наш «основной» домен) и bbb.ru. Для настройки почты будем использовать mysql. Для аутентификации пользователей будем использовать два механизма - mysql для домена bbb.ru и openldap для пользователей нашего основного домена aaa.ru. Кроме этого, почтовый сервер будет проверять входящую почту с помощью amavis на вирусы (clamav) и спам (spamassassin). Сделаем также лист рассылки (mailman) и автоответчик для пользователей. Установим систему для доступа к почте через web — horde/imp. Мы будем использовать horde/imp, т.к. это самый продвинутый веб-клиент, позволяющий полностью использовать все современные возможности почты, включая подписывание почты по протоколам S/MIME и прочие. Кроме этого, установим munin для рисования красивых графиков работы нашего почтового сервера.

Итак, предположим, что у нас есть только что установленная 10.04 LTS. Предположим также, что компьютер зовут «oban», он имеет IP адреc 10.0.0.6, находится в DMZ за NAT. Для доступа извне на наш почтовый сервер мы пробросим нужные порты по протоколу TCP – 80, 443 (для доступа к веб-серверу), 25 (для доступа к SMTP-серверу), 110, 143, 993, 995 (для “забора” почты снаружи по протоколам POP3 и IMAP). Если нужно, откроем еще порт 22 для доступа по SSH (хотя этого делать не стоит – лучше иметь доступ к серверу только изнутри нашей сети).

Пользователь, за которым мы «сидим» - это, конечно, не root, а toor (Вы же не сидите за рутом, правда?).

Установка системы

Вначале установим «чистую» систему Ubuntu 10.04 LTS server. В процессе установки ничего дополнительно устанавливать не будем, все нужное установим позже.

Первое что мы сделаем после перезагрузки, еще не отходя от терминала - установим ssh-сервер, чтобы все остальное делать удаленно:

sudo apt-get install openssh-server

После этого со спокойной совестью выходим и идем к нашему собственному компьютеру. Чтобы не набирать каждый раз пароль при входе на наш сервер, сделаем вход по ключу:

ssh-copy-id -i ~/.ssh/id_rsa.pub toor@10.0.0.6

Нас спросят, уверены ли мы, что хотим соединиться с этим сервером

Are you sure you want to continue connecting (yes/no)?

Ответим

yes

Нас спросят пароль пользователя toor на oban

toor@10.0.0.6's password:

Введем. Все, теперь для захода на наш сервер с нашего компьютера достаточно набрать

ssh toor@10.0.0.6

и мы там. Заметьте, что это не то же самое, что попытка входа как

ssh toor@oban

так что если хотите - проделайте это еще раз уже для такого варианта.

Итак, вначале установим все обновления (их наверняка набралось уже порядочно):

sudo apt-get update 
sudo apt-get dist-upgrade

Мы используем dist-upgrade а не просто upgrade чтобы получить обновления в том числе и для ядра.

Естественно, соглашаемся с предложенным списком и (если были обновления ядра или подобные важные обновления) перезагружаемся

sudo reboot

Начинаем установку.

Установим нужные пакеты

sudo apt-get install postfix postfix-mysql postfix-ldap postfix-doc postfix-tls libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql dovecot-imapd dovecot-pop3d dovecot-common mysql-client mysql-server apache2 libapache2-mod-php5 php5 php5-mysql

(здесь и далее соглашаемся с установкой дополнительных пакетов).

Отвечаем на вопросы

Новый пароль для MySQL пользователя «root»:

Обязательно устанавливаем пароль для пользователя root в mysql (это - не пароль пользователя root на компьютере, не путайте!). Здесь и далее это -

<mysql_password>
Повторите ввод пароля для MySQL пользователя «root»:
<mysql_password>
Выберите тип настройки почтового сервера, который оптимально удовлетворяет ваши требования.

Здесь просто жмем <OK>.

Общий тип почтовой настройки:

Выбираем

Internet - сайт
Системное почтовое имя:
oban.aaa.ru

После окончания установки начнем конфигурацию.

Создадим базу данных mysql для хранения всей информации для почтового сервера

mysqladmin -u root -p create mail

Нас спросят пароль пользователя root mysql

Enter password:

Введем выбранный на этапе установки пароль

<mysql_password>

Перейдем в оболочку mysql (опять вводя тот же пароль)

mysql -u root -p

Создадим специального пользователя mail_admin и паролем <mail_admin_password> (замените!) для доступа к нашей базе данных mail с привилегиями SELECT, INSERT, UPDATE и DELETE. Доступ ему будет разрешен только с локального компьютера (т.е. с самого сервера):

GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost' IDENTIFIED BY '<mail_admin_password>'; 
GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail_admin'@'localhost.localdomain' IDENTIFIED BY '<mail_admin_password>';
FLUSH PRIVILEGES;

Теперь создадим нужные нам таблицы в базе данных mail

use mail;
CREATE TABLE domains ( 
domain varchar(50) NOT NULL, 
PRIMARY KEY (domain) ) 
TYPE=MyISAM; 
 
CREATE TABLE forwardings ( 
source varchar(80) NOT NULL, 
destination TEXT NOT NULL, 
PRIMARY KEY (source) ) 
TYPE=MyISAM; 
 
CREATE TABLE transport ( 
domain varchar(128) NOT NULL DEFAULT '', 
transport varchar(128) NOT NULL DEFAULT '', 
UNIQUE KEY domain (`domain`) 
) ENGINE=MyISAM; 
 
CREATE TABLE users ( 
email varchar(80) NOT NULL, 
password varchar(20) NOT NULL, 
quota varchar(20) DEFAULT '0',
PRIMARY KEY (email) 
) TYPE=MyISAM; 

(здесь мы задаем квоту для пользователей по умолчанию без лимита - 0)

и выйдем из оболочки mysql

quit;

Настройка Postfix

Сейчас нам необходимо указать Postfix, где ему искать информацию в базе данных. Для этого создадим шесть текстовых файлов. Как вы можете заметить, я указываю Postfix соединяться с MySQL через IP адрес 127.0.0.1 вместо localhost. Это связано с тем, что Postfix запущенный в chroot окружении не сможет иметь доступа к MySQL сокету, если будет пытаться использовать localhost для подключения.

Проверим, что mysql «слушает» локальный IP адрес

cat /etc/mysql/my.cnf | grep bind
bind-address = 127.0.0.1

Если пришлось поменять /etc/mysql/my.cnf, то перезапустим mysql

sudo service mysql restart

и проверяем, что он действительно слушает этот адрес:

sudo netstat -tap | grep mysql 
tcp 0 0 localhost:mysql *:* LISTEN 5908/mysqld

(здесь 5908- это номер процесса, у Вас будет другой).

Теперь создадим файлы для того, чтобы postfix знал, где что искать в нашей базе данных:

sudo nano /etc/postfix/mysql-virtual_domains.cf
user = mail_admin 
password = <mail_admin_password> 
dbname = mail 
query = SELECT domain AS virtual FROM domains WHERE domain='%s' 
hosts = 127.0.0.1
sudo nano /etc/postfix/mysql-virtual_forwardings.cf
user = mail_admin 
password = <mail_admin_password> 
dbname = mail 
query = SELECT destination FROM forwardings WHERE source='%s' 
hosts = 127.0.0.1
sudo nano /etc/postfix/mysql-virtual_mailboxes.cf
user = mail_admin 
password = <mail_admin_password> 
dbname = mail 
query = SELECT CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') FROM users WHERE email='%s' 
hosts = 127.0.0.1
sudo nano /etc/postfix/mysql-virtual_email2email.cf
user = mail_admin 
password = <mail_admin_password> 
dbname = mail 
query = SELECT email FROM users WHERE email='%s' 
hosts = 127.0.0.1
sudo nano /etc/postfix/mysql-virtual_transports.cf
user = mail_admin 
password = <mail_admin_password> 
dbname = mail 
query = SELECT transport FROM transport WHERE domain='%s' 
hosts = 127.0.0.1

Т.к. в этих файлах у нас лежит пароль для доступа к базе данных, меняем права доступа к ним (разрешаем чтение только группе postfix, в которую входит наш почтовый сервер postfix):

sudo chmod o= /etc/postfix/mysql-virtual_*.cf 
sudo chgrp postfix /etc/postfix/mysql-virtual_*.cf

Проверяем права доступа к этим файлам:

ls -al /etc/postfix/mysql-virtual*.cf
-rw-r—– 1 root postfix 134 2010-11-26 11:24 /etc/postfix/mysql-virtual_domains.cf
-rw-r—– 1 root postfix 119 2010-11-26 11:25 /etc/postfix/mysql-virtual_email2email.cf
-rw-r—– 1 root postfix 132 2010-11-26 11:24 /etc/postfix/mysql-virtual_forwardings.cf
-rw-r—– 1 root postfix 188 2010-11-26 11:25 /etc/postfix/mysql-virtual_mailboxes.cf
-rw-r—– 1 root postfix 128 2010-11-26 11:25 /etc/postfix/mysql-virtual_transports.cf

Создаем нового пользователя и группу с названием vmail с домашней директорией /home/vmail , где будут находится почтовые ящики:

sudo groupadd -g 5000 vmail \\
sudo useradd -g vmail -u 5000 vmail -d /home/vmail -m

Предварительная настройка postfix (нам еще придется ее менять чуть позже). Не забудьте поменять oban.aaa.ru на Ваше реальное полное имя сервера, а то postfix не будет работать!

sudo postconf -e 'myhostname = oban.aaa.ru' 
sudo postconf -e 'mydestination = oban.aaa.ru, localhost, localhost.localdomain' 
sudo postconf -e 'mynetworks = 127.0.0.0/8' 
sudo postconf -e 'virtual_alias_domains =' 
sudo postconf -e 'virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf' 
sudo postconf -e 'virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf' 
sudo postconf -e 'virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf' 
sudo postconf -e 'virtual_mailbox_base = /home/vmail' 
sudo postconf -e 'virtual_uid_maps = static:5000' 
sudo postconf -e 'virtual_gid_maps = static:5000' 
sudo postconf -e 'smtpd_sasl_auth_enable = yes' 
sudo postconf -e 'broken_sasl_auth_clients = yes' 
sudo postconf -e 'smtpd_sasl_authenticated_header = yes' 
sudo postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination' 
sudo postconf -e 'smtpd_use_tls = yes' 
sudo postconf -e 'smtpd_tls_cert_file = /etc/postfix/smtp.crt' 
sudo postconf -e 'smtpd_tls_key_file = /etc/postfix/smtp.key' 
sudo postconf -e 'transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf' 
sudo postconf -e 'proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks' 

Создание SSL-сертификатов

Теперь создадим SSL сертификаты для TLS. Лучше всего (хотя и не обязательно) создать вначале свой CA (Certificate Authority), а потом подписать от его имени все сертификаты (нам еще понадобятся сертификаты для dovecot). В этом случае клиентам нужно будет добавить доверие к этому CA, а не каждому сертификату отдельно.

Создаем CA.

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

mkdir ~/CA_clean

Нам нужно вначале подготовить конфигурационный файл для создания CA

nano ca.conf
[req] 
distinguished_name =req_distinguished_name 
x509_extensions = v3_ca 
prompt = no 
[req_distinguished_name] 
C= RU 
ST = Moscow Region 
L = Moscow 
O = AAA Ltd. 
OU = ROOTCA 
CN = aaa.ru 
emailAddress = admin@aaa.ru 
[v3_ca] 
basicConstraints	= CA:true 
nsComment = "CA certificate of AAA Ltd." 
nsCertType = sslCA, emailCA 
subjectKeyIdentifier=hash 
authorityKeyIdentifier=keyid:always,issuer:always 
[ usr_cert ] 
nsComment = "Certificate issued by AAA Ltd." 
;nsBaseUrl = http://ca.aaa.ru/ 
;nsRevocationUrl = http://ca.aaa.ru/crl.crl 
;issuerAltName = URI:http://ca.aaa.ru/ca.crt 
;crlDistributionPoints = URI:http://ca.aaa.ru/crl.crl

Здесь и далее (замените на нужное Вам):

C = RU (страна)

ST = Moscow Region (регион)

L = Moscow (город)

O = AAA Ltd. (название компании)

CN = aaa.ru (имя сервера, для которого выдается ключ; в случае CA - имя домена)

emailAddress = admin@aaa.ru (почтовый адрес администратора)

(закоментаренные строки нужны только, если Вы действительно хотите иметь более-менее нормальный CA с листами отзыва ключей и т.п., но это выходит за рамки этого how-to)

Создаем частный ключ ключ CA

sudo openssl genrsa -des3 -out ca.key 4096
Enter pass phrase for ca.key:

Введите пароль для файла ca.key (два раза для подтверждения) и не забывайте его!

Verifying - Enter pass phrase for ca.key:

Он будет нужен для подписывания всех ключей (здесь используем sudo т.к. при этом переписывается состояние random_state компьютера)

Создаем открытый ключ CA. Мы говорим, что ключи нашего CA имеют «срок жизни» 10 лет (-days 3650).

openssl req -new -x509 -nodes -sha1 -days 3650 -key ca.key -out ca.crt -config ca.conf
Enter pass phrase for ca.key:

(вводим выбранный нами на предыдущем шаге пароль закрытого ключа CA)

Создаем сертификат для подписывания:

openssl pkcs12 -export -in ca.cer -inkey ca.key -out ca.pfx

openssl x509 -trustout -inform PEM -in ca.crt -outform DER -out ca.pfx

Создадим директорию, в которой у нас будут лежать все ключи для всех серверов (если мы в дальнейшем будем создавать и подписывать ключи для других серверов; например, захотим, чтобы ключи были разные для smtp.aaa.ru pop3.aaa.ru и imap.aaa.ru) и, соответственно, директории для всех имен серверов (в нашем случае — oban.aaa.ru)

mkdir SERVERS 
mkdir SERVERS/oban.aaa.ru

Создаем файлы конфигураций для ключей серверов (в каждой директории - свой файл, т.к. в нем записано имя сервера). В случае одного имени (замените на нужные Вам значения):

nano SERVERS/oban.aaa.ru/openssl.conf
[ req ] 
default_bits = 2048 
distinguished_name  = req_distinguished_name 
prompt = no 
req_extensions = v3_req 
[ req_distinguished_name ] 
C = RU 
ST = Moscow Region 
L = Moscow 
O = AAA Ltd. 
CN = oban.aaa.ru 
emailAddress = admin@aaa.ru 
[ v3_req ] 
basicConstraints = CA:FALSE 
subjectKeyIdentifier = hash 

Теперь сгенерим ключи для нашего сервера (заметьте, что мы опять используем здесь sudo):

sudo openssl genrsa -passout pass:1234 -des3 -out SERVERS/oban.aaa.ru/server.key.1 2048

Здесь 1234 — парольная фраза для промежуточного ключа. Она нам нужна только временно, т.к. мы в результате хотим получить ключ без пароля (требование postfix).

Убираем из ключа парольную фразу:

openssl rsa -passin pass:1234 -in SERVERS/oban.aaa.ru/server.key.1 -out SERVERS/oban.aaa.ru/server.key

Генерим запрос на подпись нашего ключа

openssl req -config SERVERS/oban.aaa.ru/openssl.conf -new -key SERVERS/oban.aaa.ru/server.key -out SERVERS/oban.aaa.ru/server.csr 

и удаляем промежуточный ключ

rm -f SERVERS/oban.aaa.ru/server.key.1

Теперь нам нужно подписать наш созданный ключ от имени своего CA

Сделаем конфигурационный файл для подписи (срок действия подписи 5 лет - 1828 дней):

nano sign.config 
[ ca ] 
default_ca = CA_own 
[ CA_own ] 
certs = . 
new_certs_dir = ca.db.certs 
database = ca.db.index 
serial = ca.db.serial 
RANDFILE = ca.db.rand 
certificate = ca.crt 
private_key = ca.key 
default_days = 1825 
default_crl_days = 1 
default_md = sha1 
preserve = no 
policy = policy_anything 
x509_extensions = usr_cert 
[ policy_anything ] 
countryName = optional 
stateOrProvinceName = optional 
localityName = optional 
organizationName = optional 
organizationalUnitName = optional 
commonName = supplied 
emailAddress = optional 
[usr_cert] 
basicConstraints = CA:false 
subjectKeyIdentifier = hash 
authorityKeyIdentifier = keyid:always,issuer:always 

и создадим директорию для хранения сертификатов подписей:

mkdir ca.db.certs

Для первого подписанного ключа создаем его номер и формируем индексный файл (для остальных - не нужно!)

echo '01' > ca.db.serial 
cp /dev/null ca.db.index 

и подписываем (обратите внимание, что мы опять используем sudo)

sudo openssl ca -batch -config sign.config -out SERVERS/oban.aaa.ru/server.crt -infiles SERVERS/oban.aaa.ru/server.csr
Enter pass phrase for ca.key:

(введем пароль закрытого ключа CA)

Проверим подпись (на всякий случай):

openssl verify -CAfile ca.crt SERVERS/oban.aaa.ru/server.crt

Мы должны получить

SERVERS/oban.aaa.ru/server.crt: OK

Номер ключа и индексный файл автоматически обновились, удалим старые файлы

rm -f ca.db.serial.old 
rm -rf ca.db.index.old

Скопируем ключи в директорию /etc/ssl

sudo cp SERVERS/oban.aaa.ru/server.key /etc/ssl/private/oban.key 
sudo cp SERVERS/oban.aaa.ru/server.crt /etc/ssl/certs/oban.crt

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

sudo chmod og= /etc/ssl/private/oban.key

Теперь установим доверие к новому CA. Для этого создадим папку для него

sudo mkdir /usr/share/ca-certificates/aaa 

и скопируем туда наш сертификат CA

sudo cp ca.crt /usr/share/ca-certificates/aaa/ 

После этого переконфигурируем наши корневые сертификаты

sudo dpkg-reconfigure ca-certificates 

(ответим, что мы хотим доверять новым сертификатам и выберем в списке наш новый сертификат для активации)

Нашим клиентам, которые будут связываться с нашим сервером с использованием шифрования (TLS, SSL) или с нашим веб-сервером по протоколу HTTPS нужно установить доверие к нашему CA. Тем или иным способом передайте им открытый ключ нашего CA - ca.crt.

Внимание! Никогда никому не передавайте созданные приватные ключи *.key и не делайте их доступными!

Настройка saslauthd

Авторизация почтовых пользователей на нашем сервере будет происходить через pam, к которому будет обращаться демон авторизации sasl.

Сначала выполним следующую команду:

sudo mkdir -p /var/spool/postfix/var/run/saslauthd 

Затем отредактируем файл /etc/default/saslauthd

sudo nano /etc/default/saslauthd

Установим параметр START в yes и заменим строку OPTIONS=«-c -m /var/run/saslauthd» на OPTIONS=«-c -m /var/spool/postfix/var/run/saslauthd -r»

Создадим файл /etc/pam.d/smtp

sudo nano /etc/pam.d/smtp
auth sufficient pam_mysql.so user=mail_admin passwd=<mail_admin_password> host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1 
account sufficient pam_mysql.so user=mail_admin passwd=<mail_admin_password> host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1

и сменим его права доступа

sudo chmod o= /etc/pam.d/smtp

Создаем файл /etc/postfix/sasl/smtpd.conf

sudo nano /etc/postfix/sasl/smtpd.conf
pwcheck_method: saslauthd 
mech_list: plain login 
allow_plaintext: true

и меняем ему владельца и права доступа

sudo chown postfix /etc/postfix/sasl/smtpd.conf 
sudo chmod og= /etc/postfix/sasl/smtpd.conf

Добавляем пользователя postfix в группу sasl (это даст Postfix права доступа к saslauthd):

sudo adduser postfix sasl 

Перезапускаем Postfix и Saslauthd:

sudo /etc/init.d/postfix restart 
sudo /etc/init.d/saslauthd restart

Для проверки авторизации создадим пользователя admin@bbb.ru в базе данных (заодно вначале в таблице domains зададим оба наших почтовых домена — aaa.ru и bbb.ru):

mysql -u root -p
Enter password:

Введем пароль mysql

<mysql_password>
USE mail; 
INSERT INTO `domains` (`domain`) VALUES ('aaa.ru'); 
INSERT INTO `domains` (`domain`) VALUES ('bbb.ru'); 
INSERT INTO `users` (`email`, `password`, `quota`) VALUES ('admin@bbb.ru', ENCRYPT('secret'), '10M'); 
quit;

(здесь secret - это пароль нашего пользователя, выберите более подходящий; квоту пользователю мы задаем в размере 10Мбайт)

Для проверки авторизации нам нужно сгенерить строку, которую нужно передать при авторизации (обратите внимание на обратные слеши перед @ и 0):

perl -MMIME::Base64 -e 'print encode_base64("admin\@bbb.ru\0admin\@bbb.ru\0secret");' 
YWRtaW5AYmJiLnJ1AGFkbWluQGJiYi5ydQBzZWNyZXQ=

Теперь проверим авторизацию

telnet 127.0.0.1 25
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is '^]'.
220 oban.aaa.ru ESMTP Postfix (Ubuntu)
EHLO testing
250-oban.aaa.ru
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN YWRtaW5AYmJiLnJ1AGFkbWluQGJiYi5ydQBzZWNyZXQ=

(здесь вставляем полученную ранее строку авторизации)

235 2.7.0 Authentication successful
QUIT 
221 2.0.0 Bye
Connection closed by foreign host.

Если мы получим ответ, отличный от «Authentication successful», то мы где-то ошиблись. Проверить, в чем именно, можно, посмотрев файлы /var/log/auth.log и /var/log/mail.log

Теперь сделаем аутентификацию по openldap. Установим нужные пакеты:

sudo apt-get install libpam-ldap

и ответим на вопросы:

LDAP server Uniform Resource Identifier:
ldap://10.0.0.3/
Обратите внимание — не ldapi!
Distinguished name of the search base:
dc=aaa,dc=ru
LDAP version to use:
3
Make local root Database admin:
Да
Does the LDAP database require login?
Нет
LDAP account for root:
cn=admin,dc=aaa,dc=ru
LDAP root account password:
<ldap_root_password>

(конечно, нужное замените на свои параметры). Здесь мы предполагаем, что:

  • ldap-сервер доступен по IP 10.0.0.3
  • корень расположен в dc=aaa,dc=ru
  • администратор ldap-сервера это cn=admin,dc=aaa,dc=ru
  • он имеет пароль <ldap_root_password>

Редактируем файл

sudo nano /etc/ldap.conf

и добавляем в него одну строку после закомментаренной #bind_policy hard

bind_policy soft

Редактируем файл

sudo nano /etc/pam.d/smtp

и добавляем в него строки

auth sufficient pam_ldap.so 
account sufficient pam_ldap.so

Теперь можем проверить аутентификацию ldap-пользователя (предполагаем, что в ldap есть пользователь admin с паролем secret (у которого, кстати, почтовый адрес admin@aaa.ru, но это сейчас неважно; важно понимать, что это — другой пользователь, а не admin@bbb.ru):

perl -MMIME::Base64 -e 'print encode_base64("admin\0admin\0secret");' 
YWRtaW4AYWRtaW4Ac2VjcmV0
telnet 127.0.0.1 25 
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is '^]'.
220 oban.aaa.ru ESMTP Postfix (Ubuntu)
EHLO testing 
250-oban.aaa.ru
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN YWRtaW4AYWRtaW4Ac2VjcmV0
235 2.7.0 Authentication successful
QUIT 
221 2.0.0 Bye
Connection closed by foreign host.

Для почтовых ящиков локальных пользователей будем использовать LDAP. Заметьте, что мы конфигурируем их как виртуальных пользователей, т.е. локальный домен (aaa.ru) мы занесли в базу данных. Предположим, что локальные пользователи в LDAP расположены в ou=Users,dc=aaa,dc=ru причем их имена записаны в uid а почтовые адреса - в mail.

Создаем файл /etc/postfix/ldap-mailboxes.cf

sudo nano /etc/postfix/ldap-mailboxes.cf
server_host = 10.0.0.3 
server_port = 389 
version = 3 
bind = yes 
bind_dn = cn=admin,dc=aaa,dc=ru 
bind_pw = <ldap_root_password> 
search_base = ou=Users,dc=aaa,dc=ru 
query_filter = (mail=%s) 
result_attribute = mail 
result_filter = %d/%u/

Меняем права доступа

sudo chgrp postfix /etc/postfix/ldap-mailboxes.cf 
sudo chmod o= /etc/postfix/ldap-mailboxes.cf 

и меняем строку virtual_mailbox_maps = … в файле /etc/postfix/main.cf

sudo nano /etc/postfix/main.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf ldap:/etc/postfix/ldap-mailboxes.cf

Для проверки в том же файле временно меняем строку

#smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination 
smtpd_recipient_restrictions = permit_sasl_authenticated, reject_unauth_destination 

(это запрещает доставку писем с локального IP-адреса не в наши виртуальные домены)

Перезапускаем postfix

sudo /etc/init.d/postfix restart 

и проверяем работу обоих наших тестовых адресов - test@bbb.ru (который записан в базе данных) и betatest@aaa.ru (который записан в LDAP у пользователя betatest)

telnet 127.0.0.1 25 
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is '^]'.
220 oban.aaa.ru ESMTP Postfix (Ubuntu)
HELO test 
250 oban.aaa.ru
MAIL FROM: aaa@aa.aa 
250 2.1.0 Ok
RCPT TO: admin@bbb.ru
250 2.1.5 Ok
RCPT TO: admin@aaa.ru 
250 2.1.5 Ok

(если мы попробуем передать на несуществующий адрес, мы получим:)

RCPT TO: aaa@bbb.ru
550 5.1.1 <aaa@bbb.ru>: Recipient address rejected: User unknown in virtual mailbox table
QUIT 
221 2.0.0 Bye
Connection closed by foreign host.

Вернем обратно строку в файле /etc/postfix/main.cf:

sudo nano /etc/postfix/main.cf
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

Для запрета аутентификации в postfix с передачей данных открытым текстом, вставляем в файл /etc/postfix/main.cf

sudo nano /etc/postfix/main.cf 
smtpd_tls_auth_only = yes 
smtpd_tls_cert_file = /etc/ssl/certs/oban.crt 
smtpd_tls_key_file = /etc/ssl/private/oban.key 
smtpd_use_tls = yes

и перезапускаем postfix

sudo /etc/init.d/postfix restart

Откроем и изменим /etc/aliases

sudo nano /etc/aliases

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

postmaster: root 
clamav: root
root: admin@aaa.ru 

После изменения /etc/aliases вы должны запустить команду

sudo newaliases 

Настройка dovecot

Скопируем файл

sudo cp /etc/pam.d/smtp /etc/pam.d/dovecot

(мы будем для dovecot использовать тоже аутентификацию через pam)

Отредактируем файл /etc/dovecot/dovecot-ldap.conf

sudo nano /etc/dovecot/dovecot-ldap.conf
uris = ldap://10.0.0.3/ 
dn = cn=admin,dc=aaa,dc=ru 
dnpass = <ldap_root_password> 
ldap_version = 3 
base = ou=Users,dc=aaa,dc=ru 
deref = searching 
scope = subtree 
user_attrs = mail=mail=maildir:/home/vmail/aaa.ru/%n/ 
user_filter = (&(uid=%n))

Мы не будем задавать квоту для локальных пользователей, чтобы у них была неограниченная квота (напомним, что мы задали по умолчанию квоту без лимита).

Отредактируем файл /etc/dovecot/dovecot-sql.conf

sudo nano /etc/dovecot/dovecot-sql.conf
driver = mysql 
connect = host=127.0.0.1 user=mail_admin password=<mail_admin_password> dbname=mail 
user_query = SELECT email, CONCAT('/home/vmail/',CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1))) AS home, concat('*:storage=', quota) as quota_rule  FROM users WHERE email='%u'

Отредактируем файл /etc/dovecot/dovecot.conf, изменив следующие параметры:

sudo nano /etc/dovecot/dovecot.conf
disable_plaintext_auth = yes 
ssl = yes
ssl_cert_file = /etc/ssl/certs/oban.crt 
ssl_key_file = /etc/ssl/private/oban.key
mail_location = maildir:/home/vmail/%d/%n
mail_uid = vmail 
mail_gid = vmail 
maildir_copy_with_hardlinks = yes 

В блоке auth default { должно быть выбрано

  mechanisms = plain 

и раскомментарено