Страница 1 из 1

Настройка почтовой системы c хранилищем на базе PostgreSQL

Добавлено: 08 дек 2010, 11:45
Raven
Итак, посмотрим, для чего предназначен каждый из этих компонентов
  • • Postfix (http://postfix.org) – это популярный MTA (Mail Transfer Agent), позволяющий эффективно передавать письма адресатам.
    • Dovecot (http://dovecot.org) – Secure IMAP server. IMAP-сервер, рассчитанный на максимальную безопасность и надежность. Преимуществом этой программы является то, что для поиска в больших файлах применяется бинарный древовидный индекс. Как указывает автор этого сервера, он тестировал его с 367 000 почтовыми учетными записями и не обнаружил проблем. Также программа может обслуживать запросы пользователей с помощью протоколов imap, imaps, pop3, pop3s.
    • ClamAV (http://clamav.sourceforge.net) – opensource-антивирус.
    • SpamAssasin (http://spamassasin.org) – почтовый фильтр. Предназначен для борьбы со спамом.
    • Amavisd-new (http://www.ijs.si/software/amavisd) – высокоэффективный и надежный интерфейс между MTA и одним или несколькими фильтрами содержимого: вирусные сканеры, спам-фильтры (в нашем случае Spam Assassin). Amavisd-new написан на Perl, обеспечивающим высокую надежность, мобильность и ремонтопригодность. Он взаимодействует с MTA через (E) SMTP или LMTP или при использовании программ-посредников.
Сначала устанавливаем все необходимые пакеты из репозитария:

Код: Выделить всё

[root@mosqit /]# apt-get install postfix postfix-pgsql postgresql postgresql-server dovecot amavisd clamav spamassasin 
Далее переходим к конфигурированию нашей почтовой системы. Создаем пользователя, от имени которого будет работать наша почтовая система:

Код: Выделить всё

[root@mosqit /]# groupadd -g 5000 mailuser 
[root@mosqit /]# adduser -d /var/spool/mail -M -g mailuser -s /sbin/nologin -u 5000 mailuser
PostgreSQL

Настройку и конфигурирование PostgreSQL не привожу, т.к. информации об этом предостаточно.
Создадим пользователя mailuser в базе данных Postgre SQL, c правами которого Postfix и Dovecot будут подключаться к базе данных и выполнять запросы:

Код: Выделить всё

[root@mosqit  /]# createuser -U postgres 
Enter name of user to add: mailuser 
Shall the new user be allowed to create databases? (y/n) n 
Shall the new user be allowed to create more new users? (y/n) n 
CREATE USER 
Устанавливаем пароль пользователю mailuser:

Код: Выделить всё

[root@mosqit  /]# psql -U postgres template1 
Welcome to psql 7.3.4, the PostgreSQL interactive terminal. 
Type:  \copyright for distribution terms
       \h for help with SQL commands
       \? for help on internal slash commands
       \g or terminate with semicolon to execute query
       \q to quit 
template1=# alter user mailuser with password 'topsecret'; 
ALTER USER
template1=#\q 
/var/lib/pgsql/data/pg_hba.conf 
#TYPE      DATABASE     USER   IP-ADDRESS   IP-MASK             METHOD 
local all all password 
host all all    127.0.0.1    255.255.255.255     password 
Следующий этап – это создание базы данных, в которой будет все храниться.

Код: Выделить всё

[root@mosqit  /]# createdb -U postgres mails 
CREATE DATABASE 
База данных mails создана. Далее создаем в ней таблицы. Есть 2 способа: писать SQL-команды руками в клиенте postgresql или приготовить файл с SQL-запросом, а потом создать структуру таблиц, выполнив этот самый запрос.Я выбираю последний способ. Создаем файл createtables.sql:

Код: Выделить всё

CREATE TABLE "public"."users" ( 
  "userid" VARCHAR(128) NOT NULL, 
  "password" VARCHAR(128), 
  "realname" VARCHAR(128), 
  "uid" INTEGER NOT NULL, 
  "gid" INTEGER NOT NULL, 
  "home" VARCHAR(128) NOT NULL, 
  "mail" VARCHAR(255), 
  CONSTRAINT "users_pkey" PRIMARY KEY("userid") 
) WITHOUT OIDS; 
grant select on users to mailuser; 
CREATE TABLE "public"."aliases" ( 
  "alias" VARCHAR(128) NOT NULL, 
  "dest" VARCHAR(128) NOT NULL, 
  "comment" TEXT DEFAULT ''::text 
) WITH OIDS; 
grant select on aliases to mailuser; 
Структура таблиц создана:

Код: Выделить всё

[root@mosqit /]#  /usr/bin/psql -U postgres mails < createtable.sql 
Запускаем PostgreSQL:

Код: Выделить всё

[root@mosqit /]# service postgresql start 
Postfix

Переходим к правке конфигурационного файла main.cf, который находится в /etc/postfix.main.cf. Он хорошо комментирован, поэтому внимательно вчитываемся в описание и настраиваем согласно своим требованиям. У меня main.cf выглядит так:
main.cf:

Код: Выделить всё

# Задаем имя нашего почтового узла 
myhostname = testdomain.ru 
# Имя нашего домена, если не указывать, то по умолчанию выставится минус первый компонент имени узла 
mydomain = testdomain.ru 
myorigin = $myhostname 
# RECEIVING MAIL 
# Здесь задаем, на каких сетевых интерфейсах будет работать Postfix, в моем случае на всех 
inet_interfaces = all 
# Список доменов, на которые будет осуществляться доставка через local transport 
mydestination = localhost, $myhostname, localhost.$mydomain, $config_directory/mydestination 
# REJECTING MAIL FOR UNKNOWN LOCAL USERS 
# Здесь мы указываем, что пользователей testdomain.ru нужно просматривать в $virtual_maibox_maps 
local_recipient_maps = $virtual_maibox_maps 
unknown_local_recipient_reject_code = 550 
# TRUST AND RELAY CONTROL 
# здесь указываем, кому разрешен relay, т.е. пользователям обслуживаемой сети 
mynetworks =  127.0.0.0/8, 10.70.1.0/24 
# Задаем директорию, где будет храниться почта 
mail_spool_directory = /var/spool/mail 
mailbox_command = /usr/bin/procmail -a $DOMAIN -d $LOGNAME 
# Наш почтовый сервер требует сначала комманду helo 
smtpd_helo_required = yes 
transport_maps = hash:/etc/postfix/transport.cf 
# Задаем директорию, где будет храниться почта из виртуальных доменов 
virtual_mailbox_base = /var/spool/mail/ 
# Просмотр таблиц с целью проверки действительности адреса 
virtual_mailbox_maps = pgsql:/etc/postfix/mailbox.pgsql 
virtual_alias_maps = pgsql:/etc/postfix/aliases.pgsql 
# Использую статические uid & gid; 5000 – это mailuser 
virtual_uid_maps = static:5000 
virtual_gid_maps = static:5000 
virtual_minimum_uid = 5000 
# INSTALL-TIME CONFIGURATION INFORMATION 
readme_directory = /etc/postfix/README_FILES 
sample_directory = /etc/postfix/samples 
sendmail_path = /usr/sbin/sendmail 
setgid_group = postdrop 
command_directory = /usr/sbin 
manpage_directory = /usr/share/man 
daemon_directory = /usr/lib/postfix 
newaliases_path = /usr/bin/newaliases 
mailq_path = /usr/bin/mailq 
queue_directory = /var/spool/postfix 
mail_owner = postfix 
# Этот параметр относится к Amavisd 
# Пока комментируем, чтобы можно было проверить работоспособность postfix. 
#content_filter=smtp-amavis:[127.0.0.1]:10024 
Остальные параметры по умолчанию, но их можно изменить по собственному усмотрению.
Далее редактируем конфигурационный файл master.cf:

Код: Выделить всё

#===================================================================================== 
# service  type   Type   Private      Unpriv Chroot       wakeup maxproc      command + args 
#          (yes)  (yes)  (yes)        (yes)  (never)      (100) 
#===================================================================================== 
  smtp           inet   n      -      -      -             -                   smtpd 
  pickup         fifo   n      -      -      60            1                   pickup 
  cleanup        unix   n      -      -      -             0                   cleanup
  qmgr           fifo   n      -      -      300           1                   qmgr 
  rewrite        unix   -      -      -      -             -                   trivial-rewrite 
  bounce         unix   -      -      -      -             0                   bounce 
  defer          unix   -      -      -      -             0                   bounce 
  flush          unix   n      -      -      1000          0                   flush 
  proxymap       unix   -      -      n      -             -                   proxymap 
  smtp           unix   -      -      -      -             -                   smtp 
  relay          unix   -      -      -      -             -                   smtp 
  showq          unix   n      -      -      -             -                   showq 
  error          unix   -      -      -      -             -                   error 
  local          unix   -      n      n      -             -                   local 
  virtual        unix   -      n      n      -             -                   virtual 
  lmtp           unix   -      -      -      -             -                   lmtp 
# далее относится к Amavisd 
  smtp-amavis    unix   -      -      n      -             2                   smtp 
    -o smtp_data_done_timeout=1200
    -o smtp_send_xforward_command=yes
    -o disable_dns_lookups=yes 
  127.0.0.1:10025 inet   n      -      n      -             -                   smtpd 
    -o content_filter=
    -o relay_recipient_maps=
    -o smtpd_restriction_classes=
    -o smtpd_client_restrictions=
    -o smtpd_helo_restrictions=
    -o smtpd_sender_restrictions=
    -o smtpd_recipient_restrictions=permit_mynetworks,reject
    -o mynetworks=127.0.0.0/8
    -o strict_rfc821_envelopes=yes
    -o smtpd_error_sleep_time=0
    -o smtpd_soft_error_limit=1001
    -o smtpd_hard_error_limit=1000 
И соответственно создаем файлы aliases.pgsql, maibox.pgsql, transport.cf:
aliases.pgsql:

Код: Выделить всё

hosts = localhost 
user = mailuser 
password = topsecret 
dbname = mails 
table = aliases 
select_field = dest 
where_field = alias 
mailbox.pgsql: 
hosts = localhost 
user = mailuser 
password = topsecret 
dbname = mails 
table = users 
select_field = home 
where_field = userid 
transport.cf: 
testdomain.ru           virtual: 
another.domain.ru       virtual: 
В transport.cf указываем, каким образом будут обрабатываться домены, наши домены – через virtual, в противном случае они будут обработаны с помощью local_ transport.

Запускаем postfix:

Код: Выделить всё

[root@mosqit /]# service postfix start 
Проверяем работу нашего сервера:

Код: Выделить всё

[root@mosqit  /]#  telnet 127.0.0.1 25 
Trying 127.0.0.1... 
Connected to 10.70.1.254. 
Escape character is '^]'. 
helo localhost 
220 testdomain.ru ESMTP Postfix 
250 testdomain.ru 
quit 
Работает, иначе смотрим лог-файлы в /var/log/maillog.

Создание учетных записей пользователей

Для этого я написал пару простейших скриптов на bash:
add_mailuser.bash:

Код: Выделить всё

#! /bin/bash 
basedir=/var/spool/mail 
echo "Введите e-mail в виде name@domain"
read email
pos=`expr match "$email" '[a-z1-9A-Z.]*@'`
if [ $pos = "0" ]
    then echo "Неправильное имя пользователя"
    exit 
fi 
domain=${email:$pos}
name=${email:0:($pos-1)}
cd $basedir/$domain/$name &> /dev/null
if [ $? = "0" ];
  then
    echo 'Такой пользователь существует !! '
    exit 
fi    
cd $basedir/$domain &> /dev/null
if [ $? = "1" ];
  then
    echo 'Такого домена не существует'
    exit
fi
echo "Введите полное имя " 
read fullname
echo "Введите пароль "
read pass
echo "пароль $pass"
echo -E  "INSERT INTO public.users (userid, password, realname, uid, gid, home, mail) VALUES ('$email', '$pass', '$fullname', '42', '42','$domain/$name/inbox', NULL);" | /usr/bin/psql -U postgres mails
mkdir $basedir/$domain/$name
touch $basedir/$domain/$name/inbox
chmod 600 $basedir/$domain/$name/inbox
chmod 700 $basedir/$domain/$name
chown postfix:postfix $basedir/$domain/$name -R
ls $basedir/$domain/$name/inbox &> /dev/null
if [ $? = "1" ];
  then
    echo 'Ошибочка вышла! '
    exit
fi    
echo "Пользователь создан успешно" 
del_mailuser.bash:
#! /bin/bash
basedir=/var/spool/mail 
echo "Введите e-mail, который хотите удалить в виде name@domain"
read email
pos=`expr match "$email" '[a-z1-9A-Z.]*@'`
if [ $pos = "0" ]
    then echo "Неправильное имя пользователя"
    exit
fi 
domain=${email:$pos}
name=${email:0:($pos-1)}
cd $basedir/$domain/$name &> /dev/null
if [ $? = "1" ];
  then
    echo 'Такой пользователь не существует !! '
    exit
fi    
echo "DELETE from public.users where userid='$email';" | usr/bin/psql -U postgres mails
rm -rf $basedir/$domain/$name &> /dev/null
cd $basedir/$domain/$name &> /dev/null
echo $?
if [ $? = "0" ];
  then
    echo 'Ошибочка вышла! '
    exit
fi    
echo "Пользователь удален успешно" 
add_alias.bash:
#! /bin/bash 
echo "Введите aliasname виде name@domain"
read aliasname
pos=`expr match "$aliasname" '[a-z1-9A-Z.]*@'`
if [ $pos = "0" ]
    then echo "Неправильный aliasname"
    exit
fi 
echo "Введите destination в виде name@domain"
read dest
pos=`expr match "$dest" '[a-z1-9A-Z.]*@'`
if [ $pos = "0" ]
    then echo "Неправильный destination"
    exit
fi 
echo "Введите комментарий" 
read comment 
echo -E  "INSERT INTO public.aliases (email, alias, comment) VALUES ('$aliasname', '$dest', '$comment');" | /usr/bin/psql -U postgres mails 
echo "Alias создан успешно" 
Скрипты созданы на скорую руку и поэтому не совершенны, но всегда существует возможность модифицировать их по своему усмотрению.

Создаем почтового пользователя test@testdomain.ru:

Код: Выделить всё

[root@mosqit /]# add_mailuser.bash 
Выполняем инструкции, которые выводятся на экран.

Далее проверяем, как Postfix доставляет почту:

Код: Выделить всё

[root@mosqit  /]# service postfix restart 
[root@mosqit  /]# telnet 127.0.0.1 25 
Trying 127.0.0.1... 
Connected to 10.70.1.254. 
Escape character is '^]'. 
helo localhost 
220 testdomain.ru ESMTP Postfix 
250 testdomain.ru 
mail from: vasia@gde-to.tam 
250 Ok 
rcpt to: test@testdomain.ru 
250 Ok 
data 
354 End data with <CR><LF>.<CR><LF> 
test message 
. 
quit 
Обращаю внимание на точку c новой строки после test message, это означает, что передача данных завершена.
Далее идем в каталог /var/spool/mail/testdomain/test и смотрим содержимое файла inbox, в нем и должно находиться наше сообщение. Если файл пуст, то опять же смотрим лог-файл (maillog).

ClamAV

Идем в /etc/clamav.conf и находим строчку ScanMail и раскомментируем ее, для того чтобы антивирус проверял файлы формата mailbox.
Запускаем ClamAV:

Код: Выделить всё

[root@mosqit /]# service clamd start
Amavisd-new

Далее настраиваем /etc/amavis/amavisd.conf по своему усмотрению, конечно же, перед этим прочитав документацию. Лично я ничего не изменял, но скорее всего со временем придется внести коррективы.

Запускаем Amavisd-new:

Код: Выделить всё

[root@mosqit /]# service amavisd start 
Проверяем его работу:

Код: Выделить всё

[root@mosqit  /]# telnet 127.0.0.1 10024 
220 [127.0.0.1] ESMTP amavisd-new service ready 
quit 
Раскомментируем строчку:

Код: Выделить всё

filter=smtp-amavis:[127.0.0.1]: 10024 
в файле main.cf. Перезапускаем Postfix, запускаем ClamaV, Amavisd:

Код: Выделить всё

[root@mosqit /]# service postfix restart 
Как и ранее, проверяем с помощью telnet работоспособность postfix. Если все нормально, то переходим к настройке Dovecot.

Dovecot

Далее редактируем файл настроек dovecot /etc/dovecot.conf. Так же внимательно вчитываемся в комментарии к параметрам.
dovecot.conf:

Код: Выделить всё

# Протоколы, которые мы используем 
protocols = imap imaps pop3 pop3s 
## IMAP login process 
login = imap 
## POP3 login process 
login = pop3 
## Mail processes 
first_valid_uid = 5000 
# Путь к директории, где хранится почта, где %d –  имя домена, %n – имя пользователя 
default_mail_env = mbox:/var/spool/mail/%d/%n/: INDEX=/var/spool/mail/%d/%n 
mbox_locks = fcntl flock 
## Authentication processes 
auth = default 
auth_mechanisms = plain 
auth_userdb = pgsql /etc/dovecot/pgsql.conf 
auth_passdb = pgsql /etc/dovecot/pgsql.conf 
# root т.к. использовать порты до 1024 порта может только root 
auth_user = root 
После этого нам требуется сгенерировать SSL-сертификат, т.к. у нас заявлены протоколы imaps и pop3s (s – secure).
Для этого правим файл /etc/dovecot/dovecot-openssl.cnf:

Код: Выделить всё

[ req ] 
default_bits = 1024 
encrypt_key = yes 
distinguished_name = req_dn 
x509_extensions = cert_type 
prompt = no 
[ req_dn ] 
# country (2 letter code) 
C=RU 
# State or Province Name (full name) 
ST=Bashkortostan 
# Locality Name (eg. city) 
L=Ufa 
# Organization (eg. company) 
O=Home Organizations. 
# Organizational Unit Name (eg. section) 
OU=POP3 IMAP server 
# Common Name (*.example.com is also possible) 
CN=testdomain.ru 
# E-mail contact 
emailAddress= master@testdomain.ru 
[ cert_type ] 
nsCertType = server 
Запускаем скрипт для генерации сертификата.

Код: Выделить всё

[root@mosqit /]# /usr/share/dovecot/mkcert.sh 
Правим файл /etc/dovecot/pgsql.conf, в котором указываем, как Dovecot будет подключаться и забирать данные.

Код: Выделить всё

connect = host = localhost dbname = mails user = mailuser password = secret 
default_pass_scheme = PLAIN 
password_query = SELECT password FROM users WHERE userid = '%u' 
user_query = SELECT '/var/spool/mail/'|| home, uid, gid FROM users WHERE userid = '%u' 
Все настройки произведены, можно испытать работо-способность нашего pop3-сервера:

Код: Выделить всё

[root@mosqit  /]# service dovecot start 
Настраиваем наш почтовый клиент и проверяем, доставляется почта или нет. Имя пользователя указывается полное, т.е. test@testdomain.ru, а не test.
Если же не получается, то заглядываем в /var/log/messages и устраняем причину (довольно часто причиной бывает банальная опечатка при редактировании конфигурационных файлов).

Источник: http://av5.com/journals-magazines-online/1/43/399