В прошлый раз я рассматривал пример создания подобного сервиса на примере sendmail. Напомню, целью данного деяния создать на основе существующего сайта небольшой почтовый сервис с возможностью получения на сайте входящих сообщений для пользователей. Так как по изученным мною данным postfix является вторым по использованию агентом и используется где-то на 30% серверах, я решил изучить и его для решения данной задачи. Кроме прочего postfix имеет более широкие возможности защиты и в частности поддержку SSL/TLS, которую в sendmail я, к сожалению, так и не обнаружил. В довесок postfix позволяет напрямую обращаться к базе данных, а также поддерживает формат maildir, который насколько я помню в senfmail также отсутствует. А так как однозначного ответа на просторах интернета я, как и в прошлый раз, не нашел, думаю инструкция все-таки будет полезна.
В первую очередь необходимо прописать настройки в dns-зоне:
Для MX:
И для AAAA:
И для A:
Указанный в ДНС MX адрес также надо будет прописать в /etc/hosts, добавив:
В файле /etc/postfix/main.cf отредактируем параметр mydestination. Он не должен содержать домена на который мы будем принимать сообщения для виртуальных пользователей. Если кроме виртуальных пользователей других не планируется, то можно его и вовсе оставить пустым.
Для записи в файл нам понадобиться отредактировать все тот же /etc/postfix/main.cf
Добавим в него параметры virtual_uid_maps, virtual_gid_maps, virtual_mailbox_domains, virtual_mailbox_maps и virtual_mailbox_domains. Выглядеть все это дело будет следующим образом
Параметр 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. В нем с каждой новой строчки необходимо прописать домены, с которых мы будем принимать сообщения для наших виртуальных пользователей.
Также создадим файл vmailbox, где будем прописывать инструкции для виртуальных доменов, а в параметре virtual_mailbox_maps указана ссылка на этот файл. В файле vmailbox необходимо прописать инструкции
Такая инструкция будет записывать все входящие сообщения с доменом site.ru, в файл /home/site.ru/public_html/mail. Добавим в конце слеш и получим формат Maildir.
Он будет более удобен, так как создает файл для каждого отдельного сообщения. Все новые сообщения передаются в папку /home/user/public_html/mail/new. Создаваемые файлы формируются из текущего времени, имени хоста, идентификатора процесса, создавшего этот файл, и некоторого случайного числа. Главный недостаток данной записи в отсутствии четкой номенклатуры. И разобрать где и чья почта довольно проблематично. Поэтому наиболее подходящим вариантом будет указать конкретных пользователей.
Теперь нам необходимо добавить некоторой гибкости данному процессу. Его можно добиться перенеся наших пользователей и пути с директориями для хранения сообщений в базу. В postfix для этих целей по сути существует админка PostfixAdmin, но я ставлю целью внедрить данный функционал непосредственно в сайт, поэтому она нам не понадобится. Сами базы логичнее создавать конечно непосредственно в таблице с пользователями сайта, но я покажу на примере отдельной базы.
В первую очередь нас интересует колонка `dir`, в ней необходимо прописать путь к директории с сообщениями пользователя, например site.ru/public_html/mail/user1/. Поэтому при создании пользователя нужно убедиться в наличии данной папки и при необходимости ее создать, иначе сообщениям просто негде будет сохранятся. В колонке `user` хранится логин пользователя, т.е. левая часть адреса до знака @. В колонке `domain` правая часть. В колонке `mail` адрес целиком. Из них нам нужны всего 1 или 2 колонке, но для примера я решил указать все возможные варианты.
Теперь создадим файл /etc/postfix/vmailbox.cf и пропишем в нем настройки для запроса и соединение с базой.
Специальная переменная %u будет запрашивать лишь левую часть адреса (логин пользователя) без знака @. Такой вариант будет вполне оправдан, если у Вас только один сайт, который будет принимать сообщения. В ином случае нужно будет сделать также и проверку домена
Здесь специальная переменная %d запрашивает правую часть адреса (домен) без знака @. Либо можно и вовсе хранить адрес целиком.
Соответственно переменная %s будет запрашивать весь адрес.
В файле /etc/postfix/main.cf изменим значение директивы virtual_mailbox_maps.
Если сайтов несколько, то инструкцию для каждой можно вынести в отдельный файл и перечислить через запятую
Конечно привязать к базе можно и остальные директивы, но я не вижу в этом никакой необходимости.
Перезагружаем postfix и получаем полноценный сайт с возможностью получать сообщения для пользователей.
Этот вариант в целом вполне пригодный и им даже можно пользоваться, но в общем-то далеко не безупречный. В частности отсутствует возможность сортировки, так как из имени файла, кроме даты и времени получить ничего невозможно. Чтобы получить хотя бы элементарные данные на вроде темы сообщения и отправителя, нужно открывать целый файл. Нет возможности совершить какие-либо действия при получении сообщений, что тоже немаловажно. Поэтому более гибким и удобный будет вариант с возможностью отправить сообщения непосредственно на обработку php-скрипту, который разберет почту удобным нам образом и совершим необходимые нам действия.
Убираем директивы virtual_mailbox_base, virtual_mailbox_maps, virtual_uid_maps и virtual_gid_maps. Вместо них нам теперь понадобиться директива virtual_alias_maps. В ней мы будем указывать на конкретного пользователя, которому будем переадресовывать все входящие сообщения для того или иного домена. Создадим файл, где будем прописывать инструкцию для виртуальных пользователей /etc/postfix/valias, а в нем направим всю почту для домена конкретному пользователю, от имени которого и будет работать php-скрипт, а тот уже и будет распределять ее по виртуальным пользователям нашего сайта.
Как и в случае с каталогами можно создать базу, для обработки виртуальных доменов, что позволит отбрасывать почту предназначенную для несуществующих пользователей еще на начальном этапе. Я не буду повторять пример для виртуальных пользователей, так как он аналогичен настройкам директивы virtual_mailbox_maps за тем лишь исключением, что вместо колонки `dir`, логичнее указать колонку `alias`, в которой необходимо прописывать уже не путь к директории для хранения сообщений, а имя пользователя.
В файле /etc/aliases пропишем инструкцию на файл-обработчик
И обновим карту алиансов командой newaliases, а также перезагрузим postfix.
А о том, как mail.php обработает входящий результат я планирую рассказать в следующей статье.
Для защиты от атак и вирусов можно заглянуть в http://help.ubuntu.ru/wiki/amavis_clamav_dspam_ubuntu_10_04.
http://wiki.dieg.info/postfix
http://www.postfix.org/postconf.5.html
В первую очередь необходимо прописать настройки в 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://help.ubuntu.ru/wiki/amavis_clamav_dspam_ubuntu_10_04.
http://wiki.dieg.info/postfix
http://www.postfix.org/postconf.5.html
Комментарии (5)
elcamlost
06.07.2015 09:44Статья вызывает недоверие уже с первого абзаца. Sendmail прекрасно работает и с SSL/TLS (https://www.sendmail.com/sm/open_source/docs/m4/starttls.html) и с maildir (хотя строго говоря, работа с mbox, maildir или любым другим форматом почтового ящика это задача MDA, а не MTA. См, например, www.vniigim.ru/~andr/openbsd/docs/steps/procmail.html).
la0
06.07.2015 10:10Вот бы кто написал, как стоить что-то такое без зависимости в виде mysql (к примеру, sqlite)
bioskiller
Зачем это здесь?
Учитывая более полные инструкции уже опубликованные на Хабре ранее?