Почтовый SMTP / IMAP сервер своими руками.
Давненько я не писал в свой уютненький ничего полезного. Вернее, не писал сюда вообще ничего. Думаю, что пришло время это изменить.
За прошедшее время набралось по крайней мере три темы, которые я хотел бы осветить в блоге. Начать решил с установки и настройки своего полноценного почтового сервера на связке Postfix + Dovecot + MySQL в системе Debian Squeeze.
Оглавление
- Инструментарий
- Подготовка
- Первичная настройка Postfix
- Настройка Dovecot
- Заключительная настройка Postfix
- Заключение
- Используемые ресурсы
- Дополнения
Инструментарий ↑
В качестве MTA я выбрал Postfix по нескольким причинам: мне он показался самым простым в настройке, обладающим всем необходимым функционалом, активно разрабатывается, имеет хорошую документацию и, самое главное, умеет работать с Dovecot из коробки.
MDA был выбран Dovecot за свою хорошую документацию, простоту конфигурирации и возможность тесно работать с Postfix.
Чтобы обеспечить максимальную гибкость, я решил связать почтовую систему с базой данных. Трудностей в выборе СУБД не возникло, так как и Postfix и Dovecot могут работать практически с любой хорошо известной (PostgreSQL, SQLite, MySQL). Здесь я взял первое что пришло в голову — MySQL.
С выбором операционной системы в которой все это дело будет работать проблемы так же не появилось. Выбрать я мог одно из двух: Debian или Ubuntu, с которыми я достаточно хорошо знаком. Debian был проверен временем и все необходимое для настройки было в репозиториях, поэтому я остановился на нем. Squeeze — потому, что stable морально устарел, а testing уже несколько месяцев в заморозке перед релизом.
Подготовка ↑
Установим необходимые пакеты:
Подготовим mysql:
CREATE USER 'mailuser'@'localhost' IDENTIFIED BY 'mailpassword';
-- создадим базу данных mailserver
CREATE DATABASE IF NOT EXISTS `mailserver`;
-- дадим созданному пользователю все права на созданную БД
GRANT ALL PRIVILEGES ON `mailserver`.* TO 'mailuser'@'localhost';
-- выбираем созданную БД
USE mailserver;
-- создаем таблицу для хранения виртуальных доменов
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;
-- создаем виртуальную таблицу с пользовательскими аккаунтами
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;
-- создаем виртуальную таблицу с алиасами
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;
Первичная настройка Postfix ↑
Создадим файл /etc/postfix/mysql_virtual_domains.cf со следующим содержанием:
password = mailpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
Добавим в файл /etc/postfix/main.cf опцию virtual_mailbox_domains.
Эта опция проверяет список доменов с которыми Postfix может работать. В данном случает результат будет взят из MySQL:
Добавим в базу новый виртуальный домен:
Если все настроено верно, то следующая команда выдаст в качестве результата единицу:
Создадим файл /etc/postfix/mysql_virtual_maps.cf:
password = mailpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM view_users WHERE email='%s'
Добавим в файл /etc/postfix/main.cf опцию virtual_mailbox_maps.
Эта опция проверяет существование почтовых адресов на сервере:
Добавим в базу нового пользователя username с паролем password на домене example.com:
Проверим результат:
Создадим файл /etc/postfix/mysql_virtual_alias_maps.cf:
password = mailpassword
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM view_aliases WHERE email='%s'
Добавим в файл /etc/postfix/main.cf опцию virtual_alias_maps.
Эта опция получает список адресов на которые будет пересылаться вся корреспонденция:
Добавим в базу новый алиас для только что созданного почтового ящика:
и проверим результат:
Теперь укажем Postfix использовать Dovecot в качестве локального агента доставки почты.
Для этого добавим следующие строки в /etc/postfix/master.cf:
flags=DRhu user=nobody:nogroup argv=/usr/lib/dovecot/deliver -d ${recipient}
Так же добавим в /etc/postfix/main.cf:
dovecot_destination_recipient_limit = 1
Настройка Dovecot ↑
Файл конфигурации /etc/dovecot/dovecot.conf в общем виде:
protocols = imap imaps
# директория, куда будет складываться почта
# %d - имя домена, %n - имя пользователя
mail_location = maildir:/var/spool/virtual/%d/%n
# настройка авторизации
auth default {
# механизмы авторизации
mechanisms = plain login
# получает адрес и пароль из БД для авторизации
passdb sql {
# файл, в котором описывается подключение к БД и сам запрос
args = /etc/dovecot/dovecot-sql.conf
}
# права на директорию с почтой
userdb static {
args = uid=65534 gid=65534 home=/var/spool/virtual/%d/%n allow_all_users=yes
}
# сетевые настройки аутентификации
socket listen {
# для аутентификации подключений к самому Dovecot
master {
path = /var/run/dovecot/auth-master
mode = 0600
user = nobody
}
# для аутентификации внешних приложений ( у нас для Posfix )
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
# настройка локального агента доставки почты
protocol lda {
# путь до сокета для авторизации
auth_socket_path = /var/run/dovecot/auth-master
# адрес администратора почтового сервера
postmaster_address = postmaster@example.com
}
Файл с описанием подключения к БД для получения данных о пользователе /etc/dovecot/dovecot-sql.conf:
driver = mysql
# параметры MySQL авторизации
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=mailpassword
# формат, в которых хранятся пароли в БД ( у нас это MD5 )
default_pass_scheme = PLAIN-MD5
# запрос, возвращающий пользователя и пароль
password_query = SELECT email as user, password FROM view_users WHERE email='%u';
И не забываем включить сам сервис Dovecot, указав в файле /etc/default/dovecot:
Иначе он не будет запускаться.
Заключительная настройка Postfix ↑
Так как авторизация пользователей Postfix у нас производится с помощью Dovecot, то добавим следующие строки в /etc/postfix/main.cf:
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
Так же добавим некоторые правила фильтрации почты, чем отбросим большую часть спам-ботов и им сочувствующих.
Добавим в /etc/postfix/main.cf:
permit_mynetworks
permit_sasl_authenticated
reject_unknown_client_hostname
smtpd_helo_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_sender
reject_unknown_sender_domainАга,
reject_unverified_sender
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_recipient
reject_unlisted_recipient
reject_unauth_destination
Заключение ↑
Теперь можно смело перезапустить наши сервисы:
~$ sudo invoke-rc.d postfix restart
Вся информация по работе почтовой системы логируется в файлы:
/var/log/mail.err
/var/log/mail.warn
/var/log/mail.info
Что еще можно сделать с сервером? Скажу, что целую массу полезного и интересного. Из того, что вспомнил, могу предложить проверку на вирусы с помощью ClamAV, «серые» списки с помощью Postgrey, фильтрацию спама с помощью SpamAssassin, Web-клиент для работы с почтой типа RoundCube и многое другое. О части из перечисленного я планирую рассказать, но когда это будет — неизвестно даже мне. :)
Любые предложения и замечания жду в комментариях.
Используемые ресурсы ↑
- Описание параметров конфигурации Postfix.
- Статья: «Неприступный почтовый сервер, или жизнь без спама».
- Официальная документация Dovecot.
- Статья по настройке почтового сервера на sudouser.com
- google.com
Дополнения ↑
Описание используемых флагов smtpd_*_restrictions
permit_mynetworks — разрешает любые запросы с IP адресов, указанных в параметре mynetworks.
permit_sasl_authenticated — разрешает любые запросы для пользователей, успешно прошедших аутентификацию на сервере.
reject_unknown_client_hostname — отклоняет все запросы от клиента в одном из трех случаев:
- IP адрес клиента не имеет PTR записи на DNS.
- Доменное имя клиента не имеет A записи на DNS.
- А запись клиента не соответствует его IP адресу.
reject_invalid_helo_hostname — отклоняет запросы от клиентов с неверным FQDN в HELO запросе.
reject_non_fqdn_helo_hostname — отклоняет клиентов с не FQDN в HELO запросе.
reject_unknown_helo_hostname — отклоняет клиентов с неизвестным FQDN в HELO запросе.
reject_non_fqdn_sender — отклоняет клиентов с не FQDN в адресе отправителя.
reject_unknown_sender_domain — отклоняет клиентов с неизвестным FQDN в адресе отправителя.
reject_unverified_sender — проверяет существование адреса отправителя на его сервере и отклоняет запрос если проверка не удалась
reject_non_fqdn_recipient — отклоняет клиентов с не FQDN в адресе получателя.
reject_unlisted_recipient — отклоняет запрос если получатель не существует.
reject_unauth_destination — отклоняет запросы от неавторизованных пользователей сервера.
Утилиты
Для упрощения работы с данным почтовым сервером я написал несколько небольших скриптов.
Взять их можно тут git://github.com/Ky6uk/scripts.git
@Alex G.
Не могу сказать в чем причина. Несколько раз сам настраивал сервера по этой статье, ни разу не выскачила подобная проблема. Попробуйте поискать в интернете что это за errno: 150
В ходе исследований выяснилось следующее: вся почта уходит в папку алиаса (copy). Если вручную скопировать файлы из нее в папку самого ящика (usermail) — то почтовый клиент примет эти письма. Подскажите, пожалуйста, как можно исправить это безобразие? Очень нужно для курсовой…