From: Владимир В. Агапов AKA -=Onix=- <onix@deepnet.ru.>
Date: Mon, 24 May 2005 14:31:37 +0000 (UTC)
Subject: Почтовая система на базе Postfix, PostgreSQL, с фильтрацией вирусов и спама
Безопасная почтовая система на базе Postfix, PostgreSQL, с фильтрацией
вирусов и спама на FreeBSD 5.3
Введение.
На данный момент в сети и бумажных изданиях все больше и больше
появляется информации о установке почтовых систем на основе postfix.
Вариантов достаточно много, начиная от обычной установки и заканчивая
информацией о сборке системы достаточной для крупных почтовых шлюзов.
Есть варианты позволяющие хранить всю информацию о пользователях в БД:
MySQL или PostgreSQL, варианты с SMTP авторизацией пользователя,
варианты использования для защиты соединения TLS, и прочее. Если
поискать, в сети можно найти подобное how-to на основе MySQL, но нигде
пока не удалось найти информацию по установке подобной связки на базе
PgSQL. С целью восполнить данный пробел и была написана эта статья.
PostgreSQL - объектно-реляционная СУБД базирующаяся на POSTGRES,
разработанная в департаменте Беркли, Калифорнийского Университета. В
POSTGRES они первыми внедрили много концепций, которые стали
доступными в некоторых коммерческих базах данный намного позже.
PostgreSQL - открытый потомок оригинального кода Беркли. Поддерживает
стандарты SQL92, SQL99 и предлагает несколько новых возможностей:
комплексные запросы, внешние ключи, триггеры, представления,
транзакции и прочее.
Для более подробной информации, рекомендую посетить официальный сайт.
Установка и конфигурирование
Собираем PgSQL из портов
# cd /usr/ports/databases/postgresql80-server/
# make install clean
После благополучной установки инициализируем служебную директорию PgSQL
# /usr/local/etc/rc.d/010.pgsql.sh initdb
Запускаем PgSQL
# /usr/local/etc/rc.d/010.pgsql.sh start
И проверяем что PgSQL работает нормально, выполнив простой SQL запрос:
# sudo -u pgsql psql template1
Welcome to psql 8.0.1, the PostgreSQL interactive terminal.
Type: copyright for distribution terms
h for help with SQL commands
? for help with psql commands
g or terminate with semicolon to execute query
q to quit
template1=# select * from pg_language;
lanname | lanispl | lanpltrusted | lanplcallfoid | lanvalidator | lanacl
----------+---------+--------------+---------------+--------------+------------
internal | f | f | 0 | 2246 |
c | f | f | 0 | 2247 |
sql | f | t | 0 | 2248 | {=U/pgsql}
(3 rows)
template1=#q
Создаем пользователя базы данных postfix и задаем пароль для доступа к
базе
Создаем таблицы для почты и даем пользователю postfix права на выборку
данных из базы
# sudo -u pgsql psql mail
CREATE TABLE users (
login text not null primary key,
password text not null,
maildir text not null,
expired int not null default '0',
comment text
);
CREATE TABLE aliases (
alias text not null primary key,
rcpt text not null,
comment text
);
CREATE TABLE transport (
domain text not null primary key,
transport text not null,
comment text
);
grant select on users to postfix;
grant select on aliases to postfix;
grant select on transport to postfix;
Сделаем несколько записей
INSERT INTO transport VALUES ('domain.ru', 'virtual:', 'VIRTUAL TRANSPORT');
INSERT INTO
users
VALUES
('you@domain.ru', 'Pasw0Rd', 'domain.ru/you/', '0', 'General mail');
INSERT INTO aliases VALUES('root@domain.ru', 'you@domain.ru');
INSERT INTO aliases VALUES('MAILER-DAEMON@domain.ru', 'postmaster@domain.ru');
INSERT INTO aliases VALUES('postmaster@domain.ru', 'root@domain.ru');
INSERT INTO aliases VALUES('daemon@domain.ru', 'root@domain.ru');
INSERT INTO aliases VALUES('system@domain.ru', 'root@domain.ru');
INSERT INTO aliases VALUES('uucp@domain.ru', 'root@domain.ru');
INSERT INTO aliases VALUES('abuse@domain.ru', 'root@domain.ru');
INSERT INTO aliases VALUES('security@domain.ru', 'root@domain.ru');
INSERT INTO aliases VALUES('ftp@domain.ru', 'root@domain.ru');
INSERT INTO aliases VALUES('ftp-bugs@domain.ru', 'ftp@domain.ru');
Этим мы объявляем domain.ru виртуальным, создаем пользователя
you@domain.ru и описываем служебные алиасы (см /etc/mail/aliases) с
перенаправлением всей почты на you@domain.ru. Важно не забывать
финальный слеш при вставке значения в поле maildir таблицы users, в
противном случае postfix будет производить доставку почты не в
maildir, а mailbox.
Если есть желание усилить безопасность, то правим файл
/usr/local/pgsql/data/pg_hba.conf и меняем значения trust на md5
local all all md5
host all all 127.0.0.1/32 md5
Этим мы меняем тип авторизации с доверенной (вход без пароля) на md5
(вход с паролем используя md5 шифрование).
Перезапускаем postfix и проверяем
# sudo -u postfix psql mail
Password:
Welcome to psql 8.0.1, the PostgreSQL interactive terminal.
Type: copyright for distribution terms
h for help with SQL commands
? for help with psql commands
g or terminate with semicolon to execute query
q to quit
mail=> d
List of relations
Schema | Name | Type | Owner
--------+-----------+-------+-------
public | aliases | table | pgsql
public | transport | table | pgsql
public | users | table | pgsql
(3 rows)
mail=> SELECT * FROM aliases;
...
mail=> SELECT * FROM transport;
...
mail=> SELECT * FROM users;
...
mail=> q
На этом с минимально необходимой настройкой PgSQL мы закончили.
Cyrus-SASL2
(http://asg.web.cmu.edu/sasl/)
Общая информация
SASL (Simple Authentication and Security Layer) определяет общий метод
добавления поддержки аутентификации к протоколам, ориентированным на
соединение (POP3, IMAP4, SMTP, FTP, telnet, ACAP, LDAPv3). Для этого
протокол включает в себя команды для идентификации и подтверждения
подлинности пользователя и для опционального договора выбора метода
защиты последующих взаимодействий.
Установка и конфигурирование
Собираем SASL2 из портов
# cd /usr/ports/security/cyrus-sasl2
# vi Makefile
Если не планируем использовать saslauthd, то можно закомментировать
строку
--with-saslauthd=${SASLAUTHD_RUNPATH}
Собираем и устанавливаем
# make WITH_PGSQL=yes install clean
Создаем файл /usr/local/lib/sasl2/smtpd.conf следующего содержания:
pwcheck_method: auxprop
auxprop_plugin: sql
sql_engine: pgsql
sql_user: postfix
sql_passwd: password
sql_hostnames: 127.0.0.1
sql_database: mail
sql_select: select password from users where login='%u@%r'
sql_verbose: yes
После окончания тестирования рекомендую изменить sql_verbose: yes на
sql_verbose: no
На этом с Cyrus-SASL2 мы закончили.
Postfix
(http://www.postfix.org/)
Общая информация
Что такое postfix? Postfix - это полноценная почтовая система,
предназначенная для замены sendmail-а. В отличии от него,
представляющего из себя единую программу, postfix является набором
нескольких небольших программ, каждая из которых выполняет только свою
задачу. В этом postfix ближе к QMail, но в отличие от последнего,
postfix не занимается постоянным порождением/убиванием процессов, а
держит в памяти несколько основных резидентов, что позволяет экономить
ресурсы системы, расходуемые на порождение процессов. Для более
детального знакомства со структурой и принципами работы postfix,
рекомендую посетить официальный сайт разработчиков программы.
Установка и конфигурирование
Итак, приступаем к сборке самого виновника торжества.
Скачиваем дистрибутив Postfix (на данный момент это postfix-2.2.1)
Распаковываем его
Создаем пользователя в системе postfix группу postdrop
Правим /etc/rc.conf для отключения автоматического старта sendmail
(sendmail_enable="NO")
Переходим в директорию с распакованным postfix-ом и собираем его с
поддержкой TLS, SASL и PgSQL
В процессе установки можно принимать значения по умолчанию, в этом
случае конфигурационные файлы будут установлены в директорию
/etc/postfix. Если Вы впервые устанавливаете postfix, то возможно
следует указать куда ставить файлы readme и html - по умолчанию они не
устанавливаются.
Для автоматического старта postfix-a при старте системы создадим
скрипт /usr/local/etc/rc.d/postfix.sh следующего содержания:
За объяснением значений используемых здесь параметров рекомендую
посмотреть документацию на официальном сайте.
Тестирование
Теперь попробуем с этим всем взлететь.
# postfix check
Если команда выполнилась без каких либо сообщений - значит все
нормально и можно делать
# postfix start
Смотрим /var/log/maillog на предмет каких либо ошибок. Если все прошло
нормально, пробуем отправить себе почту, telnet или mail - кому как
удобней. После отправки снова смотрим в логи, должна быть примерно
такая запись
postfix/virtual[65791]: 33AD467846: to=<user2@domain.ru.>,
orig_to=<test@domain.ru.>, relay=virtual, delay=0, status=sent
(delivered to maildir)
Ключевыми словами здесь являются <<status=sent (delivered to
maildir)>>, что обозначает успешную доставку почты postfix-ом
отправленного письма в maildir пользователя.
Пробуем отправить почту куда-нибудь в мир с другой машины, не включая
в настройках почтовой программы SMTP авторизацию.
Если появилась запись подобно приведенной выше - значит все нормально,
наш postfix не собирается выступать в роли open relay и позволять
пересылать через себя почту для других доменов.
Осталось проверить что SASL авторизация у нас работает нормально, и
авторизованному пользователю позволено писать куда угодно. Для этого
включаем в настройках почтовой программы SMTP авторизацию и пробуем
отправить это же письмо еще раз.
Если присутствуют строки типа <<sasl_method=<метод>,
sasl_username=you@domain.ru>>, значит все нормально и postfix+sasl
функционируют нормально.
Шифруем дальше
На этом можно было бы и остановиться, если бы не одно <<но>>: при
стандартной SMTP авторизации, пароль пользователя передается в
открытом виде или в слабо защищенном, и при наличии злоумышленника в
одном с вами сегменте сети (да и не только), может быть перехвачен и
расшифрован. И хотя этот пароль не имеет никакого отношения к паролю
пользователя в системе (если таковой там присутствует), кому
понравится, что кто-то имеет возможность читать его почту? Что бы
избежать этого неприятного факта, воспользуемся дополнительными
средствами, которые может предоставить нам postfix, а именно - TLS
(Transport Layer Security protocol)
TLS
Общая информация
Данный вопрос достаточно подробно раскрыт в статье Семёнова Ю.А. (ГНЦ
ИТЭФ), http://citforum.ru/nets/semenov/6/tls.shtml
Настройка
Для начала нам необходимо создать свой собственный сертификат сервера.
Для этого воспользуемся несколько модифицированным скриптом из
поставки Cyrus-IMAP
# vi /etc/ssl/mkcert.sh
#!/bin/sh
test -x /usr/bin/openssl || exit 0
prefix="/"
if test -f /etc/ssl/server.pem then
echo "/etc/ssl/server.pem already exists."
exit 1
fi
При помощи этого скрипта, мы создаем в директории /etc/ssl
самоподписанный сертификат нашего сервера - server.pem. В процессе
создания будет необходимо указать некоторые значения, названия
достаточно понятные и я думаю проблем не должно возникнуть. Главное в
поле Common Name (eg, YOUR name) [mail.domain.ru]:
указать FQDN вашего почтового сервера, в данном примере:
mail.domain.ru. Если имя сервера для отправки/приема почты в
настройках почтовой программы не совпадает с указанным в сертификате -
почтовая программа будет <<ругаться>>.
Теперь редактируем файл /etc/postfix/main.cf, а именно - добавляем
следующие строки:
Опция smtpd_tls_auth_only = yes позволяет производить SMTP авторизацию
только в режиме TLS.
Тестирование
Для тестирования воспользуемся telnet-ом на 25 порт локальной машины.
Жирным шрифтом выделен ввод с клавиатуры.
# telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.domain.ru.
Escape character is '^]'.
220 new.domain.ru Mail Server
ehlo domain.ru
250-onix.domain.ru
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-STARTTLS
250 8BITMIME
starttls
220 Ready to start TLS
quit
quit
Connection closed by foreign host.
Обращаем внимание на появившуюся строку 250-STARTTLS, это обозначает,
что сервер готов работать с использованием протокола TLS. Это так
называемое <<безопасное соединение на стандартном порту>>. Если вы
хотите использовать безопасное соединение на специальном порту,
раскомментируйте строку
smtps inet n - n - - smtpd
-o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
в файле /etc/postfix/master.cf и перезапустите postfix.
Фильтрация входящей/исходящей почты
На этом с первичной настройкой postfix-а мы закончили. Но хотелось бы
ведь еще что бы почта проверялась на вирусы и спам. Для этого нам
потребуется установить и настроить дополнительные пакеты, а именно
clamav (бесплатный антивирус с возможностью обновления баз через
Интернет), clamsmtp (SMTP фильтр для проверки на вирусы при помощи
clamav) и SpamAssassin (программа предназначенная для проверки
почтовых сообщений на спам).
Начнем по порядку
ClamAV
(http://www.clamav.net/)
Общая информация
ClamAV - бесплатный антивирусный продукт, распространяемый под
лицензией GPL. Его основное применение, по словам разработчиков -
интеграция с почтовой системой (сканирование вложений). Однако его
можно использовать и как обычный антивирусный сканер - в комплекте
идет сканер файловой системы. Однако антивирус без своевременного
обновления вирусных баз мало чем способен помочь. Невзирая на
бесплатный статус, ClamAV имеет собственное средство обновления
вирусных баз через Интернет. Из личного опыта работы с данный
антивирусом, могу сказать что обновления выпускаются достаточно
быстро, по скорости реакции во время появления нового вируса его
превосходит разве что антивирус Касперского, но и то не намного. Этот
небольшой минус на мой взгляд вполне компенсируется бесплатностью
продукта и по этой причине на своих серверах и домашней машине я
использую именно его. Еще один минус: он не умеет проверять
архивированные вложения формата RAR v3. Это связано с расхождениями в
политике лицензирования программных продуктов. На данный момент,
насколько мне известно, ведутся переговоры для устранения этого
разногласия.
Установка и конфигурирование
Установка вполне стандартная и не имеет никаких подводных камней.
# cd /usr/ports/security/clamav
# make install clean
На вопрос нужен ли нам milter можно отвечать <<нет>>, поскольку для
интеграции его с postfix-ом мы будем использовать другой механизм.
CURL - по желанию, например я его не использую.
После установки редактируем конфигурационные файлы
ClamSMTP - фильтр SMTP, который позволяет Вам проверять почтовые
сообщения используя антивирус ClamAV. По словам разработчиков,
<<ClamSMTP стремится быть небольшим, надежным и простым>>. В связи с
этим он написан на С и имеет минимум конфигурационных опций. Так же по
словам разработчиков, <<Если Вы нуждайтесь в большем количестве
вариантов тогда, Вы можете использовать что-нибудь большое, как
AMaViS, который написанный на PERL и может сделать почти все.>> Однако
при построении системы, я отказался от использования AMaViS, поскольку
для программы-посредника, на мой взгляд, он занимает слишком много
памяти.
Установка и конфигурирование
Установка тоже стандартная и не вызывает каких либо вопросов.
# cd /usr/ports/security/clamsmtp/
# make install clean
# cp /usr/local/etc/clamsmtpd.conf-sample /usr/local/etc/clamsmtpd.conf
# vi /usr/local/etc/clamsmtpd.conf
OutAddress: 10026
XClient: off
Listen: 127.0.0.1:10025
ClamAddress: /var/run/clamav/clamd
Header: X-Virus-Scanned: -=Onix=-
TempDirectory: /tmp
Bounce: off
Quarantine: off
TransparentProxy: off
User: clamav
Добавляем в /etc/rc.conf строку
clamsmtpd_enable="YES"
И запускаем его
/usr/local/etc/rc.d/clamsmtpd.sh start
Для проверки можно сделать
# sockstat -4 | grep clamsmtpd
Должна присутствовать строка наподобие этой:
clamav clamsmtpd 39991 3 tcp4 127.0.0.1:10025 *:*
SpamAssassin
(http://spamassassin.apache.org/)
Общая информация
SpamAssassin - почтовый фильтр, который использует различные
эвристические анализаторы заголовков почты и в основном тексте для
идентификации спама. Написан на PERL (исключение составляет модуль
spamd). Использует комплексный подход к проверке писем на спам,
начиная от заголовков SMTP сессии (к сожалению на данный момент не
умеет получать эту информацию из самой сессии, использует для этого
заголовки письма) и заканчивая фильтрацией тела письма. Из плюсов:
большое количество проверок увеличивает шанс отлова спама, возможность
самообучения, возможность вручную переопределять веса правил,
эвристический анализатор текста письма. Из минусов: из-за большого
количества проверок возможны ложные срабатывание, эвристические методы
в режиме самообучения могут ошибочно посчитать SPAM нормальным
письмом, после чего количество правильно распознаваемого спама сильно
упадет, достаточно сильно нагружает систему.
Установка и конфигурирование
Данная тема выходит за пределы обсуждения этой статьи, в связи с
большим количеством документации как на официальном сайте программы,
так и в русскоязычной части Интернета и бумажных изданиях.
Тестирование
Проверяем его работоспособность.
# echo "TEST" | spamc
X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on localhost
X-Spam-Level:
X-Spam-Status: No, score=-1.2 required=7.5 tests=ALL_TRUSTED,MISSING_DATE,
MISSING_SUBJECT autolearn=failed version=3.0.2
Если вы ведете, что то подобное - значит SpamAssassin настроен
нормально и вполне боеспособен.
Что бы узнать как он реагирует на спам - можете воспользоваться GTUBE
тестом. Файл spam.eml можно взять здесь:
http://www.deepnet.ru/files/mail/spam.eml
Дополнительная информация
Для дополнительной информации по SpamAssassin рекомендую:
Официальный сайт: http://spamassassin.apache.org/
Проект OpenNet: http://www.opennet.ru/
Поисковые системы.
Поскольку SpamAssassin сам не имеет SMTP модуля, нам придется ему в
этом помочь. Напишем скрипт, который будет принимать письмо,
передавать его для разбора SpamAssassin-у и потом возвращать письмо
обратно в postfix.
Создаем директорию /etc/postfix/scripts/
Создаем файл spam.pl
#!/usr/bin/perl -w
use strict;
use Net::SMTP;
my $host = &sall_ch(shift(@ARGV), '"');
my $ehlo = &sall_ch(shift(@ARGV), '"');
my $mail_from = &sall_ch(shift(@ARGV), '"');
my $rcpt_to = &sall_ch(shift(@ARGV), '"');
my $spamc = &sall_ch(shift(@ARGV), '"');
if (defined($spamc)) {
open(CF, "$spamc |") or undef($spamc);
}
my $smtp = Net::SMTP->new($host);
$smtp->hello($ehlo);
$smtp->mail($mail_from);
$smtp->to($rcpt_to);
$smtp->data();
if (defined($spamc)) {
while(<CF>) {
next if (/^delivered-to:/i);
$smtp->datasend($_);
}
}
else {
while(<>) {
next if (/^delivered-to:/i);
$smtp->datasend($_);
}
}
$smtp->dataend();
close(CF) if defined($spamc);
Однако одной отправкой писем достаточно сложно обойтись в электронной
почте - почту еще бы хотелось и принимать. Для этого воспользуемся
пакетом Courier-IMAP
Courier-IMAP
(http://www.courier-mta.org/imap/)
Общая информация
Courier-IMAP - сервер, предоставляющий IMAP доступ к почтовым ящикам
формата Maildir. IMAP сервер не позволяет работать с традиционными
почтовыми ящиками формата mailbox. Courier-IMAP включает в себя
некоторые расширения к стандартному формату хранения Maildir почты,
для поддержания дополнительных возможностей, таких как IMAP папки и
<<мягкие>> квоты. Так же он способен работать со стандартными папками
Maildir, правда в этом случае дополнительные возможности не доступны.
И главное, он позволяет работать с виртуальными пользователями, что
будет весьма полезно при построении нашей системы. Помимо IMAP
сервера, он включает в себя POP3 сервер, с возможностью работы через
SSL.
Установка и конфигурирование
Если у вас новые порты, то демон идентификации Courier-IMAP вынесен в
отдельный порт - courier-authlib. Для начала поставим его.
# cd /usr/ports/mail/courier-authlib/
# make config
Выбираем опции POSTGRESQL и MERGECFGS, со всех остальных выделение
снимаем.
# make install clean
# cd /usr/local/etc/authlib/
# vi authdaemonrc
Проверим, что POP3 демон и авторизация у нас работают нормально.
# telnet localhost 110
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.domain.ru.
Escape character is '^]'.
+OK Hello there.
user you@domain.ru
+OK Password required.
pass Pasw0Rd
+OK logged in.
list
+OK POP3 clients that break here, they violate STD53.
13258
.
quit
+OK Bye-bye.
Connection closed by foreign host.
Заключение
Если все прошло нормально, то на данный момент мы имеем минимально
настроенную, но работоспособную защищенную почтовую систему. Однако
многие тонкости настройки как postfix-а, так и глобальной безопасности
остались за пределами данной статьи. Если вам интересна эта тема, то я
всегда готов выслушать ваши вопросы, комментарии, предложения и
замечания.
Владимир В. Агапов AKA -=Onix=-
769 Прочтений • [Почтовая система на базе Postfix, PostgreSQL, с фильтрацией вирусов и спама (postfix postgresql imap virus mail imap)] [08.05.2012] [Комментариев: 0]