Skip to main content

Настройка почтового сервера. Postfix.

Настройка почтового сервера
DOVECOT + POSTFIX + OPENSSL + MySQL

Часть 1. Настройка Postfix

В этой заметке я расскажу о том, как настроить на своем сервере почтовый сервер. Все действия происходят на сервере Ubuntu 10.04 Server, в среде виртуализации под управлением OpenVZ.

За основу я взял статью «Установка почтового сервера Postfix + Dovecot + MYSQL и виртуальных доменов», и немного модифицировал ее под свои нужды.

root@poligon:~# lsb_release -d -r -c   
Description:	Ubuntu 10.04 LTS
Release:	10.04
Codename:	lucid
root@poligon:~# uname -a
Linux poligon 2.6.18-194.8.1.el5.028stab070.2 #1 SMP Tue Jul 6 15:26:41 MSD 2010 i686 GNU/Linux

В ролях:
Postfix, как SMTP сервер;
Dovecot, как IMAP ( POP3 ) сервер;
MySQL в качестве базы для почтовых аккаунтов.

Последняя выбрана из-за простоты и понятности настройки, а так же из-за простой возможности интеграции с другими системами ( например,с XMPP сервером eJabberd )

В качестве фронтенда для MySQL я использую phpmyadmin, только из-за удобства, но особой разницы нет — пользуйтесь удобными инструментами.

Итак, первым делом установим нужные пакеты.

root@poligon:~# apt-get install phpmyadmin mysql-server-5.1 dovecot-common dovecot-postfix postfix postfix-mysql openssl
Reading package lists... Done
Building dependency tree       
Reading state information... Done
phpmyadmin is already the newest version.
The following extra packages will be installed:
  dovecot-imapd dovecot-pop3d libpq5 lockfile-progs ntpdate
Suggested packages:
  ntp ufw openssl-doc postfix-mysql postfix-pgsql postfix-ldap postfix-pcre
  libsasl2-modules resolvconf postfix-cdb
The following packages will be REMOVED:
  rmail sendmail sendmail-bin
The following NEW packages will be installed:
  dovecot-common dovecot-imapd dovecot-pop3d dovecot-postfix libpq5
  lockfile-progs ntpdate postfix postfix-mysql

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

Здесь и далее mail_password — пароль базы данных mail в MySQL.

CREATE USER 'mail'@'localhost' IDENTIFIED BY  'mail_password';
 
GRANT USAGE ON * . * TO  'mail'@'localhost' IDENTIFIED BY  'mail_password' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
 
CREATE DATABASE IF NOT EXISTS  `mail` ;
 
GRANT ALL PRIVILEGES ON  `mail` . * TO  'mail'@'localhost';

Таким образом мы создали пользователя mail в MySQL и создали одноименную базу, на которую выдали ему полные права. Далее следует создать необходимые таблицы в базе.

Создадим таблицу виртуальных доменов сервера:

CREATE TABLE  `virtual_domains` (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
name VARCHAR( 50 ) NOT NULL
) ENGINE = INNODB;

Создадим таблицу виртуальных пользователей сервера:

CREATE TABLE  `virtual_users` (
id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
domain_id INT( 11 ) NOT NULL ,
USER VARCHAR( 40 ) NOT NULL ,
PASSWORD VARCHAR( 32 ) NOT NULL ,
CONSTRAINT UNIQUE_EMAIL UNIQUE (
domain_id,
USER
),
FOREIGN KEY ( domain_id ) REFERENCES virtual_domains( id ) ON DELETE CASCADE
) ENGINE = INNODB;

Создадим таблицу синонимов пользователей:

CREATE TABLE  `virtual_aliases` (
id INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
domain_id INT( 11 ) NOT NULL ,
SOURCE VARCHAR( 40 ) NOT NULL ,
destination VARCHAR( 80 ) NOT NULL ,
FOREIGN KEY ( domain_id ) REFERENCES virtual_domains( id ) ON DELETE CASCADE
) ENGINE = INNODB;

Далее нам надо создать файлы конфигураций, которые опишут в Postfix, откуда брать нужные данные.
Создадим файл /etc/postfix/virtual-domains.cf:

root@poligon:~# cat /etc/postfix/virtual-domains.cf
user = mail
password = mail_password
hosts = 127.0.0.1
dbname = mail
query = SELECT 1 FROM virtual_domains WHERE name='%s'

Укажем в главное конфигурации Postfix, что данные для подключения надо брать из этого файла:

root@poligon:~# postconf -e virtual_mailbox_domains=mysql:/etc/postfix/virtual-domains.cf

Добавим домен в таблицу доменов:

INSERT INTO virtual_domains( id, name ) 
VALUES ( 1,  'poligon.scaytrase.ru' ) ;

Теперь мы можем проверить настройки:

root@poligon:~# postmap -q poligon.scaytrase.ru mysql:/etc/postfix/virtual-domains.cf
1

Единица означает, что данный домен был успешно найден с помощью нашего конфигурационного файла. В противном случае, проверьте, все ли конфигурационные файлы созданы, и занесли ли вы в них корректные данные.
Дальше мы создадим пользователя и группу для физического управления и размещения файлов почты:

root@poligon:~# useradd -g vmail -u 241 vmail -d /home/vmail/ -m
root@poligon:~# groupadd -g 241 vmail

Создадим первого виртуального пользователя нашей почты:

INSERT INTO virtual_users( id, domain_id, USER, password ) 
VALUES ( 1, 1,  'testuser', MD5(  'secret' ) ) ;

Далее надо создать VIEW для того, чтобы Postfix мог запросить пользователя несложным запросом:

CREATE VIEW view_users AS SELECT CONCAT( virtual_users.USER,  '@', virtual_domains.name ) AS email, virtual_users.password
FROM virtual_users
LEFT JOIN virtual_domains ON virtual_users.domain_id = virtual_domains.id;

создадим файл /etc/postfix/virtual-users.cf, аналогичный тому, что был показан выше:

root@poligon:~# cat /etc/postfix/virtual-users.cf
user = mail
password = mail_password
hosts = 127.0.0.1
dbname = mail
query = SELECT 1 FROM view_users WHERE email='%s'

Аналогично, занесем информацию в конфигурацию Postfix

root@poligon:~# postconf -e virtual_mailbox_maps=mysql:/etc/postfix/virtual-users.cf

Проверим результат командой

root@poligon:~# postmap -q testuser@poligon.scaytrase.ru mysql:/etc/postfix/virtual-users.cf
1

Опять же 1 — означает успех, в противном случае ищите ошибку в конфигурации.
Теперь абсолютно также настроим альясы для пересылки почты, тут все точно также, приведу код без комментариев:
Добавим два альяса:

INSERT INTO virtual_aliases( id, domain_id, SOURCE, destination ) 
VALUES ( 1, 1,  'testuser',  'testuser@poligon.scaytrase.ru' ) , ( 2, 1,  'testuser',  'pavel.batanov@scaytrase.ru' ) ;

Создадим VIEW

CREATE VIEW view_aliases AS SELECT CONCAT( virtual_aliases.SOURCE,  '@', virtual_domains.name ) AS email, destination
FROM virtual_aliases
LEFT JOIN virtual_domains ON virtual_aliases.domain_id = virtual_domains.id;

Создадим файл /etc/postfix/virtual-aliases.cf:

root@poligon:~# cat /etc/postfix/virtual-aliases.cf
user = mail
password = mail_password
hosts = 127.0.0.1
dbname = mail
query = SELECT destination FROM view_aliases WHERE email='%s'

Проверим работоспособность:

root@poligon:~# postmap -q testuser@poligon.scaytrase.ru mysql:/etc/postfix/virtual-aliases.cf
testuser@poligon.scaytrase.ru,pavel.batanov@scaytrase.ru

Создадим файл /etc/postfix/email2email.cf:

root@poligon:~# cat /etc/postfix/email2email.cf
user = mail
password = mail_password
hosts = 127.0.0.1
dbname = mail
query = SELECT email FROM view_users WHERE email='%s'

Проверим его работоспособность:

root@poligon:~# postmap -q testuser@poligon.scaytrase.ru mysql:/etc/postfix/email2email.cf
testuser@poligon.scaytrase.ru

Занесем данные об этих двух файлах в конфигурацию Postfix:

root@poligon:~# postconf -e virtual_alias_maps=mysql:/etc/postfix/virtual-aliases.cf,mysql:/etc/postfix/email2email.cf

Теперь настроим Postfix, чтобы он использовал Dovecot в качестве транспорта. Вставьте эти строки в конец файла /etc/postfix/master.cf:

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

Внимание, два пробела перед flags!

Также надо добавить информацию о транспорте в конфигурацию Postfix

root@poligon:~/ssl# postconf -e virtual_transport=dovecot
root@poligon:~/ssl# postconf -e dovecot_destination_recipient_limit=1

Теперь подготовим сертификаты, подробнее о процессе и утилитах можно прочитать в моей записи
Настройка SSL сертификатов

root@poligon:~/ssl# ./ssl.pl --prepare
root@poligon:~/ssl# ./ssl.pl --ca
Generating a 4096 bit RSA private key
..................................................................++
................++
writing new private key to 'ca/rootCA.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [Russia]:
Locality Name (eg, city) [Moscow]:
Organization Name (eg, company) [ScayTrase Personal]:
Organizational Unit Name (eg, section) [Security Team]:
[Sub]Domain Name [poligon.scaytrase.ru]:
Email Address [pavel.batanov@scaytrase.ru]:
 
root@poligon:~/ssl# ./ssl.pl --rs poligon.scaytrase.ru
Generating a 4096 bit RSA private key
............++
.........++
writing new private key to 'poligon.scaytrase.ru.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [RU]:
State or Province Name (full name) [Russia]:
Locality Name (eg, city) [Moscow]:
Organization Name (eg, company) [ScayTrase Personal]:
Organizational Unit Name (eg, section) [Security Team]:
[Sub]Domain Name [poligon.scaytrase.ru]:
Email Address [pavel.batanov@scaytrase.ru]:
Using configuration from ./config.ini
Enter pass phrase for ./ca/rootCA.key:
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName           :PRINTABLE:'RU'
stateOrProvinceName   :PRINTABLE:'Russia'
localityName          :PRINTABLE:'Moscow'
organizationName      :PRINTABLE:'ScayTrase Personal'
organizationalUnitName:PRINTABLE:'Security Team'
commonName            :PRINTABLE:'poligon.scaytrase.ru'
emailAddress          :IA5STRING:'pavel.batanov@scaytrase.ru'
Certificate is to be certified until Jul  7 15:02:25 2021 GMT (3650 days)
 
Write out database with 1 new entries
Data Base Updated

В итоге мы получим 4 существенных файла:

  1. ./certs/poligon.scaytrase.ru.crt
  2. ./key/poligon.scaytrase.ru.key
  3. ./ca/rootCA.crt
  4. ./ca/rootCA.key

Файлы .key держите в секрете. Файлы .crt, в частности корневой сертификат rootCA.crt — публичен, выдайте его пользователям, чтобы они установили его в качестве доверенного центра сертификации.

Теперь внесем информацию о сертификатах в Postfix:

root@poligon:~/ssl# postconf -e smtpd_tls_cert_file=/root/ssl/certs/poligon.scaytrase.ru.crt
root@poligon:~/ssl# postconf -e smtpd_tls_key_file=/root/ssl/keys/poligon.scaytrase.ru.key
root@poligon:~/ssl# postconf -e smtpd_use_tls=yes

Осталось совсем чуть-чуть — настроить авторизацию:

root@poligon:~/ssl# postconf -e mynetworks=127.0.0.0/8    
root@poligon:~/ssl# postconf -e smtpd_sasl_type=dovecot
root@poligon:~/ssl# postconf -e smtpd_sasl_path=private/auth
root@poligon:~/ssl# postconf -e smtpd_sasl_auth_enable=yes
root@poligon:~/ssl# postconf -e smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination
root@poligon:~/ssl# postconf -e mailbox_size_limit=1024000

Первая строчка говорит, что доверенные сети — только локалхост.
Вторая устанавливает тип SASL dovecot.
Третья указывает путь сокета авторизации (относительно пути /var/spool/postfix/ )
Четвертая говорит, что надо использовать sasl аутентификацию.
Пятая устанавливает ограничения на получателей — разрешить доверенные сети, разрешить авторизованным пользователей, запретить неавторизованных.

На этом можно перезагрузить Postfix и перейти к настройке Dovecot.

root@poligon:~/ssl# service postfix start
 * Starting Postfix Mail Transport Agent postfix                         [ OK ]

Можем проверить работоспособность нашего сервера:

 
scaytrase@st-Laptop ~ $ telnet poligon.scaytrase.ru 25
Trying 178.162.173.83...
Connected to poligon.scaytrase.ru.
Escape character is '^]'.
220 poligon.scaytrase.ru ESMTP Postfix (Ubuntu)
HELO localhost
250 poligon.scaytrase.ru
EHLO localhost
250-poligon.scaytrase.ru
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
221 2.0.0 Bye
Connection closed by foreign host.

Как мы видим, хост откликается и предлагает нам STARTTLS, без него он даже не предлагает AUTH.
Попробуем STARTTLS подключение:

 openssl s_client -starttls smtp -crlf -connect poligon.scaytrase.ru:25
CONNECTED(00000003)
depth=0 /C=RU/ST=Russia/O=ScayTrase Personal/OU=Security Team/CN=poligon.scaytrase.ru/emailAddress=pavel.batanov@scaytrase.ru
<...Пропустим кучу служебных данных...>
---
250 DSN
read:errno=0

Ошибка. Как мы видим в логах

Jul 10 19:33:45 poligon postfix/smtpd[22436]: fatal: no SASL authentication mechanisms

Что вобщем то следовало ожидать, ведь Dovecot мы еще не настравали.
Как настроить Dovecot