Почтовый сервер на собственном сайте с помощью postfix

от автора

В прошлый раз я рассматривал пример создания подобного сервиса на примере sendmail. Напомню, целью данного деяния создать на основе существующего сайта небольшой почтовый сервис с возможностью получения на сайте входящих сообщений для пользователей. Так как по изученным мною данным postfix является вторым по использованию агентом и используется где-то на 30% серверах, я решил изучить и его для решения данной задачи. Кроме прочего postfix имеет более широкие возможности защиты и в частности поддержку SSL/TLS, которую в sendmail я, к сожалению, так и не обнаружил. В довесок postfix позволяет напрямую обращаться к базе данных, а также поддерживает формат maildir, который насколько я помню в senfmail также отсутствует. А так как однозначного ответа на просторах интернета я, как и в прошлый раз, не нашел, думаю инструкция все-таки будет полезна.

В первую очередь необходимо прописать настройки в dns-зоне:

Для MX:

@ IN MX 10 mail.site.ru.

И для AAAA:

@ IN AAAA 2001:0db8:85a3:0000:0000:8a2e:0370:7334

И для A:

mail.site.ru. IN A <IP>

Указанный в ДНС MX адрес также надо будет прописать в /etc/hosts, добавив:

<IP> mail.site.ru

В файле /etc/postfix/main.cf отредактируем параметр mydestination. Он не должен содержать домена на который мы будем принимать сообщения для виртуальных пользователей. Если кроме виртуальных пользователей других не планируется, то можно его и вовсе оставить пустым.

mydestination =  

Для записи в файл нам понадобиться отредактировать все тот же /etc/postfix/main.cf

Добавим в него параметры virtual_uid_maps, virtual_gid_maps, virtual_mailbox_domains, virtual_mailbox_maps и virtual_mailbox_domains. Выглядеть все это дело будет следующим образом

virtual_uid_maps = static:1001, static:1002  virtual_gid_maps = static:1001, static:1002 virtual_mailbox_domains = /etc/postfix/vhosts virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_mailbox_base = /home 

Параметр virtual_uid_maps содержит идентификатор пользователя, от имени которого мы будем записывать сообщения, virtual_gid_maps делает тоже самое, но для группы. Если их несколько можно перечислить их через запятую. В директиву virtual_mailbox_base необходимо указать путь для корневого каталога всех возможных почтовых ящиков. Вдальнейшем он будет формировать примерно следующим образом virtual_mailbox_base+vmailbox и получится что-то навроде (/home)+(/)+(site.ru/public_html/mail)=/home/site.ru/public_html/mail

Далее создадим файл vhosts в папке /etc/postfix. В нем с каждой новой строчки необходимо прописать домены, с которых мы будем принимать сообщения для наших виртуальных пользователей.

site.ru poddomen.site.ru site.com 

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

@site.ru                     site.ru/public_html/mail @poddomen.site.ru   poddomen.site.ru/public_html/mail @site.com                  site.com/public_html/mail 

Такая инструкция будет записывать все входящие сообщения с доменом site.ru, в файл /home/site.ru/public_html/mail. Добавим в конце слеш и получим формат Maildir.

@site.ru                     site.ru/public_html/mail/ @poddomen.site.ru   poddomen.site.ru/public_html/mail/ @site.com                  site.com/public_html/mail/ 

Он будет более удобен, так как создает файл для каждого отдельного сообщения. Все новые сообщения передаются в папку /home/user/public_html/mail/new. Создаваемые файлы формируются из текущего времени, имени хоста, идентификатора процесса, создавшего этот файл, и некоторого случайного числа. Главный недостаток данной записи в отсутствии четкой номенклатуры. И разобрать где и чья почта довольно проблематично. Поэтому наиболее подходящим вариантом будет указать конкретных пользователей.

user1@site.ru site.ru/public_html/mail/user1/ user2@site.ru site.ru/public_html/mail/user2/ user3@site.ru site.ru/public_html/mail/user3/ 

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

CREATE TABLE `virtual_domains` ( 	`user` VARCHAR(50) NOT NULL COLLATE 'cp1251_general_ci', 	`mail` VARCHAR(50) NOT NULL COLLATE 'cp1251_general_ci', 	`dir` VARCHAR(50) NOT NULL COLLATE 'cp1251_general_ci', 	`domain` VARCHAR(50) NOT NULL ) COLLATE='cp1250_general_ci' ENGINE=MyISAM; 

В первую очередь нас интересует колонка `dir`, в ней необходимо прописать путь к директории с сообщениями пользователя, например site.ru/public_html/mail/user1/. Поэтому при создании пользователя нужно убедиться в наличии данной папки и при необходимости ее создать, иначе сообщениям просто негде будет сохранятся. В колонке `user` хранится логин пользователя, т.е. левая часть адреса до знака @. В колонке `domain` правая часть. В колонке `mail` адрес целиком. Из них нам нужны всего 1 или 2 колонке, но для примера я решил указать все возможные варианты.

Теперь создадим файл /etc/postfix/vmailbox.cf и пропишем в нем настройки для запроса и соединение с базой.

user = mail_user password = password dbname = base_mail hosts = localhost query = select dir from virtual_domains where user='%u' 

Специальная переменная %u будет запрашивать лишь левую часть адреса (логин пользователя) без знака @. Такой вариант будет вполне оправдан, если у Вас только один сайт, который будет принимать сообщения. В ином случае нужно будет сделать также и проверку домена

query = select dir from virtual_domains where user='%u' and domain='%d'  

Здесь специальная переменная %d запрашивает правую часть адреса (домен) без знака @. Либо можно и вовсе хранить адрес целиком.

query = select dir from virtual_domains where mal='%s' 

Соответственно переменная %s будет запрашивать весь адрес.

В файле /etc/postfix/main.cf изменим значение директивы virtual_mailbox_maps.

virtual_mailbox_maps = proxy:mysql:/etc/postfix/vmailbox.cf 

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

virtual_mailbox_maps = proxy:mysql:/etc/postfix/vmailbox.cf, proxy:mysql:/etc/postfix/vmailbox2.cf 

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

Этот вариант в целом вполне пригодный и им даже можно пользоваться, но в общем-то далеко не безупречный. В частности отсутствует возможность сортировки, так как из имени файла, кроме даты и времени получить ничего невозможно. Чтобы получить хотя бы элементарные данные на вроде темы сообщения и отправителя, нужно открывать целый файл. Нет возможности совершить какие-либо действия при получении сообщений, что тоже немаловажно. Поэтому более гибким и удобный будет вариант с возможностью отправить сообщения непосредственно на обработку php-скрипту, который разберет почту удобным нам образом и совершим необходимые нам действия.

Убираем директивы virtual_mailbox_base, virtual_mailbox_maps, virtual_uid_maps и virtual_gid_maps. Вместо них нам теперь понадобиться директива virtual_alias_maps. В ней мы будем указывать на конкретного пользователя, которому будем переадресовывать все входящие сообщения для того или иного домена. Создадим файл, где будем прописывать инструкцию для виртуальных пользователей /etc/postfix/valias, а в нем направим всю почту для домена конкретному пользователю, от имени которого и будет работать php-скрипт, а тот уже и будет распределять ее по виртуальным пользователям нашего сайта.

@site.ru user @site.com user2 

Как и в случае с каталогами можно создать базу, для обработки виртуальных доменов, что позволит отбрасывать почту предназначенную для несуществующих пользователей еще на начальном этапе. Я не буду повторять пример для виртуальных пользователей, так как он аналогичен настройкам директивы virtual_mailbox_maps за тем лишь исключением, что вместо колонки `dir`, логичнее указать колонку `alias`, в которой необходимо прописывать уже не путь к директории для хранения сообщений, а имя пользователя.

В файле /etc/aliases пропишем инструкцию на файл-обработчик

user:    "|php5-cgi -c /path/to/php.ini /site.ru/public_html/mail.php" user2:   "|php5-cgi -c /path/to/php.ini /site.com/public_html/mail.php" 

И обновим карту алиансов командой newaliases, а также перезагрузим postfix.

А о том, как mail.php обработает входящий результат я планирую рассказать в следующей статье.

Для защиты от атак и вирусов можно заглянуть в http://habrahabr.ru/post/193220/ начиная с пятого пункта.

http://wiki.dieg.info/postfix
http://www.postfix.org/postconf.5.html

ссылка на оригинал статьи http://habrahabr.ru/post/261861/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *