Решение проблем с отправкой почты из скриптов в Sendmail. Отправка писем с помощью php Отключение проверки корректности адреса отправителя при отправке почты

Каждый раз настраивая локальный вебсервер, сталкиваюсь с вопросом о заглушке для Sendmail.

Есть прекрасное решение для Windows: fake sendmail for windows (sendmail.exe) http://glob.com.au/sendmail/
На хабре есть статья об этом решении: PHP mail под Windows http://habrahabr.ru/post/26518/
Ещё одно решение под Windows: Test Mail Server Tool http://www.toolheap.com/test-mail-server-tool/
Так же есть статья для линуксоидов: Sendmail-заглушка для Linux http://habrahabr.ru/post/49665/

Лично мне больше понравилось решение на чистом PHP, о котором и пойдёт дальнейшее описание.

Из плюсов:

  • Отсутствие сторонних сервисов
  • Кроссплатформенное решение для OS на которой установлен PHP
  • Минимальный размер файла заглушки
  • Вся логика заглушки доступна для редактирования на PHP
  • Сохранение сообщения в файле

Из минусов:

  • Отсутствие пересылки на реальный почтовый ящик

Список аргументов и возможностей заглушки:

  • --dir <Путь к папке> - Папка для файлов
  • --file <имя файла> - Сохранять каждое сообщение в конкретном общем файле
  • --prepend - Добавлять новое сообщение в начало общего файла
  • --open - Автоматически открывать файл сообщения в Notepad

Параметры для PHP.INI файла:

;SMTP = localhost ;smtp_port = 25 ;sendmail_from = [email protected] sendmail_path = "php.exe C:sendmail.php --dir C:mail --open"

Если путь к php.exe прописан в PATH, то можно не указывать его в PHP.INI иначе желательно изменить php.exe на <Путь к папке с PHP>php.exe

Sendmail_path = "C:serverbinphpphp.exe C:sendmail.php --dir C:mail --open"

На линукс можно сразу указать путь к файлу, не забыв предварительно сделать его запускаемым: chmod 755 sendmail.php

Sendmail_path = "/home/someuser/sendmail.php --dir /tmp/mail"

Сам sendmail.php скрипт:

#!/usr/local/bin/php

Буду рад, если Вам это будет полезным.

Сергей Супрунов

Как работает Sendmail? Полезные подробности

Часть 4: Взаимодействие со сторонними программами

Гуртом і батька добре бити.

Мудрость братского народа

Как бы ни был гибок и функционален Sendmail, его возможностей не всегда хватает для решения всего многообразия задач. Но открытость ПО тем и хороша, что позволяет наращивать мощь практически без ограничений.

Защиты не бывает много

Sendmail, как было показано в предыдущих частях статьи (№ 5, 6, 7 за 2006 г. – ; http:// www. samag. ru/ cgi- bin/ go. pl? q= articles; n=06.2006; a=02 ; ), позволяет, используя файл aliases или пользовательские.forward-файлы, перенаправлять входящие сообщения на обработку сторонними программами. Сам механизм достаточно прост: письмо в исходном формате поступает на стандартный вход (stdin) указанной программы или скрипта, который в дальнейшем занимается его обработкой. Несложный пример реализации такого сценария на Python можно найти в статье «Практикум Python: обрабатываем входящую электронную почту» (№2 за 2006 г. – http:// www. samag. ru/ cgi- bin/ go. pl? q= articles; n=02.2006; a=01 ).

Однако здесь скрывается потенциальная проблема безопасности – если у пользователя будет возможность самостоятельно указывать любые программы в качестве обработчиков почты, то всегда остаётся вероятность, что он воспользуется этим для несанкционированного вызова программы, к которой в нормальных условиях у него нет доступа (например, не предоставляется доступ к командной оболочке, но есть возможность вносить изменения в.forward-файл через веб-интерфейс). Конечно, Sendmail снижает до минимума негативные последствия этой возможности, запуская процесс, выполняющий такую обработку, от имени пользователя-владельца.forward-файла. Но нельзя забывать, что в системе могут быть исполняемые файлы, на которые установлен бит suid, что в ряде случаев может привести к печальным последствиям...

Для решения этой проблемы Sendmail можно настроить на работу с «ограниченной оболочкой» (restricted shell for sendmail) – smrsh. Особенностью этой оболочки является то, что она позволяет запускать программы только из своего каталога, в системах FreeBSD по умолчанию это /usr/libexec/sm.bin (изменить можно перекомпиляцией утилиты с флагом -DSMRSH_CMDDIR).

Как это работает, лучше всего посмотреть на примере (после ключа -c указывается имя выполняемой программы):

# pwd

/usr/libexec/sm.bin

# ls –l

total 0

# /usr/libexec/smrsh -c w

10:01AM up 20 days, 21:44, 1 user, load averages: 0.00, 0.02, 0.00

USER TTY FROM LOGIN@ IDLE WHAT

serg p0 curs3.myserver. 8:48AM - /usr/libexec/sm.bin/w

# /usr/libexec/smrsh -c who

/usr/libexec/smrsh: "who" not available for sendmail programs (stat failed)

# /usr/libexec/smrsh -c thetest

Smrsh test

Как видите, smrsh позволяет исполнять только те программы, ссылки на которые (или сами двоичные файлы) размещены в /usr/libexec/sm.bin. Это же относится и к скриптам – достаточно указать ссылку на скрипт, делать ссылку на интерпретатор не требуется. При желании вы можете использовать любое имя программы – будет использоваться имя ссылки, а не первоначальное имя «бинарника».

Чтобы Sendmail использовал для обработки перенаправлений эту оболочку, а не стандартную sh, добавьте в mc-файл такую строку:

FEATURE(smrsh)

Любители править cf-файл могут заменить имя программы в строке Mprog, т.е. вместо «Mprog, P=/bin/sh . . . » использовать «Mprog, P=/usr/libexec/smrsh . . . ».

Вход только по пропускам

Если для всех ваших пользователей предусматривается работа только из вашей подсети (или в крайнем случае существует ограниченный и стабильный список внешних сетей для доступа к почте), то задача ограничения режима ретрансляции почты, чтобы ваш MTA не стал «открытым релеем», решается довольно легко с помощью файла access.

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

Пожалуй, самой удобной методикой для Sendmail является использование SASL-аутентификации силами пакета SASL-Auth. По умолчанию Sendmail во FreeBSD собирается без поддержки SASL, в чём можно убедиться, подав такую команду:

$ sendmail -d0.1 -bv

и внимательно изучив строчки «Compiled with» на предмет упоминания про SASL.

Чтобы поддержка SASL в Sendmail появилась, нужно его пересобрать. Для этого у вас должны быть исходные коды системы. Последовательность действий такова:

  1. Устанавливаем из портов security/cyrus-sasl2-saslauthd. Конфигурацию можно оставить по умолчанию.
  2. В файле /usr/local/lib/sasl2/Sendmail.conf проверяем значение переменной pwcheck_method. По умолчанию она определена как saslauthd, что означает использование универсального демона и будет хорошим решением в большинстве случаев.
  3. Редактируем /etc/make.conf, добавив туда несколько строк, которые будут использоваться при сборке системных программ:
  4. # Флаги SASL для Sendmail

    SENDMAIL_CFLAGS=-I/usr/local/include -DSASL=2

    SENDMAIL_LDFLAGS=-L/usr/local/lib

    SENDMAIL_LDADD=-lsasl2

    # Поддержка порта smtps для sendmail (если планируется)

    SENDMAIL_CFLAGS+= -D_FER_SMTP_SSL

    Здесь мы указываем добавлять при компиляции Sendmail данные флаги, а также сообщаем программе make пути к необходимым библиотекам.

  5. Теперь пересобираем Sendmail:

# cd /usr/src/lib/libsmutil/

# cd ../libsm

# make clean && make depend && make

# cd /usr/src/usr.sbin/sendmail

# make clean && make depend && make && make install

Обязательно убедитесь, что предварительно установили пакет cyrus-sasl (см. пункт 1), иначе получите ошибку об отсутствии нужных библиотек. Кстати, чтобы эти библиотеки не приходилось отыскивать по всему диску, настоятельно рекомендуется ставить всё только из системы портов.

Теперь в выводимой информации должно присутствовать упоминание SASLv2:

$ sendmail -d0.1 –bv

Version 8.13.6

Compiled with: . . .SASLv2 . . .

Это означает, что осталось подкорректировать при необходимости конфигурацию Sendmail, и можно проверять работу системы. Первое, что может потребовать настройки, это список разрешённых методов аутентификации. То, что у вас получилось сразу после перекомпиляции, можно узнать, подключившись с помощью telnet на 25-й порт и введя команду EHLO:

$ telnet localhost 25

Trying 127.0.0.1...

Connected to localhost.

Escape character is "^]".

220 server.ru ESMTP Sendmail 8.13.6/8.13.6;

EHLO me

250-server.ru Hello localhost , pleased to meet you

250-ENHANCEDSTATUSCODES

250-PIPELINING

250-8BITMIME

250-SIZE 12500000

250-DSN

250-AUTH GSSAPI DIGEST-MD5 CRAM-MD5

250-DELIVERBY

250 HELP

Третья с конца строка как раз и отображает поддерживаемые механизмы аутентификации. Изменить их список можно с помощью следующих директив:

TRUST_AUTH_MECH(`DIGEST-MD5 LOGIN PLAIN")dnl

define(`confAUTH_MECHANISMS", `DIGEST-MD5 LOGIN PLAIN")dnl

Во второй строке перечисляются поддерживаемые механизмы вообще, в то время как первой директивой мы определяем список «доверенных» механизмов, т.е. тех, при использовании которых будет разрешена пересылка почты (relaying), даже если адрес клиента не помечен в базе access как RELAY или OK.

Ребята! Да я же свой!

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

Для этого существует файл authinfo, который подключается таким образом:

FEATURE(`authinfo", `hash -o /etc/mail/authinfo")

В указанном файле прописываем параметры аутентификации на нужные серверы в следующем формате:

AuthInfo:servak.de "U:" "I:" "P:" "M:LOGIN PLAIN"

Здесь servak.de – имя удалённого сервера, которому нужно будет предоставить аутентификационную информацию. В ключе M указываются методы, которые должны при этом использоваться. Не забудьте создать хэш этого файла.

LDAP – путь к единению

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

Sendmail поддерживает возможность работы с LDAP-базой, позволяя вам использовать службу каталогов вместо файлов access, aliases и т. д. Правда, так же, как и в случае с SASL, во FreeBSD он собран без поддержки LDAP. Включается эта поддержка аналогично:

  1. Устанавливаем из портов openldap-client или openldap-server (если LDAP-сервера у нас ещё нет и мы хотим запустить его на этой же машине).
  2. Вносим изменения в /etc/make.conf:
  3. # Флаги LDAP для Sendmail

    SENDMAIL_CFLAGS+= -I/usr/local/include -DLDAPMAP

    SENDMAIL_LDFLAGS+= -L/usr/local/lib

    SENDMAIL_LDADD+= -lldap -llber

  4. Пересобираем Sendmail, как было описано для SASL (см. пункт 4).

Теперь уже знакомая нам команда должна вывести упоминание и про LDAP:

# sendmail -d0.1 -bv root | grep LDAP

После перекомпиляции (или установки) Sendmail проверьте в /usr/local/etc/openldap/slapd.conf, подключена ли схема sendmail.schema.

Если нет, добавьте строку:

include /usr/share/sendmail/cf/sendmail.schema

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

Теперь осталось занести в каталог LDAP необходимые записи (как это сделать, смотрите в документации по LDAP; несколько полезных ссылок приведено в конце статьи) и добавить в mc-файл директивы, указывающие, что следует использовать LDAP:

define(`confLDAP_DEFAULT_SPEC", `-h ldap.your.domain.ru -b dc=your,dc=domain,dc=ru")

FEATURE(`access_db", `LDAP")

define(`ALIAS_FILE", `ldap:")

Первая строка задаёт параметры LDAP-сервера, второй мы указываем, что вместо /etc/mail/access следует использовать службу каталогов, третьей строкой аналогично указываем использовать LDAP для определения псевдонимов.

Альтернативные LDA

Sendmail позволяет подключать практически любую программу в качестве локального агента доставки, естественно, при условии, что эта программа будет «вести себя как LDA» (помните? – «если это выглядит как утка, крякает как утка и ходит как утка, то это – утка»). Благодаря этому у нас есть возможность довольно сильно влиять на то, как почта будет сохраняться. Поэтому не удивительно, что помимо стандартного для FreeBSD mail.local разработано большое число «альтернативных» агентов доставки.

Прежде всего вспоминается очень мощная программа procmail, предоставляющая широчайшие возможности по обработке почты, до того как она попадёт в почтовый ящик пользователя. Её порой так активно используют для борьбы со спамом, что письмо в принципе может вообще не попасть к пользователю. Недаром во многих дистрибутивах Linux именно она работает в паре с Sendmail по умолчанию. Чтобы воспользоваться его преимуществами, достаточно подключить этот LDA (директивой MAILER(procmail), соответствующий m4-файл входит в стандартную поставку Sendmail) и указать в mailertable использование этого LDA для нужных доменов:

your.domain procmail

Второй вариант – включить в mc-файл директиву FEATURE(`local_procmail’), которая даст указание использовать procmail в качестве стандартного LDA (объявленного как local).

FEATURE(`local_procmail", `/usr/local/bin/maildrop", `maildrop -d $u")

Здесь мы воспользовались той же самой директивой, только вместо пути к procmail указали нужный нам. Кстати, если procmail у вас установлен нестандартно (т.е. не в /usr/local/bin), то и для его подключения потребуется указывать полный путь. Естественно, для полноценной работы с Maildir ваш POP3/IMAP-сервер тоже должен уметь работать с этим форматом, впрочем, это уже совсем другая история…

Следующий шаг к совершенству – DBMail

Для полного счастья хорошо бы ещё добавить гибкости почтовым ящикам пользователей. Одно из решений – использовать для их хранения реляционную СУБД, что и реализуется проектом DBMail.

Подробно о DBMail здесь мы говорить не будем (этот пакет с успехом может применяться не только в связке с Sendmail, но и с другими популярными MTA). Некоторая общая информация представлена во врезке «DBMail». Также обратитесь к статье Евгения Прокопьева «Почтовый сервер на основе реляционной СУБД» (№1 за 2006 г.), где работа DBMail освещена очень детально.

Поскольку размещение входящей корреспонденции по почтовым ящикам пользователей не является функцией MTA (как вы помните из первой части статьи, этим занимается агент локальной доставки (LDA)), то с точки зрения Sendmail его логика обработки сообщений совершенно не меняется. Всё что требуется – это зарегистрировать DBMail в качестве LDA и дать указание Sendmail использовать именно его для доставки входящей корреспонденции, как мы это делали для procmail. Первая задача решается одной из следующих директив в mc-файле:

MAILER(dbmail)

MAILER(dbmail-lmtp)

Вторая задача (чтобы Sendmail знал, для какой почты следует использовать тот или иной LDA) – настройка mailtertable для использования этого LDA:

your.domain dbmail

other.domain dbmail-lmpt:

Естественно, вы можете указать использование dbmail только для необходимых доменов. Не забудьте всё пересобрать и перезагрузить процесс sendmail, чтобы изменения вступили в силу.

Думаю, можно также безболезненно воспользоваться тем же приёмом, которым мы подключали maildrop (т.е. создав видимость, что наш dbmail – это procmail, и воспользовавшись готовыми шаблонами для этого LDA). Правда, на практике это не испытывал.

Расширенные возможности фильтрации

Очень широкие возможности для обработки сообщений предоставляют появившиеся в версии 8.11.6 (неофициально – с 8.10) почтовые фильтры, или «мильтеры» (milter, аббревиатура от Mail fILTER).

Почтовые фильтры широко применяются для взаимодействия с такими программами, как антивирусы, спам-фильтры и т. д. То есть они, по сути, предоставляют возможность «заворачивать» обрабатываемое сообщение сторонней программе через сетевой или UNIX-сокет. Кстати говоря, использование для взаимодействия сокетов позволяет размещать программу-фильтр на другой машине в сети, что в ряде случаев может быть полезно для централизации обработки или для снижения нагрузки на основной сервер, если фильтрация требует существенных вычислительных ресурсов или создаёт большую нагрузку на дисковую подсистему. Но нельзя забывать и о дополнительных задержках в этом случае, равно как и о безопасности передаваемой по сокету информации.

Фильтр позволяет контролировать обработку письма начиная с момента установления соединения с удалённым сервером и до полного его получения. В любой момент обработка может быть прервана с помощью одного из флагов возврата: ACCEPT (принять сообщение), REJECT (отклонить с уведомлением об этом отправителя) или DISCARD (отбросить без каких-либо уведомлений). То есть, скажем, если необходимость отклонить сообщение будет выявлена на ранних стадиях сеанса, например, на основе информации, помещённой в заголовок, то это можно будет сделать до того, как письмо будет принято полностью. Ещё один пример использования такой возможности – приём сообщения (ACCEPT) без проверки всех вложений на вирусы, если в заголовке будет обнаружена строка, информирующая о том, что такая проверка уже выполнялась сервером отправителя (хотя всецело доверять таким заголовкам, конечно же, не стоит).

Помимо решения о том, принять или отклонить сообщение, milter позволяет вносить изменения в тему или тело сообщения, добавлять строки в заголовок, и т. д. Благодаря этому можно, например, поместить в заголовок информацию о выполненной антивирусной проверке или оставить пометку, что письмо признано вероятным спамом. Именно так поступают многие антивирусные и антиспамовые пакеты.

Условно схема прохождения письма через подключенные фильтры показана на рис. 1. Фильтров может быть сколь угодно много (реальное ограничение накладывается лишь нагрузкой на систему и требованиями к допустимой задержке при обработке сообщений). Порядок применения фильтров определяется порядком их подключения в конфигурационном файле.

Кстати, о конфигурации... Подключается milter такой директивой:

INPUT_MAIL_FILTER(`clmilter", `S=local:/var/run/clamav/clmilter.sock,F=, T=S:4m;R:4m")

Первым аргументом передаётся имя фильтра, вторым – строка параметров. Параметра может быть три:

  • S, который задаёт используемый сокет (может быть local и inet);
  • F, определяющий, как поступать с письмом в случае проблем с milter (F=T означает возвращать отправителю временную ошибку (temporary fail), F=R – отбросить (reject) соединение, пустое значение F= даёт указание игнорировать проблемы с milter и обрабатывать соединение без фильтрации);
  • T задаёт несколько тайм-аутов (см. таблицу), по истечении которых фильтр будет признан «неотвечающим»

Флаги тайм-аутов

В нашем примере, если clamav-milter не начнёт принимать сообщение от Sendmail в течение четырёх минут или не даст ответ в течение такого же времени, то сообщение будет передано на дальнейшую обработку без фильтрации.

Вместо указанной выше директивы можно подключать фильтры и таким образом:

MAIL_FILTER(`miltergreylist", `S=local:/var/milter-greylist/milter-greylist.sock,F=, T=S:4m;R:4m")dnl

define(`confINPUT_MAIL_FILTERS", `miltergreylist")

Здесь процедура подключения фильтра разделена на два этапа – первой директивой мы объявляем milter с указанными параметрами, второй – регистрируем указанный milter как фильтр для обработки сообщений. Если по такой схеме требуется подключить несколько почтовых фильтров, то директива define нужна только одна, в которой через запятую перечисляются все регистрируемые фильтры в нужном порядке.

Нужно сказать, что для разработки milter существует прекрасный API, позволяющий довольно быстро создавать фильтры на родном для Sendmail языке C (в списке дополнительной литературы вы найдёте ссылку на пример разработки milter для дублирования исходящей почты на некоторый адрес). Существуют «привязки» к этому API для других языков программирования, например, для Perl (модуль Sendmail::Milter, в коллекции портов – mail/p5-Sendmail-Milter) и Python (интерфейс Python Milter, в Портах – mail/py-milter). Прекрасный пример разработки фильтра на Python рассматривался в статье Романа Сузи «Почтовый фильтр, или Milter = Mail + Filter» (№2 за 2003 г., статью вы можете найти на сайте журнала в разделе «Статьи».).

Электронная почта широко используется в самых различных формах. Конечно, если говорить о ведении групповых дискуссий, то есть и более удобные средства: IRC, службы новостей (NNTP), веб-форумы, наконец. Несмотря на это, списки рассылки по электронной почте до сих пор остаются довольно популярным способом обсуждения тех или иных проблем. Очень многие открытые проекты (например, FreeBSD.org, ALT Linux) используют рассылки для оказания технической поддержки своим пользователям, для обсуждения новых возможностей тестовых версий, для уведомлений об обнаруженных проблемах безопасности…

Одной из наиболее известных систем управления списками рассылки является программа Majordomo. Она очень хорошо интегрируется с серверами Sendmail и обладает достаточным набором функций для работы с рассылками.

Установка из коллекции портов никаких сложностей не вызывает, за исключением одного небольшого нюанса: начиная с FreeBSD 5.x Perl не является частью системы и должен устанавливаться из портов, т.е. размещается в /usr/local/bin. Однако порт Majordomo по-старинке хотел видеть /usr/bin/perl. Пришлось ставить ссылку (хотя можно, конечно, и Makefile подправить):

# ln /usr/local/bin/perl /usr/bin/perl

После этого вам нужно будет указать, какой MTA будет использоваться (см. рис. 2; наш выбор, думаю, очевиден). После непродолжительной компиляции мы получим немного нестандартную для FreeBSD схему размещения файлов: «бинарники» и файлы конфигурации будут располагаться в /usr/local/majordomo. Наиболее важны здесь два конфигурационных файла – majordomo.cf, где можно изменить базовые настройки, и aliases.majordomo, содержащий настроенный набор псевдонимов, с помощью которых будет работать Majordomo.

Принцип взаимодействия этого пакета с Sendmail достаточно прост и основан на псевдонимах. Например, сообщение, поступающее на адрес [email protected] будет перенаправлено программе /usr/local/majordomo/wrapper и обработано в соответствии с настройками списка.

Для того чтобы Majordomo начал работать, нужно подключить к Sendmail его файл псевдонимов (хотя можно и просто скопировать нужные строки в /etc/mail/aliases):

define(`ALIAS_FILE", `/etc/mail/aliases, /usr/local/majordomo/aliases.majordomo")

Всё – Majordomo готов к работе. Отправив письмо с командой «lists» в теле на свой домен на адрес majordomo, вы получите информацию о доступных списках рассылки (по умолчанию там будет test-l и test-l-digest). По образу и подобию вы можете создавать собственные списки, для чего нужно создать пустой файл, соответствующий имени рассылки, в /usr/local/majordomo/lists, а также в aliases.majordomo ввести псевдонимы для самой рассылки, команд, адресов владельцев ит.д. – пример можно посмотреть для того же демо-списка, test-l.

Дальнейшее администрирование может выполняться через электронную почту. Например, чтобы поэкспериментировать со списком test-l, первым делом рекомендуется сменить пароль администратора, послав на адрес test-l-request письмо в фразой «passwd test-l test mynewpas», где test-l – имя списка, для которого меняется пароль, test – старый пароль (используется по умолчанию), mynewpas – новый пароль. В случае удачи вы получите письмо с сообщением «Password changed».

Впрочем, работа со списками рассылок – это уже другая тема, и здесь не будем вдаваться в подробности. Тем более что к вашим услугам – отличная страница справки, man majordomo.

Подводная часть айсберга

На этом, пожалуй, и завершим наше знакомство с Sendmail. Естественно, даже в пределах столь объёмного цикла невозможно охватить все аспекты работы этого мощного пакета. Поэтому в заключение я решил привести список ссылок (тоже далеко не полный), по которым можно получить дополнительную информацию.

На этом всё! Удачи!

Приложение

Cyrus SASL

Механизм аутентификации SASL (Simple Authentication and Security Layer) используется для реализации безопасной аутентификации в связке с другими интернет-протоколами. Помимо аутентификации, SASL предоставляет механизмы проверки целостности данных.

Одной из наиболее популярных реализаций SASL является библиотека Cyrus SASL. Будучи разработанной для нужд Cyrus IMAP Server, она широко используется и для других задач, включая SMTP-аутентификацию.

Cyrus SASL поддерживает широкий набор механизмов аутентификации – CRAM-MD5, DIGEST-MD5, Kerberos, GSSAPI (спецификация Kerberos 5). При необходимости может быть разрешена поддержка механизмов «плоской» аутентификации, таких как LOGIN и PLAIN, однако их рекомендуется использовать только при работе по защищённому соединению.

Для выполнения аутентификации используется входящий в состав Cyrus SASL демон saslauthd. Он умеет проводить проверку пароля как по собственной базе, так и используя механизмы PAM, LDAP, системный файл паролей /etc/passwd, и т. д.

LDAP

Lightweight Directory Access Protocol – облегчённый протокол доступа к каталогам – это протокол, призванный обеспечить работу так называемой службы каталогов. Службы каталогов используются для централизованного хранения различной информации, такой как пользовательские учётные записи, адресные книги, различные настройки.

Первоначально служба каталогов (определённая в протоколе X.500) была ориентирована на обслуживание почтовых сетей стандарта X.400, разработанного OSI. Для доступа к этой службе использовался протокол DAP, который и послужил основой для разработки более простого и удобного в работе LDAP.

Записи, хранящиеся в каталогах LDAP, представлены уникальными именами (distinguished name) и рядом атрибутов, определяемых в так называемых схемах. Структура записей позволяет легко организовать записи в виде дерева.

Основным преимуществом LDAP перед «плоскими» файлами или реляционными базами данных является ориентированность на высокую скорость чтения. С учётом очень эффективного кэширования, использование LDAP, помимо централизации информации, что упрощает её сопровождение (включая резервирование), позволяет также снизить задержки при получении информации, если объёмы данных достигают значительных величин.

Помимо свободной реализации службы каталогов – OpenLDAP, широко используемой в системах семейства UNIX/Linux, существует ряд других (например, Active Directory, предназначенная для управления сетями Windows).

Сам протокол LDAP определён в RFC 1777, RFC 2251 (версия 3). Существует также большое число расширяющих и дополняющих документов.

DBMail

Программа DBMail, разработка которой осуществляется двумя датскими фирмами – IC&S и NFG, позволяет организовать хранилище пользовательских почтовых ящиков в базе данных общего назначения. Поддерживаются MySQL и PostgreSQL (в версии 2.2 ожидается добавление к этому списку и SQLite). Для небольших почтовых серверов, обслуживающих локальную сеть вашего предприятия, дополнительное звено в цепи «почтового обслуживания» пользователей лишь снизит надёжность и усложнит сопровождение системы, практически ничего не давая взамен.

Однако на системах с большим числом пользователей или там, где от почтовой системы требуется максимальная гибкость и возможность реализовать самые различные услуги (например, полнотекстовый поиск по всему почтовому ящику с использованием веб-интерфейса) хранение всех сообщений в БД даёт почти безграничные возможности. Например, DBMail очень легко позволяет задать максимальный размер почтового ящика (в случае использования традиционных хранилищ для этого приходится прибегать к системному механизму установки квот на файловую систему): его нужно просто указать в команде создания нового пользователя или изменения параметров его учётной записи:

# dbmail-users -c vasya -m 100M

Любая статистика может быть получена напрямую из базы данных, с помощью обычного SQL-запроса. Кроме того, вы можете использовать все преимущества реляционных баз, такие как резервирование, размещение на отдельном сервере, кластеризация (хотя применительно к поддерживаемым в настоящее время СУБД её реализация требует некоторых дополнительных усилий; см., например, статью Андрея Тренина «Создаём кластер для PostgreSQL» (№1 http://reki.ru/sendmail_setup.html http://unix1.jinr.ru/~lavr/sendmail+sasl2 http://www.milter.org .

  • Роман Сузи, Почтовый фильтр, или Milter = Mail + Filter – .
  • Пример milter на языке C для дублирования исходящей почты – http://www.opennet.ru/base/met/mail_copy_milter.txt.html .
  • Прочие

    1. Основной сайт проекта DBMail – http://www.dbmail.org .
    2. DBMail Documentation – http://www.helgrim.com/dbmaildocs/installation.html .
    3. SMTP STARTTLS в sendmail/Secure Switch – http://linuxnews.ru/docs/new/starttls.html .
    4. Majordomo and MajorCool HOWTO –

    Недавно настраивал домашний сервер, и понадобилось мне там протестировать отправку почты. Но вот беда, при запросе страницы, которая отправляет почту вылезала 500 ошибка.

    Проблема

    Начал смотреть, в чём же дело. В логах php-fpm ничего интереного нет, в логах nginx видно, что php-fpm upstream отваливает по таймауту.

    2013/04/18 15:28:01 6928#0: *1409 upstream timed out (110: Connection timed out) while reading response header from upstream, client: xx.xx.xx.xx, server: , request: "POST /page.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9010", host: "site.ru", referrer: "http://site.ru"

    И тут мне в голову пришла идея заглянуть в syslog. Там то я и увидел интересные строчки:

    Sep 9 18:53:20 mega sm-msp-queue: My unqualified host name (mega) unknown; sleeping for retry Sep 9 18:54:20 mega sm-msp-queue: unable to qualify my own domain name (mega) -- using short name

    Ага, начал грешить в сторону sendmail. Пробую перезапустить его командой:

    Sudo service sendmail restart

    и вижу подтверждение своей догадки.

    Andrey@mega:/home/andrey# sudoservice sendmail restart sudo: unable to resolve host xyz.xyz * Restarting Mail Transport Agent (MTA) sendmail andrey@mega:/home/andrey#

    Решение

    Дело оказалось в имени сервера. После того, как поставил вот такое имя сервера (с точкой) — всё заработало как надо.

    127.0.0.1 localhost localhost.localdomain mega mega.foobar

    Спасибо!

    Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:

    Знакомство с php-функцией mail() и простейший пример её использования для отправки писем по электронной почте. Что лучше или Sendmail vs mail.

    PHP-функция mail() позволяет вам отправлять письма на указанный адрес электронной почты.

    Синтаксис :

    Bool mail (string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]]);

    Параметры :

    • to — адрес электронной почты получателя письма в соответствии с форматом RFC 2822. Например :
    • subject — тема отправляемого письма в соответствии с форматом RFC 2047
    • message — содержание отправляемого письма. Каждая строка должна быть не длиннее 70 символов и заканчиваться символом новой строки (\n).

      Только для Windows : Когда PHP обращается к SMTP серверу напрямую, точка в начале строки удаляется. Для борьбы с этим нюансом, следует использовать замену на двойную точку в начале строки.

      $message = str_replace ("\n.", "\n..", $message);

    • additional_headers (не обязательно) – строка, которая будет добавлена после заголовков письма. Обычно используется для добавления дополнительных заголовков (From, Cc и Bcc). Строки должны быть разделены CRLF (\r\n).
    • additional_parameters (не обязательно) – дополнительные параметры, используемые программой назначенной для отправки писем.

    Возвращает : TRUE если письмо отправлено успешно или FALSE если нет. Следует отметить, если письмо успешно поставлено в очередь на отправление, это не значит, что оно достигнет адресата.

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

    Пример : php-функция MIME base64 кодирования, с учетом кодировки

    Function mime_base64($string, $charset="windows-1251") { return "=?" . $charset . "?B?" . base64_encode(trim($string)) . "?="; }

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

    Function is_email($string) { return preg_match("/^()+([\.a-zA-Z0-9_-])*@()+(\.+)*\.({2,6})$/", $string); }

    С эти тоже разобрались. А теперь то, ради чего и писалась данная заметка.

    Пример : отправка писем с помощью php-функции mail()

    $charset = "windows-1251"; $from = mime_base64("Имя отправитель", $charset) . " "; $to = mime_base64("Имя получитель", $charset) . " "; $subject = mime_base64("Тема отправляемого письма", $charset); $message = "Содержание отправляемого письма."; $message = wordwrap($message, 70); $headers = "From: " . $from . "\r\n" . "Reply-To: " . $from . "\r\n" . "X-Mailer: PHP/" . phpversion(). "\r\n" . "MIME-Version: 1.0" . "\r\n" . "Content-type: text/plain; charset="" . $charset . """; if (mail($to, $subject, $message, $headers)) { echo "

    Письмо отправлено.

    "; } else { echo "

    Произошла ошибка.

    "; }

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

    X-Sendmail-Cmdline: sendmail.pl -t -i To: =?windows-1251?B?yOz/IO/u6/P36PLl6/w=?= Subject: =?windows-1251?B?0uXs4CDu8u/w4OLr/+Xs7uPuIO/o8fzs4A==?= From: =?windows-1251?B?yOz/IO7y7/Dg4ujy5ev8?= Reply-To: =?windows-1251?B?yOz/IO7y7/Dg4ujy5ev8?= X-Mailer: PHP/5.3.3 MIME-Version: 1.0 Content-type: text/plain; charset="windows-1251"

    Sendmail vs php mail()

    Напоследок небольшой ликбез. Sendmail является одним из почтовых серверов (MTA), в то время как php-функция mail() просто реализует процесс отправки писем через SMTP соединение. Понятно, что использование php-функции является удобным, но далеко не оптимальным решением. Обычно mail() используется в тех случаях, когда речь не заходит о масштабных рассылках.

    Настройка почтового сервера sendmail (решение проблемы с отправкой почты из скриптов)

    В некоторых случаях бывает, что почтовый сервер Sendmail не отправляет почту, возвращая ошибку:

    Feb 28 22:04:24 myhost sendmail: mATM4O8w58065806: Losing ./qfmATM4O8w58065806: savemail panic Feb 28 22:04:24 myhost sendmail: mATM4O8w58065806: SYSERR(www): savemail: cannot save rejected email anywhere

    Также в логах может быть ошибка вида:

    Stat=Data format error

    Проблема, как правило, вызвана несуществующим hostname сервера, либо несуществующим почтовым адресом при отправке.

    В таких случаях необходимо указать существующий почтовый адрес. В ISPmanager его можно прописать в свойствах WWW домена в поле "E-Mail администратора".

    При указании адреса в конфигурации веб-сервера Apache в описании виртуального хоста:

    Php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f [email protected]"

    Если используется PHP в режиме как CGI или как FastCGI, запись прописывается в файле ~/php-bin/php.ini

    Sendmail_path = "/usr/sbin/sendmail -t -i -f [email protected]"

    Отключение проверки корректности адреса отправителя при отправке почты

    Sendmail по умолчанию запускается с Message Submission Program (MSP). Это отдельный процесс для обработки почтовой очереди.

    Рассмотрим его отключение в системе FreeBSD

    Пропишите в файле /etc/make.conf строку, отключающую автоматическое создание файла submit.cf

    SENDMAIL_SET_USER_ID=yes

    После чего необходимо удалить файл submit.cf, поменять права на исполнимый файл sendmail (поставить на него SUID bit вместо SGID, то есть установить права 4755 вместо 2755) и перезапустить Sendmail