Настройка exim + cyrus-imapd + mysql

Настройка exim + cyrus-imapd + mysql на базе OpenBSD

Автор: fr33man.

Началось все как всегда банально — кто-то постучал в асю. Спрашивали, как настроить cyrus-imap. Я с ним не работал, поэтому честно ответил, что не знаю, но пообещал разобраться(благо времени немного было). Но просто разобраться было не интересно. :) Поэтому я решил настроить почтовую связку на базе OpenBSD. В принципе все довольно просто, но меня заинтересовал cyrus-imap, который, как выяснилось, хранит всю почту в своей собственной базе(db). После гугления этого вопроса я наткнулся на много различных обсуждений, в которых часто говорилось, что cyrus-imap всех рвет по скорости. Я немного подумал и решил, что нужно его настроить, а потом потестировать. )) Здесь описан процесс его настройки на чистой системе OpenBSD-4.2.
Так же хочется отдельно сказать, что большинство конфигов(exim и postfixadmin) я взял из статьи Лиса(lissyara) про связку exim + courer-imap.
Итак приступим.

Ставим mysql-сервер и mysql-клиент:

# export PKG_PATH="ftp://ftp.openbsd.org/pub/OpenBSD/4.2/packages/i386/"
# pkg_add mysql-server
mysql-client-5.0.45: complete
p5-DBD-mysql-3.0008:p5-Net-Daemon-0.39: complete
p5-DBD-mysql-3.0008:p5-PlRPC-0.2018p0: complete
p5-DBD-mysql-3.0008:p5-DBI-1.53: complete
p5-DBD-mysql-3.0008: complete
mysql-server-5.0.45: complete
--- mysql-server-5.0.45 -------------------
You can find detailed instructions on how to install a database
in /usr/local/share/doc/mysql/README.OpenBSD.
#

Установка mysql завершена. Давайте немного его настроим. Для начала создадим БД:

# /usr/local/bin/mysql_install_db
Installing MySQL system tables...
OK
Filling help tables...
OK
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/usr/local/bin/mysqladmin -u root password 'new-password'
/usr/local/bin/mysqladmin -u root -h openbsd.my.domain password 'new-password'
See the manual for more instructions.
Please report any problems with the /usr/local/bin/mysqlbug script!

The latest information about MySQL is available on the web at
http://www.mysql.com
Support MySQL by buying support/licenses at http://shop.mysql.com
#

Теперь создадим свой login class для Mysql'а. Добавим в /etc/login.conf такие строки:

mysql:\
:openfiles-cur=1024:\
:openfiles-max=2048:\
:tc=daemon:

и пересоздадим бд login.conf:

# cap_mkdb /etc/login.conf

Хорошо. Теперь добавим mysql в автозапуск:

# cat >> /etc/rc.local
if [ -x /usr/local/bin/mysqld_safe ] ; then
su -c mysql root -c '/usr/local/bin/mysqld_safe >/dev/null 2>&1 &'
echo -n ' mysql'
fi

Запускаем:

# su -c mysql root -c '/usr/local/bin/mysqld_safe >/dev/null 2>&1 &'
# ps ax | grep sql
19337 p0 I 0:00.03 /bin/sh /usr/local/bin/mysqld_safe
29798 p0 I 0:00.74 /usr/local/libexec/mysqld --basedir
=/usr/local --datadir=/var/mysql --user=_mysql --pid-file=
/var/mysql/openbsd.my.domain.pid --po
4427 p0 R+ 0:00.01 grep sql
#

Как видите — все работает.
Удаляем из mysql левые БД.

# mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.45-log OpenBSD port: mysql-server-5.0.45

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.00 sec)

mysql> drop database test;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
bye
#

Отлично. Так как юзать мы будем postfixadmin, то я вкратце напишу, как настроить apache. Перед установкой php нужно установить xbase — Там есть необходимые библиотеки. Монтируем сидюк с Openbsd и делаем такую штуку:

# cd /
# mount -t cd9660 /dev/cd0a /mnt
# tar xzvphf /mnt/4.2/i386/xbase42.tgz

Усе — теперь ставим php5:

# pkg_add php5-core
libiconv-1.9.2p3: complete
gettext-0.14.6p0: complete
libxml-2.6.29: complete
php5-core-5.2.3: complete
--- php5-core-5.2.3 -------------------
To finish the install, enable the php5 module with:
/usr/local/sbin/phpxs -s

To enable parsing of PHP scripts, add the following to
/var/www/conf/httpd.conf:

AddType application/x-httpd-php .php

Copy the config file below into /var/www/conf/php.ini
/usr/local/share/examples/php5/php.ini-recommended

Don't forget that the default OpenBSD httpd is chrooted
into /var/www by default, so you may need to create support
directories such as /var/www/tmp for PHP to work correctly.
#

И ставим расширение php5 — mysql:

# pkg_add php5-mysql
php5-mysql-5.2.3: complete
--- php5-mysql-5.2.3 -------------------
Enable this module in php.ini using the following command:

/usr/local/sbin/phpxs -a mysql
#

Усе установилось... Теперь добавляем в Httpd.conf строчку для модуля php5:

# /usr/local/sbin/phpxs -s
[activating module `php5' in /var/www/conf/httpd.conf]
cp /usr/local/lib/php/libphp5.so /usr/lib/apache/modules/libphp5.so
chmod 755 /usr/lib/apache/modules/libphp5.so
cp /var/www/conf/httpd.conf /var/www/conf/httpd.conf.bak
cp /var/www/conf/httpd.conf.new /var/www/conf/httpd.conf
rm /var/www/conf/httpd.conf.new

You should copy the sample configuration files from
/usr/local/share/examples/php5 to /var/www/conf/php.ini
#

И включаем модуль mysql:

# cp /usr/local/share/examples/php5/php.ini-dist /var/www/conf/php.ini
# /usr/local/sbin/phpxs -a mysql
Activating extension : mysql
#

Добавляем две строки в /var/www/conf/httpd.conf:

DirectoryIndex index.php index.html
AddType application/x-httpd-php .php

Добавляем httpd в автозапуск:

# cat >> /etc/rc.conf.local
httpd_flags=""

Запускаем apache:

# apachectl start
/usr/sbin/apachectl start: httpd started
# ps ax | grep httpd
17814 ?? Is 0:00.12 httpd: parent [chroot /var/www] (httpd)
16596 ?? I 0:00.02 httpd: child (httpd)
28908 ?? I 0:00.01 httpd: child (httpd)
6870 ?? I 0:00.02 httpd: child (httpd)
19022 ?? I 0:00.03 httpd: child (httpd)
29760 ?? I 0:00.03 httpd: child (httpd)
21614 p0 I+ 0:00.01 grep httpd
#

Вгоняем в Mysql такой dump:

# cd /root
# cat > dump.sql

--
-- БД: `exim`
--
USE mysql;
INSERT INTO `user` (`Host`, `User`, `Password`)
VALUES ('localhost','exim',password('exim'));
INSERT INTO `db` (`Host`, `Db`, `User`, `Select_priv`)
VALUES ('localhost','exim','exim','Y');
FLUSH PRIVILEGES;
GRANT USAGE ON exim.* TO exim@localhost;
GRANT SELECT, INSERT, DELETE, UPDATE ON exim.* TO exim@localhost;
CREATE DATABASE `exim`;
USE `exim`;

-- --------------------------------------------------------

--
-- Структура таблицы `admin`
--

CREATE TABLE `admin` (
`username` varchar(255) NOT NULL default '',
`password` varchar(255) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`username`),
KEY `username` (`username`)
) TYPE=MyISAM COMMENT='Exim and cyrus-imap Admin - Virtual Admins';

-- --------------------------------------------------------

--
-- Структура таблицы `alias`
--

CREATE TABLE `alias` (
`address` varchar(255) NOT NULL default '',
`goto` text NOT NULL,
`domain` varchar(255) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
`copy_mail` int(1) NOT NULL default '1',
PRIMARY KEY (`address`),
KEY `address` (`address`)
) TYPE=MyISAM COMMENT='Exim and cyrus-imap Admin - Virtual Aliases';

-- --------------------------------------------------------

--
-- Структура таблицы `domain`
--

CREATE TABLE `domain` (
`domain` varchar(255) NOT NULL default '',
`description` varchar(255) NOT NULL default '',
`aliases` int(10) NOT NULL default '0',
`mailboxes` int(10) NOT NULL default '0',
`maxquota` int(10) NOT NULL default '0',
`transport` varchar(255) default NULL,
`backupmx` tinyint(1) NOT NULL default '0',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`domain`),
KEY `domain` (`domain`)
) TYPE=MyISAM COMMENT='Exim and cyrus-imap Admin - Virtual Domains';

-- --------------------------------------------------------

--
-- Структура таблицы `domain_admins`
--

CREATE TABLE `domain_admins` (
`username` varchar(255) NOT NULL default '',
`domain` varchar(255) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
KEY `username` (`username`)
) TYPE=MyISAM COMMENT='Exim and cyrus-imap Admin - Domain Admins';

-- --------------------------------------------------------

--
-- Структура таблицы `log`
--

CREATE TABLE `log` (
`timestamp` datetime NOT NULL default '0000-00-00 00:00:00',
`username` varchar(255) NOT NULL default '',
`domain` varchar(255) NOT NULL default '',
`action` varchar(255) NOT NULL default '',
`data` varchar(255) NOT NULL default '',
KEY `timestamp` (`timestamp`)
) TYPE=MyISAM COMMENT='Exim and cyrus-imap Admin - Log';

-- --------------------------------------------------------

--
-- Структура таблицы `mailbox`
--

CREATE TABLE `mailbox` (
`username` varchar(255) NOT NULL default '',
`password` varchar(255) NOT NULL default '',
`name` varchar(255) NOT NULL default '',
`maildir` varchar(255) NOT NULL default '',
`quota` int(10) NOT NULL default '0',
`domain` varchar(255) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`modified` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`username`),
KEY `username` (`username`)
) TYPE=MyISAM COMMENT='Exim and cyrus-imap Admin - Virtual Mailboxes';

-- --------------------------------------------------------

--
-- Структура таблицы `vacation`
--

CREATE TABLE `vacation` (
`email` varchar(255) NOT NULL default '',
`subject` varchar(255) NOT NULL default '',
`body` text NOT NULL,
`cache` text NOT NULL,
`domain` varchar(255) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`email`),
KEY `email` (`email`)
) TYPE=MyISAM COMMENT='Exim and cyrus-imap Admin - Virtual Vacation';

# mysql -u root < dump.sql

Ставим postfix-admin:

# cd /var/www/htdocs/
# ftp \
> http://optusnet.dl.sourceforge.net/sourceforge/postfixadmin/postfixadmin...
Trying 211.29.132.142...
Requesting
http://optusnet.dl.sourceforge.net/sourceforge/postfixadmin/postfixadmin...
100% |***************************************| 156 KB 00:04
Successfully retrieved file.
#

Устанавливаем:

# tar zxf postfixadmin-2.1.0.tgz
# mv postfixadmin-2.1.0 mailadmin
# chown -R www:www /var/www/htdocs/mailadmin/

Теперь редактируем конфиг postfixadmin'а:

# cd mailadmin
# cp config.inc.php.sample config.inc.php

Редактируем config.inc.php:

$CONF['database_type'] = 'mysql';
$CONF['database_host'] = '127.0.0.1';
$CONF['database_user'] = 'exim';
$CONF['database_password'] = 'exim';
$CONF['database_name'] = 'exim';
$CONF['database_prefix'] = '';
$CONF['encrypt'] = 'cleartext';
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['smtp_server'] = '127.0.0.1';
$PALANG['charset'] = 'cp1251';

И последний штрих:

# cat config.inc.php | \
> sed 's/change-this-to-your.domain.tld/local.ru/' > \
> tmp && mv tmp config.inc.php

Если будете использовать русский язык, то файл: /var/www/htdocs/mailadmin/templates/admin_menu.tpl — тут после строки содержащий backup воткните 4-е <br>.
Так же не забудьте запаролить админку.

Все. Можете заходить по адресу: http://ваш_серв/mailadmin/admin/.

Осталось осилить exim и cyrus-imap..

Ставим exim:

# cd /usr/ports/mail/exim/

Добавляем в Makefile, перед строкой

FLAVORS=no_exiscan no_x11 mysql postgresql sqlite3 ldap iconv sasl

такую вещь:

EXIM_MAKECAT+= "TRANSPORT_LMTP=yes\n"

Это необходимо для того, что подрубить в exim'е транспорт lmtp. Собираем пакет:

# env FLAVOR="no_x11 mysql" make package

... skipped ...
===> Building package for exim-4.67-no_x11-mysql
Create /usr/ports/packages/i386/all/exim-4.67-no_x11-mysql.tgz
Link to /usr/ports/packages/i386/ftp/exim-4.67-no_x11-mysql.tgz
Link to /usr/ports/packages/i386/cdrom/exim-4.67-no_x11-mysql.tgz
#

Устанавливаем:

# pkg_add /usr/ports/packages/i386/all/exim-4.67-no_x11-mysql.tgz
useradd: Warning: home directory `/var/spool/exim'
doesn't exist, and -m was not specified
exim-4.67-no_x11-mysql: complete
--- exim-4.67-no_x11-mysql -------------------
If you intend replacing sendmail with exim, then don't
forget to modify /etc/mailer.conf accordingly; see
mailwrapper(8).

A perl script may help converting from exim-3.xx config
files and has been installed in
/usr/local/share/examples/exim/convert4r4
you have mail in /var/mail/root
#

Составляем конфиг /etc/exim/configure:

#!/bin/sh
# Файл конфигурации: /usr/local/etc/exim/configure

# моя конфига экзма. Будь проклят тот день,
# когда мне пришла в голову мысль подписать
# русские поясния ко всем пунктам! :) Хоть и
# делал я это в первую очередь для себя -
# чтоб лучше понять его, но работа эта оказалась
# слишком масштабная и неблагодарная...

# Имя хоста. Используется в EHLO.
# Фигурирует в других пунктах, если они не заданы -
# типа qualify_domain и прочих..
# Если тут ничё не установлено (строка закомметрована)
# то используется то, что вернёт функция uname()
primary_hostname = local.ru

# Вводим данные для подключения к MySQL серверу.
# словечко `hide`, вначале, означает, что при
# вызове проверки конфига командой
# exim -bV config_file эти данные не будут отображаться.
# Если без него - то будут показаны... Формат записи:
# хост/имя_бд/пользователь/пароль
hide mysql_servers = localhost/exim/exim/exim

 

# Делаем список локальных доменов. Далее этот
# список будет фигурировать в виде +local_domains
# В данном случае домены выбираются из БД MySQL. Также
# можно их просто перечислить через двоеточие. Есть интересная
# возможность, можно указать юзер@[хост] - lissyara@[222.222.4.5]
domainlist local_domains = ${lookup mysql{SELECT `domain` \
FROM `domain` WHERE \
`domain`='${domain}' AND \
`active`='1'}}

# делаем список доменов с которых разрешены релеи.
# Далее этот список будет в виде +relay_to_domains
# Можно использовать символы подстановки, типа:
# .... = *.my.domen.su : !spam.my.domen.su : first.su
# тогда пропускается всё, что похоже на *.my.domen.su, но
# от spam.my.domen.su релеится почта не будет.
domainlist relay_to_domains = ${lookup mysql{SELECT `domain` \
FROM `domain` WHERE \
`domain`='${domain}' AND \
`active`='1'}}

# Составляем список хостов с которых разрешён неавторизованый
# релей. Обычно в нём находятся локальные сети, и локалхост...
# ЛокалХост в двух видах был внесён сознательно - пару раз
# сталкивался с кривым файлом /etc/hosts - результатом было
# непонимание `localhost` но пониманием 127.0.0.1/8
hostlist relay_from_hosts = localhost:127.0.0.0/8:192.168.0.0/16

# Вводим названия acl`ов для проверки почты. (В общем-то, это
# необязательно, если вы делаете открытый релей, или хотите
# принимать вообще всю почту с любого хоста для любых
# получателей... Тока потом не жалуйтесь что у Вас спам
# и провайдер выкатывает немеряный счёт :))
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data

# Имя домена добавляемое для локальных отправителей (реальных
# юзеров системы) т.е. почта отправляемая от root, будет от
# root@домен_указанный_здесь. Если пункт незадан, то используется
# имя хоста из `primary_hostname`. Логичней было бы написать здесь
# local.ru, но мне удобней иначе:
qualify_domain = local.ru

# Имя хоста для ситуации, обратной предыдущей, - это имя домена
# добавляемое к почте для системных юзеров, ну и вообще для почты
# пришедшей на адрес типа `root`, `lissyara`, & etc... Если этот
# пункт незадан то используется значение полученное из
# предыдущего пункта - `qualify_domain`
qualify_recipient = local.ru

# А это как раз кусок вышеописанного анахронизма - про почту в
# виде user@[222.222.222.222] - принимать её или нет. По дефолту
# (когда строка закомментирована) значение - false. Если захотите
# поставить true то надо будет добавить в список доменов
# комбинацию @[] - она означает `все локальные адреса`
allow_domain_literals = false

# Пользователь от которого работает exim
exim_user = _exim

# группа в кторой работает exim
exim_group = _exim

# запрещаем работу доставки под юзером root - в целях безопасности
never_users = root

# Тоже анахронизм (на самом деле, не такой уж анахронизм, но все давно
# забили на ident и закрыли файрволлом tcp:113...) Это проверка - Ваш
# хост спрашивает у удалённого, с которого было подключение, а кто
# собстно ко мне подключился на такой-то порт? Если на удалённом хосте
# работает identd - он может ответить (а может и не ответить - как
# настроить), скажет UID пользователя от которого установлено
# соединение, тип ОС, и имя пользователя. Теперь, понимаете, почему
# у всех оно зарублено и файрволлами позакрыто? :) Это же палево :)
# Тока на мой взгляд, если на сервере всё настроено правильно -
# то вовсе это и не страшно.
# Короче - если хостс поставить * то будет проверять все. Таймаут -
# если поставить 0 то не будет ждать ответа ни от кого. По
# вышеописанным причинам - отключаем
#rfc1413_hosts = *
rfc1413_query_timeout = 0s

# Если сообщение было недоставлено, то генерится соощение
# об ошибке. Если сообщение об ошибке не удалось доставить
# то оно замораживается на указанный в этом пункте срок,
# после чего снова попытка доставить его. При очередной
# неудаче - сообщение удаляется.
ignore_bounce_errors_after = 45m

# Замороженные сообщения, находящиеся в очереди, дольше
# указанного времени удаляются и генерится сообщение
# об ошибке (при условии, что это не было недоставленное
# сообщение об ошибке :))
timeout_frozen_after = 15d

# собсно на этом штатный конфиг кончился, но
# меня-то это не устраивает... Поэтому пошли пункты,
# почёрпнутые из других источников.

# список адресов, через запятую, на которые засылаются
# сообщения о замороженных сообщениях (о замороженых
# уведомлениях о заморозке, сообщения не генерятся. - я
# надеюсь эта строка понятна :))
freeze_tell = admin@local.ru

# Список хостов, почта от которых принимается, несмотря
# на ошибки в HELO/EHLO
helo_accept_junk_hosts = 192.168.0.0/16

# Через какое время повторять попытку доставки
# замороженного сообщения
auto_thaw = 1h

# Приветствие сервера
smtp_banner = "$primary_hostname, ESMTP EXIM $version_number"

# Максимальное число одновременных подключений по
# SMTP. Рассчитывать надо исходя из нагрузки на сервер
smtp_accept_max = 50

# максимальное число сообщений принимаемое за одно соединение
# от удалённого сервера (или пользователя). C числом 25
# я имел проблемы тока один раз - когда у меня три дня лежал
# инет и после его подъёма попёрли мессаги. Но у меня не так
# много почты - всего 30 пользователей.
smtp_accept_max_per_connection = 25

# чё-то про логи и борьбу с флудом - я так понимаю -
# максимальное число сообщений записываемых в логи
smtp_connect_backlog = 30

# максимальное число коннектов с одного хоста
smtp_accept_max_per_host = 20

# Ход ладьёй - для увеличения производительности,
# директория `spool` внутри, разбивается на
# директории - это ускоряет обработку
split_spool_directory = true

# Если у сообщения много адресатов на удалённых хостах,
# то запускатеся до указанного числа максимально число
# параллельных процессов доставки
remote_max_parallel = 15

# при генерации сообщения об ошибке прикладывать
# не всё сообщение, а кусок (от начала) указанного
# размера (иногда полезно и целиком - в таком случае
# просто закомментируйте эту строку)
return_size_limit = 70k

# размер сообщения. У меня стоит относительно большой
# размер (`относительно` - потому, что на большинстве
# хостов оно ограничено 2-5-10мб, либо стоит анлим.)
message_size_limit = 24M

# разрешаем неположенные символы в HELO (столкнулся
# с этим случайно - имя фирмы состояло из двух слов
# и какой-то раздолбай домен обозвал my_firme_name
# прям с подчёркиваниями... Виндовые клиенты при
# соединении радостно рапортовали о себе
# `vasya.my_firme_name` ну а экзим их футболил :))
helo_allow_chars = _

# Принудительная синхронизация. Если отправитель
# торопится подавать команды, не дождавшись ответа,
# то он посылается далеко и надолго :) Немного,
# спам режется.
smtp_enforce_sync = false

# Выбираем, что мы будем логировать
# + - писать в логи,
# - - Не писать в логи.
# +all_parents - все входящие?
# +connection_reject - разорваные соединения
# +incoming_interface - интерфейс (реально - IP)
# +lost_incoming_connections - потеряные входящие
# соединения
# +received_sender - отправитель
# +received_recipients - получатель
# +smtp_confirmation - подтверждения SMTP?
# +smtp_syntax_error - ошибки синтаксиса SMTP
# +smtp_protocol_error - ошибки протокола SMTP
# -queue_run - работа очереди (замороженные мессаги)
log_selector = \
+all_parents \
+connection_reject \
+incoming_interface \
+lost_incoming_connection \
+received_sender \
+received_recipients \
+smtp_confirmation \
+smtp_syntax_error \
+smtp_protocol_error \
-queue_run

# Убираем собственную временную метку exim`a из логов, её ставит
# сам syslogd - нефига дублировать
syslog_timestamp = no

begin acl

# Эти правила срабатывают для каждого получателя
acl_check_rcpt:

# принимать сообщения которые пришли с локалхоста,
# не по TCP/IP
accept hosts = :
accept hosts = localhost : 127.0.0.1

# Запрещаем письма содержащие в локальной части
# символы @; %; !; /; |. Учтите, если у вас было
# `percent_hack_domains` то % надо убрать.
# Проверяются локальные домены
deny message = "Unknown symbols in address"
domains = +local_domains
local_parts = ^[.] : ^.*[@%!/|]

# Проверяем недопустимые символы для
# нелокальных получателей:
deny message = "Unknown symbols in address"
domains = !+local_domains
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./

# Принимаем почту для постмастеров локальных доменов без
# проверки отправителя (я закомментировал, т.к. это -
# основной источник спама с мой ящик).

accept local_parts = postmaster
domains = +local_domains

# Запрещщаем, если невозможно проверить отправителя
# (отсутствует в списке локальных пользователей)
# У себя я это закоментил, по причине, что некоторые
# железяки (принтеры, & etc) и программы (Касперский, DrWEB)
# умеют слать почту, в случае проблем но не умеют ставить
# нужного отправителя. Такие письма эта проверка не пускает.
# require verify = sender

# Запрещщаем тех, кто не обменивается приветственными
# сообщениями (HELO/EHLO)
deny message = "You must send HELO/EHLO"
condition = ${if eq{$sender_helo_name}{}{yes}{no}}

# Принимаем сообщения от тех, кто аутентифицировался:
# Вообще, большинство конфигов в рунете - это один и тот же
# конфиг написанный Ginger, в котором этот пункт расположен
# внизу. Но при таком расположении рубятся клиенты с adsl,
# ppp, и прочие зарезанные на последующих проверках. Но это
# жа неправильно! Этом мои пользователи из дома! Потому
# я это правило расположил до проверок.
accept authenticated = *

# Рубаем нах, тех, кто подставляет свой IP в HELO
deny message = "Dont enter my ip in helo"
hosts = *:!+relay_from_hosts
condition = ${if eq{$sender_helo_name}\
{$sender_host_address}{true}{false}}

# Рубаем тех, кто в HELO пихает мой IP (2500 за месяц!)
deny condition = ${if eq{$sender_helo_name}\
{$interface_address}{yes}{no}}
hosts = !127.0.0.1 : !localhost : *
message = "Its my ip address. Go away"

# Рубаем тех, кто в HELO пихает только цифры
# (не бывает хостов ТОЛЬКО из цифр)
deny condition = ${if match{$sender_helo_name}\
{\N^\d+$\N}{yes}{no}}
hosts = !127.0.0.1:!localhost:*
message = "hmm... I dont understand your helo"

# Рубаем хосты типа *adsl*; *dialup*; *pool*;....
# Нормальные люди с таких не пишут. Если будут
# проблемы - уберёте проблемный пункт (у меня клиенты
# имеют запись типа asdl-1233.zone.su - я ADSL убрал...)
deny message = "I dont like your host"
condition = ${if match{$sender_host_name} \
{adsl|dialup|pool|peer|dhcp} \
{yes}{no}}

# Задержка. (это такой метод борьбы со спамом,
# основанный на принципе его рассылки) На этом рубается
# почти весь спам. Единственно - метод неприменим на
# реально загруженных MTA - т.к. в результате ему
# приходится держать много открытых соединений.
# но на офисе в сотню-две человек - шикарный метод.
#
# более сложный вариант, смотрите в статье по exim и
# курьер имап. Т.к. там метод боле умный (просто правил
# больше :), то можно и на более загруженные сервера ставить)
warn
# ставим дефолтовую задержку в 20 секунд
set acl_m0 = 20s
warn
# ставим задержку в 0 секунд своим хостам и
# дружественным сетям (соседняя контора :))
hosts = +relay_from_hosts : 213.234.195.226/28
set acl_m0 = 0s
warn
# пишем в логи задержку (если оно вам надо)
logwrite = Delay $acl_m0 for $sender_host_name \
[$sender_host_address] with HELO=$sender_helo_name. Mail \
from $sender_address to $local_part@$domain.
delay = $acl_m0

 

 

 

# Проверка получателя в локальных доменах.
# Если не проходит, то проверяется следующий ACL,
# и если непрошёл и там - deny
accept domains = +local_domains
endpass
message = "I dont know this user"
verify = recipient

# Проверяем получателя в релейных доменах
# Опять-таки если не проходит -> следующий ACL,
# и если непрошёл и там - deny
accept domains = +relay_to_domains
endpass
message = "I dont know route to this host"
verify = recipient

# Разрешаем почту от доменов в списке relay_from_hosts
accept hosts = +relay_from_hosts

# Если неподошло ни одно правило - чувак явно ищет
# открытый релей. Пшёл прочь. :)
deny message = "Its not openrelay ))"

# Тут идут ACL проверяющие содержимое (тело) письма.
# Без них будут пропускаться все сообщения.

acl_check_data:

accept

 

# чё делаем с почтой
begin routers

# Поиск маршрута к хосту в DNS. Если маршрут не найден в DNS -
# то это `унроутабле аддресс`. Не проверяются локальные
# домены, 0.0.0.0 и 127.0.0.0/8
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more

system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{SELECT `goto` FROM `alias` WHERE \
`address`='${quote_mysql:$local_part@$domain}' OR \
`address`='${quote_mysql:@$domain}'}}

mysqluser:
driver = accept
condition = ${if eq{}{${lookup mysql{SELECT `maildir` FROM `mailbox` \
WHERE `username`='${quote_mysql:$local_part@$domain}'}}}{no}{yes}}
transport = cyrus_delivery

# начинаются транспорты - как доставляем почту
begin transports

# Доставка на удалённые хосты - по SMTP
remote_smtp:
driver = smtp

# Транспорт для доставки почты локальным пользователям.
cyrus_delivery:
driver = lmtp
socket = /var/imap/socket/lmtp
batch_max = 100
user = _cyrus

address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add

# Имя программы
address_pipe:
driver = pipe
return_output

# Транспорт для автоответов
address_reply:
driver = autoreply

 

# Начинаются повторы недоставленных писем.
begin retry

# Этот кусок я не трогал. Думаю разработчики лучше знают,
# какие тут должны быть цифирьки. Если же вы это знаете
# лучше их - меняйте. Хотя... А какого, если Вы такой
# умный, читаете этот мануал? Может ну, их, цифирьки, а? :)
# Address or Domain Error Retries
# ----------------- ----- -------
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h

# преобразование адресов. У меня такого нету.
begin rewrite

# Секция авторизации при отправке писем. Ввиду того,
# что почтовых клиентов много, и все всё делают
# по-своему, то и механизмов авторизации три...
begin authenticators

# А вот по какому методу авторизуется оутглюк - я уже и
# не помню... Хотя в своё время долго ковырялся,
# пока настроил... Толь plain, толь login...
auth_plain:
driver = plaintext
public_name = PLAIN
server_condition = ${lookup mysql{SELECT `username` FROM \
`mailbox` WHERE `username` = \
'${quote_mysql:$1}' AND `password` = \
'${quote_mysql:$2}'}{yes}{no}}
server_prompts = :
server_set_id = $2

# Вроде по этому оутглюк, а по предыдущему нетскейп.
auth_login:
driver = plaintext
public_name = LOGIN
server_condition = ${lookup mysql{SELECT `username` FROM \
`mailbox` WHERE `username` = \
'${quote_mysql:$1}' AND `password` = \
'${quote_mysql:$2}'}{yes}{no}}
server_prompts = Username:: : Password::
server_set_id = $1

# А так авторизуется "Летучая Мышь" - TheBat!
auth_cram_md5:
driver = cram_md5
public_name = CRAM-MD5
server_secret = ${lookup mysql{SELECT `password` FROM \
`mailbox` WHERE `username` \
= '${quote_mysql:$1}'}{$value}fail}
server_set_id = $1

# Фсё. Конфиг кончился. Два дня убил.
# &copy; lissyara 2006-02-25, 01:19

Меняем sendmail на exim:

# cat > /etc/mailer.conf
sendmail /usr/local/bin/exim
send-mail /usr/local/bin/exim
mailq /usr/local/bin/exim -bp
newaliases /usr/local/bin/exim -bi
hoststat /usr/local/bin/exim
purgestat /usr/local/bin/exim
#

Добавляем в /etc/rc.local, для отключения sendmail'а:

# cat >> /etc/rc.conf.local
sendmail_flags="NO"
#

Добавляем exim в автозагрузку(/etc/rc.local):

if [ -x /usr/local/bin/exim ] ; then
/usr/local/bin/exim -bd -q30m >/dev/null 2>&1
echo -n ' exim'
fi

Вырубаем sendmail:

# kill `cat /var/run/sendmail.pid`

Врубить сейчас exim не получится — мы пока не поставили cyrus-imap:
1) У нас нет пользователя _cyrus
2) У нас нет доставщика почты(мы используем cyrus-imap для доставки почты в ящики)

Так что перейдем к настройке cyrus-imap.

Перед тем, как ставить cyrus-imap необходимо установить cyrus-sasl — он потребуется для аутентификации:

# pkg_add cyrus-sasl-2.1.22p1-mysql
cyrus-sasl-2.1.22p1-mysql: complete
#

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

/* ссылки нужно писать одной строкой. Тут просто не влезло. */
# cd /root
# ftp http://email.uoa.gr/download/cyrus/
cyrus-imapd-2.3.8/cyrus-imapd-2.3.8-autocreate-0.10-0.diff
Trying 195.134.100.120...
Requesting http://email.uoa.gr/download/cyrus/
cyrus-imapd-2.3.8/cyrus-imapd-2.3.8-autocreate-0.10-0.diff
100% |**************************************************| 84571 00:00
Successfully retrieved file.
# ftp http://email.uoa.gr/download/cyrus/
cyrus-imapd-2.3.8/cyrus-imapd-2.3.8-autosieve-0.6.0.diff
Trying 195.134.100.120...
Requesting http://email.uoa.gr/download/cyrus/
cyrus-imapd-2.3.8/cyrus-imapd-2.3.8-autosieve-0.6.0.diff
100% |**************************************************| 7906 00:00
Successfully retrieved file.
# ftp http://email.uoa.gr/download/cyrus/
cyrus-imapd-2.3.8/cyrus-imapd-2.3.8-rmquota+deletemailbox-0.2-1.diff
Trying 195.134.100.120...
Requesting http://email.uoa.gr/download/cyrus/
cyrus-imapd-2.3.8/cyrus-imapd-2.3.8-rmquota+deletemailbox-0.2-1.diff
100% |**************************************************| 19775 00:00
Successfully retrieved file.
#

Разархивируем cyrus-imap:

/* На данном шаге система установит все
зависимости для cyrus-imapd... так что придется подождать... )) */
# make extract
===> Checking files for cyrus-imapd-2.3.8
>> cyrus-imapd-2.3.8.tar.gz doesn't seem to exist on this system.
>> Fetch ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-imapd-2.3.8.tar.gz.
100% |*******************************************| 2155 KB 00:27
>> Size matches for /usr/ports/distfiles/cyrus-imapd-2.3.8.tar.gz
>> (SHA256) cyrus-imapd-2.3.8.tar.gz: OK
===> cyrus-imapd-2.3.8p0 depends on: cyrus-sasl-* - found
===> cyrus-imapd-2.3.8p0 depends on: db-4.* - not found

... skipped ...

===> Extracting for cyrus-imapd-2.3.8
#

Теперь патчим:

# cd w-cyrus-imapd-2.3.8/cyrus-imapd-2.3.8/
# patch -p1 < /root/cyrus-imapd-2.3.8-autocreate-0.10-0.diff
Hmm... Looks like a unified diff to me...
The text leading up to this was:

... skipped ...

done
# patch -p1 < /root/cyrus-imapd-2.3.8-autosieve-0.6.0.diff
Hmm... Looks like a unified diff to me...
The text leading up to this was:

... skipped ...

done
# patch -p1 < /root/cyrus-imapd-2.3.8-rmquota+deletemailbox-0.2-1.diff
Hmm... Looks like a unified diff to me...
The text leading up to this was:

... skipped ...

done
#

Собираем пакет для cyrus-imapd и устанавливаем его:

# cd /usr/ports/mail/cyrus-imapd/
# make package
===> Patching for cyrus-imapd-2.3.8
===> Configuring for cyrus-imapd-2.3.8

... skipped ...

===> Building package for cyrus-imapd-2.3.8p0
Create /usr/ports/packages/i386/all/cyrus-imapd-2.3.8p0.tgz
Link to /usr/ports/packages/i386/ftp/cyrus-imapd-2.3.8p0.tgz
Link to /usr/ports/packages/i386/cdrom/cyrus-imapd-2.3.8p0.tgz
`/usr/ports/mail/cyrus-imapd/w-cyrus-imapd-2.3.8/fake-i386/.fake_done' is up to date.
===> Building package for cyrus-imapd-perl-2.3.8
Create /usr/ports/packages/i386/all/cyrus-imapd-perl-2.3.8.tgz
Link to /usr/ports/packages/i386/ftp/cyrus-imapd-perl-2.3.8.tgz
Link to /usr/ports/packages/i386/cdrom/cyrus-imapd-perl-2.3.8.tgz
# pkg_add /usr/ports/packages/i386/all/cyrus-imapd-2.3.8p0.tgz
cyrus-imapd-2.3.8p0: complete
--- cyrus-imapd-2.3.8p0 -------------------
Don't forget to edit /etc/services to include missing network services
if needed.
# pkg_add /usr/ports/packages/i386/all/cyrus-imapd-perl-2.3.8.tgz
cyrus-imapd-perl-2.3.8: complete
#

Установилось. ) Теперь составляем конфиг для imap'а:

# cat > /etc/imapd.conf
# Автоматом создавать квоту для пользователя.
# на самом деле нужно только для автоматического
# создания юзерских хомяков
autocreatequota: 10485760
# Создаем почтовые ящики при попытке отправить
# им письмо
createonpost: yes
# Директория с БД и тд.
configdirectory: /var/imap
# Настройки безопасности sasl
sasl_minimum_layer: 0
# Где храним почту
partition-default: /var/spool/imap
# Какие пользователи являются админами
admins: admin
# Директория со скриптами
sievedir: /var/imap/sieve
# sendmail прога
sendmail: /usr/sbin/sendmail
# как проверяем пасс
sasl_pwcheck_method: auxprop
# расположение сокетов
lmtpsocket: /var/imap/socket/lmtp
idlesocket: /var/imap/socket/idle
notifysocket: /var/imap/socket/notify
# сама проверка пароля...
# все параметры очевидны. )
sasl_auxprop_plugin: sql
sasl_sql_engine: mysql
sasl_sql_user: exim
sasl_sql_passwd: exim
sasl_sql_database: exim
sasl_sql_hostnames: 127.0.0.1
sasl_sql_select: SELECT password FROM mailbox WHERE username='%u@%r' AND active='1'
sasl_sql_verbose: yes
sasl_mech_list: PLAIN LOGIN
sasl_password_format: plaintext
# разрешаем не криптованные пароли
allowplaintext: yes
altnamespace: yes
# имя сервера
servername: local.ru
# используем виртуальные домены
virtdomains: userid
# домен по умолчанию
defaultdomain: local.ru
#

Теперь создаем необходимые файлы и папки для работы imap'а.

# /usr/local/share/examples/cyrus-imapd/tools/mkimap
reading configure file /etc/imapd.conf...
i will configure directory /var/imap.
i saw partition /var/spool/imap.
done
configuring /var/imap...
creating /var/spool/imap...
done
#

Добавим cyrus-imap в автозагрузку:

# cat >> /etc/rc.local
if [ -x /usr/local/libexec/cyrus-imapd/master ] ; then
/usr/local/libexec/cyrus-imapd/master \
-C /etc/imapd.conf -M /etc/cyrus.conf -d
echo -n ' cyrus-imap'
fi

Отлично! ) Теперь можно запускать cyrus-imap и exim:

# /usr/local/libexec/cyrus-imapd/master \
> -C /etc/imapd.conf -M /etc/cyrus.conf -d
# ps ax | grep master
29110 ?? Is 0:00.02 /usr/local/libexec/cyrus-imapd/master
-C /etc/imapd.conf -M /etc/cyrus.conf -d
27057 p0 I+ 0:00.01 grep master
# /usr/local/bin/exim -bd -q30m
# ps ax | grep exim
27271 ?? Is 0:00.01 /usr/local/bin/exim -bd -q30m (exim-4.66)
#

Можно проверять!

Заходим в postfixadmin и создаем какой-нить домен. И создаем пользователя двух пользователей: admin@local.ru — будет администратором для cyrus-imapd, прошу обратить внимание, что этот админ не должен получать почту. Его необходимо использовать только для администрирования cyrus-imapd. И второго пользователя: test@local.ru и смотрим логи:

2008-04-03 02:51:49 1JhBo5-0007cT-Ci <= postmaster@local.ru H=(127.0.0.1) [127.0.0.1] I=[127.0.0.1]:25 P=esmtp S=298 from <postmaster@local.ru> for test@local.ru
2008-04-03 02:51:49 1JhBo5-0007cT-Ci => test <test@local.ru> R=mysqluser T=cyrus_delivery
2008-04-03 02:51:49 1JhBo5-0007cT-Ci Completed

Как видите — ящик test успешно был создан, а ящик админа не создался, потому что ему не надо. ))

Теперь можете настраивать свой любимый почтовый клиент(я юзаю thunderbird) на использование нашего сервера.

P.S. По скорости работы cyrus-imap рулит. )
P.S.2 В отличии от courier'а — можно папки создавать в корне, а не во "Входящие". Это радует.
P.S.3 Если Вам нужны логи от cyrus-imap'а, то в /etc/syslogd.conf пропишите следующее:

local6.debug /var/log/imapd.log
auth.debug /var/log/auth.log

И перезапустите syslog:

# kill -HUP `cat /var/run/syslog.pid`

P.S.4 В следующей статье попытаюсь рассказать про такие вкусности, как sieve. )

Поделитесь с друзьями ссылкой на эту страницу в своей социальной сети
 

Смотрите далее по теме "Linux + Линукс + exim + cyrus + imapd + mysql + техническая информация"

Блок близких по теме записей. Мы подобрали для вас наиболее популярные публикации Фэнтези портала.

Темы Автор Просмотры

Как я искал драйвер для геймпада Xbox 360 для PC - Windows

Поиски в яндексе ничего хорошего не давали, кроме куче файлов с подозрительных ресурсов, которые выкладывали данный файл для заработка на рекламе, не более... Делаю вывод, уже не...
Mascher
7,898

Распиновка RJ45 Ethernet 10/100 BaseT (cross over)

Давно у меня валяется сия картинка, когда у меня спрашивают как сделать патчкорд, я обычно даю эту картинку, и красиво и понятно :)     Этот тип патчкорда используется для...
Mascher
6,235

Восстановление жесткого диска Seagate Barracuda ES.2 ST500320NS

Случилось так что у моего знакомого сломался жесткий диск Seagate Barracuda ES.2 модель ST500320NS, это линейка жестких дисков повышенной надежности от фирмы Seagate... Как оказалось позже,...
Mascher
2,047

Руссификация консоли Gentoo Linux

1. Быстрая русификация консоли Материал из Gentoo Linux Wiki Перейти к: навигация, поиск Файл: /etc/rc.conf unicode="YES" Файл: /etc/conf.d/consolefont consolefont="Cyr_a8x16"...
Mascher
1,712