From: evgy@rr.ru
Date: Thu, 7 Aug 2003 19:50:19 +0100
Subject: Почтовый сервер на базе Postfix с аккаунтами пользователей в PostgreSQL.
Задача: почтовая система для сети примерно на 300 человек,
пользователи в базе, защита от вирусов, аутентификация SMTP
отсутствует.
Дано: Операционка - FreeBSD 4.8-RELEASE. Все привиллегированные
команды исполняются через sudo, посему подразумеваю наличие ее у вас.
Установку и настройку ее не описываю.
Для реализации проекта задействовано:
* Postfix-2.0.13
* Courier-IMAP-2.0.0
* PostgreSQL-7.3.4
* DrWEB-4.29.2-freebsd4
В статье подразумевается виртуальный домен thedom.ru ( the domain :)
Прежде всего, скажу о моей "идеологии". Никому не навязываю, при
наличии минимальных знаний можно ее ни коим образом не придерживаться.
* 1) Люблю, чтобы все стояло под /usr/local/. Соответственно, все
ставим туда.
* 2) Всякие системные штуковины наподобие gmake ставим из портов,
остальное - крупные пользовательские сервисы, ставим ручками.
Ругайте или нет, я люблю покопаться, как и что устроено.
* 3) Предпочитаю работать через консоль. Иксов на сервере у меня
нет.
Итак. Кое-что сегодня мы будем ставить из портов. А раз из портов -
порты надо прежде обновить.
Небольшое отступление по обновлению портов, или что такое CVSup
(сивисап). Это софтверная система, позволяющая (помимо всего прочего)
вам всегда получить конкретную, или, что нам интереснее, самую
последнюю версию какой-либо части дерева файлов. В нашем случае, нас
интересует дерево портов.
CVSup
Если вас интересует подробное руководство по сивисапу, то можно
сходить на
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/cvsup.html,
я именно по этому руководству и делал.
Сначала поставим саму программу, которая будет нам обновлять дерево
портов. То есть, саму cvsup. Поставить можно из портов (см. мое
замечание выше - я отношу эту программу к системным программам) или из
пакаджей.
(по поводу портов: здесь сразу скажу, в /usr/ports/net/ лежит 2 версии
cvsup: cvsup и cvsup-without-gui. Первая рассчитана работу с иксами,
вторая - консольная, нам и нужна. Но по поводу установки из портов
меня насторожила фраза в доке по упомянутому выше адресу:
...But be forewarned: the net/cvsup port depends on the Modula-3 system, which
takes a substantial amount of time and disk space to download and build....
так как модулу ставить я не захотел, то...)
...я предпочел установку пакаджа, потому пошел на
http://www.freebsd.org/ports/index.html, впечатал в поле поиска
cvsup-without-gui, скачал пакадж (
ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-4-stable/All/cvsup-without-gui-16.1h.tgz)
и поставил его: sudo pkg_add cvsup-without-gui-16.1h.tgz
Для работы программы нужен каталог и конфиг, так что делаем
sudo mkdir /usr/local/etc/cvsup
и пишем конфиг. У меня конфиг зовется /etc/supfile и выглядит так:
Если интересует что здесь что значит - все описано в упомянутой доке
по сивисапу, скажу лишь, что данный конфиг обновляет только дерево
портов.
Теперь все готово к обновлению. Запускаем его:
sudo cvsup /etc/supfile
После успешного выполнения (у меня ушло на это около 25 минут) должно
написать Finished successfully. При желании, если хотим всегда иметь
свежее дерево портов, то можно добавить упомянутый вызов (но только с
полным путем к программе cvsup) в /etc/crontab. Пример - запуск
программы ежедневно в 6:00 утра:
0 6 * * * root /usr/local/bin/cvsup /etc/supfile
PostgreSQL
Но мы время не тратим, открываем второе терминальное окошко, и
приступаем к установке постгреса. Как и все существенное - ставим
ручками. Идем на сайт слона http://www.postgresql.org/, и выбираем
последнюю версию постгреса - на текущий момент есть 7.3.4. Скачиваем и
разворачиваем тар:
tar xzf postgresql-7.3.4.tar.gz
cd postgresql-7.3.4
Пока продолжают обновляться порты, можно глянуть в INSTALL. Там
написано, что для сборки постгреса нужен gmake версии не ниже 3.76.1,
а не make, который штатно есть в системе. Если в ответ на команду
gmake -v
на нас выругаются, вместо того, чтобы сообщить номер версии, придется
ставить еще и gmake. Учитывая, что это системная штука - ставим из
портов. Значит, ждем, пока порты дообновляются :) Как только это
свершится,
cd /usr/ports/devel/gmake/
sudo make install clean
Возвращаемся в каталог дистрибутива постгреса. Постгрес по умолчанию
ставится куда мы желаем - в /usr/local/, где создает для всего своего
хозяйства подкаталог pgsql. В процессе установки для нужд постгреса
создадим пользователя.
Соответственно, лежит он в /usr/local/etc/rc.d/ и у меня зовется
340.pgsql.sh. Не забываем для него
sudo chmod a+x /usr/local/etc/rc.d/340.pgsql.sh
Стартуем постгрес:
sudo /usr/local/etc/rc.d/340.pgsql.sh start
Если в ответ получаем postmaster successfully started, значит все
прекрасно, иначе смотрим в логи /usr/local/pgsql/log/pgsql.log и
/var/log/messages что не так, и разбираемся. Если все нормально, то
можем идти дальше. Нам надо создать в постгресе пользователя, под
именем которого с постгресом будет работать постфикс. Делаем так:
sudo -u postgres /usr/local/pgsql/bin/createuser
Enter name of user to add: postfix
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
Пользователь создан, но пока у нас нет никакой защиты в постгресе, а
это - нехорошо.
sudo -u postgres /usr/local/pgsql/bin/psql 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 postfix with password 'topsecret';
ALTER USER
template1=# alter user postgres with password 'postgres';
ALTER USER
template1=#q
Как вы, я надеюсь, поняли, последними командами мы установили
постгресовские пароли: для пользователя postfix - пароль topsecret, а
для postgres - пароль postgres. ВНИМАНИЕ, эти пароли не имеют НИКАКОГО
отношения в паролям пользователей в системе!!! Нам остается поправить
конфигурационный файл доступа (если мне не изменяет память, hba
расшифровывается как host based authentication)
sudo vi /usr/local/pgsql/data/pg_hba.conf
правим внизу поля METHOD, что мы хотим проверку паролей, а не trust
(работать без пароля), стоящее по умолчанию:
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
local all all md5
host all all 127.0.0.1 255.255.255.255 md5
после этого проверяем, перезапускаем постгрес и убеждаемся, что у нас
спросят пароль:
sudo /usr/local/etc/rc.d/340.pgsql.sh restart
Restarting PostgreSQL...
waiting for postmaster to shut down......done
postmaster successfully shut down
postmaster successfully started
sudo -u postgres /usr/local/pgsql/bin/psql -u template1
psql: Warning: The -u option is deprecated. Use -U.
User name: postfix
Password: topsecret
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=>q
Пускает. Что ж, создаем нашу базу данных, в которой мы будем хранить
пользователей.
sudo -u postgres /usr/local/pgsql/bin/createdb mail
Password: postgres
CREATE DATABASE
sudo -u postgres /usr/local/pgsql/bin/psql mail
Password: postgres
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
mail=# CREATE TABLE users (
mail(# id int,
mail(# email text not null,
mail(# mbox text not null,
mail(# pass text,
mail(# name text);
CREATE TABLE
mail=# grant select on users to postfix;
GRANT
mail=# CREATE TABLE aliases (
mail(# email text not null,
mail(# alias text not null,
mail(# comment text default '');
CREATE TABLE
mail=# grant select on aliases to postfix;
GRANT
В первую таблицу мы будем вносить пользователей, во вторую - альясы.
Итак, теперь мы готовы к тому, чтобы начать саму установку самого
постфикса. Прежде всего, четко уверяем себя, что мы прощаемся с
сендмейлом. Поэтому в /etc/rc.conf пишем
sendmail_enable="NONE"
Postfix
Постфикс, как и БД, мы будем ставить ручками. Дело это не тривиальное,
и придется немного повозиться. Для того, чтобы постфикс умел работать
с постгресом, первый придется пропатчить. Но это чуть позже. А пока
идем на http://www.postfix.org и берем последнюю версию постфикса.
Сейчас это 2.0.13. Потом берем упомянутый патч -
http://www.mat.cc/postfix/postfix-pg.postfix-2.0.0.2.patch, и
сохраняем его. Как следует из названия, патч рассчитан на версию
постфикса 2.0.0.2, у нас же - 2.0.13. Но новее я ничего найти не смог,
однако и этот патч замечательно работает, после некоторой подгонки
напильником :) Открываем postfix-pg.postfix-2.0.0.2.patch любым
текстовым редактором и выполняем такие процедуры:
1. Найти все подстроки "2.0.0.2" и заменить их на "2.0.13"
2. Найти все подстроки "-vanilla" и заменить их все пустой строкой -
""
А далее - все просто:
tar xzf postfix-2.0.13.tar.gz
patch < postfix-pg.postfix-2.0.0.2.patch
cd postfix-2.0.13
Как я говорил уже, я люблю, чтоб все лежало под /usr/local, в
отдельной папочке для каждого сервиса. Постфикс пусть раскладывает
свое хозяйство в /usr/local/postfix. Сам постфикс по умолчанию
ставится далеко не туда, куда я хочу, поэтому все задаем ключиками.
Кроме того, ключиками же говорим, что у нас уже есть постгрес.
Следующий ужас :) дается как одна команда в одну строку:
Постфиксу тоже нужен свой пользователь в системе. Делаем sudo vipw и
добавляем строчку (юиды и гиды можно взять другие):
postfix:*:1001:1001::0:0:Postfix Mail System:/var/spool/postfix:/sbin/nologin
а потом - sudo vi /etc/group и добавляем:
postfix:*:1001:
postdrop:*:1002:
При инсталляции у меня почему-то начал ругаться на то, что не может
найти библиотечку от постгреса - libpq.so.3. Вылечилось командой
sudo ln -s /usr/local/pgsql/lib/libpq.so.3 /usr/local/lib/libpq.so.3
Ставим:
sudo make install
Если вы делали конфигурацию (см. выше) так, как предлагаю я, то при
инсталляции вам останется на все вопросы согласиться с предлагаемыми
по умолчанию значениями:
Ура! Сам постфикс поставился. Рискнем выполнить первую настройку. У
постфикса 2 главных конфигурационных файла main.cf и master.cf. Если
следовать тому, как мы все ставим, то файлы будут лежать в
/usr/local/postfix/etc. Даем: sudo vi /usr/local/postfix/etc/main.cf и
первым делом правим конфиг на предмет альясов:
(у вас пути, разумеется, могут немного отличаться) Запустим постфикс и
посмотрим, что получилось:
sudo /usr/local/postfix/sbin/postfix start
Пошлите сами себе письмо (это описывать не буду), проверьте, что будет
в логах /var/log/maillog и /var/log/messages. Если все работает -
переходим к самой интересной части - виртуальным почтовым доменам.
Открываем конфигурацию main.cf постфикса и пишем:
Что все это значит? Во всех документациях, что мне встречались, это
объяснялось так: сделайте и не парьтесь. Я так не люблю. Надо ж хоть
чуть-чуть представлять, что мы тут такое делаем?... На подробное
описание я не претендую, но все же.
transport_maps определяет список наших виртуальных доменов и
транспортов, используемых при их обслуживании. Под транспортом
понимается способ обслуживания почтового сообщения этого домена -
например, положить в локальный почтовый ящик (транспорт local),
передать на другой SMTP сервер (транспорт smtp), положить в локальный
виртуальный почтовый ящик (транспорт virtual) и т.п. У нас будет один
домен, тестовый, соответственно, мой
/usr/local/postfix/etc/transportfile содержит:
thedom.ru virtual:
то есть, указывает, что для адресов домена thedom.ru необходимо
применять транспорт virtual. Так как постфикс будет работать с хешем
этого файла, то нам надо сделать:
cd /usr/local/postfix/etc/
sudo /usr/local/postfix/sbin/postmap transportfile
virtual_mailbox_base говорит, что надо добавлять к путям виртуальных
почтовых ящиков, извлеченным из БД. Так как мы будем хранить в БД
полные пути, то здесь пишем просто "/". virtual_mailbox_maps
определяет, откуда постфикс будет брать информацию о путях к
виртуальным почтовым ящикам. Фактически, файл mailbox.pgsql полностью
описывает, как подключиться к БД, и где что взять:
hosts = localhost
user = postfix
password = topsecret
dbname = mail
table = users
select_field = mbox
where_field = email
#additional_conditions = and status = 'goodboy'
Этот файл указывает подключиться к постгресовой базе mail на
localhost'е, зайти под именем postfix и паролем topsecret, и сделать
такой запрос вида select mbox from users where email=адрес. Зачум
нужен additional_conditions, думаю, смекнете :) Аналогично и с
директивами virtual_alias_maps и virtual_uid_maps. Первая описывает,
откуда взять виртуальные альясы, вторая - UIDы пользователей, чтоб
знать с какими правами обращаться на почтовый ящик.
uid.pgsql:
hosts = localhost
user = postfix
password = topsecret
dbname = mail
table = users
select_field = id
where_field = email
aliases.pgsql:
hosts = localhost
user = postfix
password = topsecret
dbname = mail
table = aliases
select_field = alias
where_field = email
Последнеи 2 строчки с virtual_minimum_uid и virtual_gid_maps указывают
минимальное значение UIDа виртуального пользователя, которое возможно
в системе (некая степень защиты) а так же номер группы для всех
пользователей. Последний тоже, если надо, можно вынимать из постгреса.
Только зачем? :) Поэтому стоит static:1002. Вспомните, перед тем, как
ставить постфикс, мы делали группу postdrop:*:1002: - именно для этих
целей.
Теперь немного надо подстроить постгрес, иначе постфикс не сможет
коннектиться к БД через сокет.
sudo vi /usr/local/pgsql/data/postgresql.conf
Опция tcpip_socket должна быть раскомментирована и быть true. Создадим
каталог для виртуальных почтовых ящиков:
теперь добавляем пробного пользователя в БД, и посылаем ему письмо:
/usr/local/pgsql/bin/psql -u mail
psql: Warning: The -u option is deprecated. Use -U.
User name: postgres
Password: postgres
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
mail=# INSERT INTO users VALUES (2002, 'evgy@thedom.ru',
'/var/spool/VMAIL/evgy@thedom.ru/', 'pass','test user');
INSERT 16989 1
mail=# select * from users ;
id | email | mbox | pass | name
------+----------------+----------------------------------+------+------
2002 | evgy@thedom.ru | /var/spool/VMAIL/evgy@thedom.ru/ | pass |
mail=# insert into aliases VALUES ('cool@thedom.ru','evgy@thedom.ru');
mail=# SELECT * from aliases ;
email | alias | comment
----------------+----------------+---------
cool@thedom.ru | evgy@thedom.ru |
(1 row)
Теперь пробуем написать письмо от имени пользователя evgy@thedom.ru
самому evgy@thedom.ru. Успешно прошедшее письмо можно будет обнаружить
в каталоге /var/spool/VMAIL/evgy@thedom.ru/new. Так же проверим альяс
- пошлем письмо на cool@thedom.ru.
Если есть ошибки - смотрим на логи /var/log/maillog и
/var/log/messages и пытаемся понять, в чем дело.
Для запуска постфикса при старте системы я использую такой скриптик:
more /usr/local/etc/rc.d/360.postfix.sh
#!/bin/sh
case "$1" in
start) echo "Starting POSTFIX..."
/usr/local/postfix/sbin/postfix start
;;
Ну а если все нормально, то ставим Courier-IMAP. После постфикса его
установка покажется детским лепетом :) Скачиваем дистрибутив - на
текущий момент это версия 2.0.0 -
http://prdownloads.sourceforge.net/courier/courier-imap-2.0.0.tar.b
z2. Как и во всех нормальных дистрибутивах, внутри есть INSTALL, в
котором все подробнейше описано. Это для любопытных. Следующие команды
выполняем как обычный пользователь:
bzip2 -d courier-imap-2.0.0.tar.bz2
tar xf courier-imap-2.0.0.tar
export LDFLAGS="-L/usr/local/pgsql/lib"
export CPPFLAGS="-I/usr/local/pgsql/include"
cd courier-imap-2.0.0
./configure --prefix=/usr/local/courier-imap --with-piddir=/var/run
gmake (именно gmake, а не make)
запускаем authlib/authinfo - эта программа должна выдать что-то вроде:
Главное, чтоб присутствовал "authpgsql". По умолчанию - его не
находит, для этого мы и экспортировали LDFLAGS и CPPFLAGS.
sudo gmake install (именно gmake, а не make)
sudo gmake install-configure (именно gmake, а не make)
cd /usr/local/courier-imap/etc
sudo vi authdaemonrc
находим строчку authmodulelist="authcustom authcram authuserdb
authpgsql authpam" Это перечень всех возможных способов авторизации,
поддерживаемых на машине. Оставляем от нее authmodulelist="authpgsql",
больше ничего не трогаем.
sudo vi authpgsqlrc
Файл прекрасно внутри описан и по сути тоже задает как коннектиться к
БД, и где что брать. У нас опции будут иметь такие значения::
#PGSQL_HOST pgsql.example.com
PGSQL_PORT 5432
PGSQL_USERNAME postfix
PGSQL_PASSWORD topsecret
PGSQL_DATABASE mail
PGSQL_USER_TABLE users
#PGSQL_CRYPT_PWFIELD crypt
PGSQL_CLEAR_PWFIELD pass
PGSQL_UID_FIELD id
PGSQL_GID_FIELD 1002
PGSQL_LOGIN_FIELD email
PGSQL_HOME_FIELD mbox
PGSQL_NAME_FIELD name
PGSQL_MAILDIR_FIELD mbox
Обратите внимание, параметры PGSQL_HOST и PGSQL_CRYPT_PWFIELD по
умолчанию раскомментированы, они нам не нужны, закомментируйте их -
поставьте "#". Запускаем и проверяем
разворачиваем их. Создаем пользователя drweb, принадлежащего группе
drweb. Я брал юид и гид 1003:
sudo vipw, добавляем drweb:*:1003:1003::0:0:DrWeb Anti Virus System:/nonexistent:/sbin/nologin
sudo vi /etc/group, добавляем drweb:*:1003:
Заходим в каталог веба. Видим install и install.sh. По умолчанию ДрВеб
вообше пожелает встать в /opt - жуть! Это рассчитано на Linux. Поэтому
придется поправить путь в файле установки - install.sh. Конфиги свои
drweb пусть хранит в /etc/drweb - это немного отходит от моей
идеологии - все в /usr/local, но иначе придется слишком много
исправлять в настройках веба. Так что смиримся. Кроме того, доктор все
равно хочет иметь спульный каталог в /var - это правильно. Так что он
разложится за рамками /usr/local... Итак, приступим: правим -
sudo vi install.sh
меняем строчку DEFAULT_INSTALL_DIR на значение
DEFAULT_INSTALL_DIR="/usr/local/drweb".
sudo sh install.sh
Enter destination directory (/usr/local/drweb is default): [Enter]
Select interface language: 0) english 1) russian
0
Dr.Web is installed to /usr/local/drweb.
Edit /drweb32.ini to complete setup.
Сразу же разворачиваем примочку для связки веба с постфиксом.
tar xzf drweb-postfix-4.29.12-D-freebsd4.tar.gz
заходим внутрь и внутри видим 2 каталога - opt и etc. Содержимое
каталога etc/drweb должно соответственно попасть в /etc/drweb, все из
opt/drweb кладем в /usr/local/drweb/
Разкомментировать строку User = drweb и проверить UpdatePath =
"/usr/local/drweb/updates".
Ну и попробуем:
sudo /usr/local/etc/rc.d/100.drwebd.sh start
Посмотрим, что скажет, если ругается - исправляем что не так. Далее
правим конфигурационный файл для связки с постфиксом
/etc/drweb/drweb_postfix.conf. Обязательно надо прописать альясы для
оповещений:
посылаем письмо сами себе и проверяем, как пойдет. В логе обязательно
должна проскочить строка вроде
... drweb-postfix: dwlib: scan[44496]: message(/var/drweb/spool/drweb.tmp.YKMi0
q) sent by .... is passed
для того, чтобы симитировать вирус, создаем файл с текстом:
X5O!P%@AP[4PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
и сохраняем его под именем virus-test.com. Приаттачиваем к письму и
проверяем.
Ну и напоследок. Антивирусные базы надо бы обновлять. Для этого в
комплекте доктора есть утилитка /usr/local/drweb/update/update.pl, а
для ее работы нужен перловый модуль String::CRC32. Идем на
http://www.cpan.org/, ищем и находим на
http://www.cpan.org/authors/id/S/SO/SOENKE/String-CRC32-1.2.tar.gz
,
tar xzf String-CRC32-1.2.tar.gz
cd String-CRC32-1.2
perl Makefile.PL
make
sudo make install
запускаем update.pl. Если все ок, то можем запускать через cron с
желаемой периодичностью. Все.
_________________________________________________________________
Жду комментариев на evgy ЭТ rr.ru.
При подготовке статьи использовался материал статьи Бешкова Андрея
Юрьевича (http://onix.opennet.ru/ - Почтовая система среднего и малого
офиса) и материалы из соответствующих описаний к упомянутым здесь
программам (вроде INSTALL, README и пр.). Отдельное спасибо Певневу
Андрею за периодические консультации и подсказки ;)
редакция 1.1
1133 Прочтений • [Почтовый сервер на базе Postfix с аккаунтами пользователей в PostgreSQL. (mail postfix postgresql imap virus)] [08.05.2012] [Комментариев: 0]