Почтовая система на базе MTA exim::Журнал СА7.2004
www.samag.ru
Журнал «БИТ. Бизнес&Информационные технологии»      
Поиск   
              
 www.samag.ru    Web  0 товаров , сумма 0 руб.
E-mail
Пароль  
 Запомнить меня
Регистрация | Забыли пароль?
Журнал "Системный администратор"
Журнал «БИТ»
Подписка
Архив номеров
Где купить
Наука и технологии
Авторам
Рекламодателям
Контакты
   

  Опросы
1001 и 1 книга  
19.03.2018г.
Просмотров: 6979
Комментарии: 0
Машинное обучение с использованием библиотеки Н2О

 Читать далее...

12.03.2018г.
Просмотров: 7441
Комментарии: 0
Особенности киберпреступлений в России: инструменты нападения и защита информации

 Читать далее...

12.03.2018г.
Просмотров: 4847
Комментарии: 0
Глубокое обучение с точки зрения практика

 Читать далее...

12.03.2018г.
Просмотров: 3189
Комментарии: 0
Изучаем pandas

 Читать далее...

12.03.2018г.
Просмотров: 3987
Комментарии: 0
Программирование на языке Rust (Цветное издание)

 Читать далее...

19.12.2017г.
Просмотров: 3991
Комментарии: 0
Глубокое обучение

 Читать далее...

19.12.2017г.
Просмотров: 6487
Комментарии: 0
Анализ социальных медиа на Python

 Читать далее...

19.12.2017г.
Просмотров: 3340
Комментарии: 0
Основы блокчейна

 Читать далее...

19.12.2017г.
Просмотров: 3616
Комментарии: 0
Java 9. Полный обзор нововведений

 Читать далее...

16.02.2017г.
Просмотров: 7476
Комментарии: 0
Опоздавших не бывает, или книга о стеке

 Читать далее...

17.05.2016г.
Просмотров: 10844
Комментарии: 0
Теория вычислений для программистов

 Читать далее...

30.03.2015г.
Просмотров: 12551
Комментарии: 0
От математики к обобщенному программированию

 Читать далее...

18.02.2014г.
Просмотров: 14271
Комментарии: 0
Рецензия на книгу «Читаем Тьюринга»

 Читать далее...

13.02.2014г.
Просмотров: 9289
Комментарии: 0
Читайте, размышляйте, действуйте

 Читать далее...

12.02.2014г.
Просмотров: 7244
Комментарии: 0
Рисуем наши мысли

 Читать далее...

10.02.2014г.
Просмотров: 5540
Комментарии: 3
Страна в цифрах

 Читать далее...

18.12.2013г.
Просмотров: 4770
Комментарии: 0
Большие данные меняют нашу жизнь

 Читать далее...

18.12.2013г.
Просмотров: 3590
Комментарии: 0
Компьютерные технологии – корень зла для точки роста

 Читать далее...

04.12.2013г.
Просмотров: 3295
Комментарии: 0
Паутина в облаках

 Читать далее...

03.12.2013г.
Просмотров: 3526
Комментарии: 1
Рецензия на книгу «MongoDB в действии»

 Читать далее...

02.12.2013г.
Просмотров: 3181
Комментарии: 0
Не думай о минутах свысока

 Читать далее...

Друзья сайта  

 Почтовая система на базе MTA exim

Архив номеров / 2004 / Выпуск №7 (20) / Почтовая система на базе MTA exim

Рубрика: Администрирование /  Электронная почта   | Дополнительные материалы

ВСЕВОЛОД СТАХОВ

Почтовая система на базе MTA exim

В этой статье пойдет речь о создании эффективного почтового сервера на базе MTA exim. Первый вопрос, который, конечно же, приходит в голову – «Почему именно exim?». Отвечают на этот вопрос по-разному, поэтому я скажу, что меня так привлекает в exim:

  • логичная схема обработки почты;
  • высокая скорость работы;
  • удобный формат конфигурационного файла;
  • широчайшие возможности по поиску каких-либо значений в файлах, СУБД, LDAP;
  • встроенная поддержка smtp-аутентификации;
  • небольшое число найденных уязвимостей (фактически я знаю только об одной, найденной недавно, она касалась версий exim до 4.20 включительно);
  • очень большое количество возможностей, а также чрезвычайная гибкость;
  • возможность полной замены sendmail (т.е. можно сделать):

ln -sf /usr/local/sbin/exim /usr/libexec/sendmail

На мой взгляд, exim является весьма и весьма удачным продуктом, не зря он используется по умолчанию в ОС Debian GNU Linux. Два больших минуса exim состоят в том, что отсутствует качественная документация на русском языке (этот недостаток я, возможно, постараюсь в скором времени исправить написанием книги, посвященной целиком и полностью этому замечательному MTA) и необходимость правки Makefile для включения тех или иных возможностей exim.

Итак, для начала подумаем, что должна содержать «идеальная» с точки зрения удобства администрирования и использования почтовая система. Сформулируем ряд требований к почтовой системе:

  • простота управления пользователями;
  • возможность предоставления доступа для отправки почты пользователям локальной сети и мобильным пользователям (при помощи smtp-аутентификации);
  • максимальная защита от хакерских атак, вирусов и спама.

Базовой системой для установки MTA явилась FreeBSD 5.2.1, что обусловило определенные особенности установки. Перечислю весь набор программного обеспечения для организации mail-сервера:

  • exim-4.34;
  • MTA (mail transfer agent – агент передачи почты);
  • courier-3.0.4 – imap-сервер для доступа к почте пользователей, не имеющих локальных пользовательских учетных записей (виртуальные пользователи);
  • ClamAV – для поиска вирусов;
  • SpamAssasin – для поиска спамерских писем;
  • PostgreSQL-7.4.2 – для хранения всех данных о пользователях почтовой системы;
  • SquirrelMail – просто приятный веб-интерфейс для почты (требует веб-сервер и php).

Конечно, можно собрать все вышеперечисленные компоненты и вручную, но я не поклонник такого подхода. Во-первых, надо очень четко представлять порядок сборки различных компонентов. Во-вторых, необходимо разбираться в куче опций для связки различных библиотек. В-третьих, надо четко представлять себе все пути и знать, каких пользователей надо добавлять. Ну и в-четвертых, это дело очень сложно обновлять. Потому мы воспользуемся услугами системы портов (если у вас, например, Debian GNU Linux, то нужный пакет называется exim4-daemon-heavy).

Для этого ставим следующие порты:

databases/pogstgresql7

mail/exim

при компиляции необходимо указать следующие опции:

make WITH_PGSQL=yo

mail/p5-Mail-SpamAssassin

security/clamav

mail/courier-imap

при компиляции опять же указываем:

make WITH_CRAM=yo WITH_POSTGRESQL=yo

mail/squirrelmail

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

Итак, начнем с настройки СУБД PostgreSQL, как основы для построения почтовой системы. Во-первых, Postgre SQL работает с правами системного пользователя pgsql (обратите внимание, этот пользователь имеет реальный shell и домашний каталог – /usr/local/pgsql). Поэтому для начала задаем пароль для данного пользователя:

# passwd pgsql

Далее делаем su pgsql и начинаем создание базы данных:

# su pgsql

% psql

Вводим пароль пользователя pgsql и попадаем в командную строку SQL-запросов. Для подробного ознакомления с возможностями СУБД советую обратиться к руководству или же одной из книг. Создаем БД:

CREATE DATABASE users;

Присоединяемся к данной БД:

c users

Создаем таблицу пользовательских аккаунтов, а также constraint для нее:

CREATE TABLE accounts (

    uid serial NOT NULL,

    login character varying(128),

    "password" character varying(128),

    maildir character varying(255),

    gecos character varying(255),

    gid integer DEFAULT 150,

    home character varying(255),

    mailquota integer DEFAULT 20

);

ALTER TABLE ONLY accounts

    ADD CONSTRAINT uid_k PRIMARY KEY (uid);

ALTER TABLE ONLY accounts

    ADD CONSTRAINT login_k UNIQUE (login);

Создаем таблицу алиасов:

CREATE TABLE aliases (

    mail character varying(128) NOT NULL,

    alias character varying(128)

);

ALTER TABLE ONLY aliases

    ADD CONSTRAINT mail_k PRIMARY KEY (mail);

Поясню назначение таблиц и полей:

  • таблица accounts предназначена для хранения данных о виртуальных пользователях почтовой системы, назначение полей:
  • uid – уникальный номер пользователя, имеет автоинкрементный тип;
  • login – строка, содержащая имя пользователя в формате «имя@домен» для возможности доставки почты для пользователей различных доменов;
  • password – пароль в открытом виде (для возможности безопасной cram-md5 аутентификации);
  • maildir – путь к почтовому ящику в формате maildir -gecos – комментарий (для чего-нибудь да пригодится);
  • gid – идентификатор группы (не нужен реально, но зачем-то требуется для courier);
  • home – аналогично gid;
  • mailquota – число в мегабайтах, указывающее квоту для пользователя;
  • таблица aliases представляет собой просто замену /etc/aliases, содержит два поля – mail (исходный адрес) и alias (адрес для перенаправления).

После этого будем считать, что PostgreSQL у нас работает. Однако для полного использования возможностей этой СУБД лучше почитать документацию.

Далее перейдем к настройке собственно MTA exim. Конфигурационный файл для версии «из портов» хранится в /usr/local/etc/exim/configure. Для начала я бы хотел пояснить значение некоторых терминов и рассказать о базовых принципах работы exim.

Представим себе путь прохождения любого почтового сообщения. Любое письмо состоит из так называемого конверта и собственно данных. То, с чем мы привыкли работать в почтовых клиентах, как раз является «данными» и не имеет к конверту никакого отношения. В конверте описываются 2 параметра: mail from: и rcpt to:, которые указывают отправителя и получателей соответственно. Сеанс работы с MTA может предваряться «приветствием» – стандартным (HELO) и расширенным (EHLO). В приветствии должно указываться FQDN клиента, хотя по ряду причин не стоит слишком строго следить за именно FQDN, т.к. многие машины могут находиться за NAT. MTA в ответ на HELO или EHLO сообщает о своих возможностях, обеспечивая тем самым синхронизацию клиента и сервера. Далее exim осуществляет проверку целевых адресов на предмет их допустимости для данного сервера. Этот этап может предваряться аутентификацией и установкой TLS-сессии. Если пользователь прошел какой-либо из этих этапов, ему присваиваются определенные флаги, которые в дальнейшем могут использоваться на этапе проверки конверта. По умолчанию exim осуществляет проверку недопустимых символов в адресах и позволяет отправлять почту только из локальных доменов и только на локальные домены. Кроме того, при успешной аутентификации письмо проходит и в Интернет. Для остальных писем релей (передача писем) запрещена. Все проверки в exim4 осуществляются на основании механизма acl (access control list – список доступа). Также может осуществляться проверка данных (этот механизм добавляется при установке патча exiscan, который при установке портов уже ставится). После успешного прохождения этого этапа exim просматривает rewrite-правила для переписывания отдельных частей конверта (может использоваться в целях перенаправления всех писем на какой-либо смарт-хост, например). Далее письмо попадает на цепочку так называемых роутеров, которые определяют, как именно доставлять письмо. Среди роутеров фигурирует dnslookup, доставляющий письма на основании MX-записей в DNS, проверка файла алиасов и .forward-файлов, ну и локальная доставка. Каждый роутер имеет некое условие срабатывания и соответствующий транспорт. При выполнении условия exim выбирает указанный транспорт для доставки письма, иначе письмо проходит на следующий роутер (поэтому важен порядок описания роутеров в конфигурационном файле). Транспорты же определяют порядок доставки письма. Таким образом, настройка exim состоит из нескольких частей:

  • настройка глобальных параметров;
  • настройка acl’s;
  • настройка роутеров;
  • настройка транспортов;
  • настройка аутентификаторов;
  • настройка очереди;
  • настройка rewrite-правил.

В настройке exim широко используются различные списки (hostlist, domainlist и dnslist) и так называемые lookup, при помощи которых exim извлекает данные из внешних источников.

Многие мои знакомые, пытаясь освоить exim, считали lookup самой запутанной темой, потому я остановлюсь на этом вопросе чуть подробнее. Существует два типа поиска: поиск по одному ключу (single-key) и поиск по запросу (query). Первый используется для поиска в локальных файлах, а второй – в различного рода базах (sql, ldap и прочее). Любые lookup могут быть вложенными, то есть в одном поиске используются результаты другого.

Поиск на основе single key строится примерно так:

${lookup{$var_to_search}lsearch{/path/to/file}}

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

$список -> ${lookup список} -> ${lookup {$var_to_search} driver{driver_arguments}}

При этом сам файл, в котором осуществляется поиск, должен выглядеть так:

$var_to_search: значение

Приведу более конкретный пример – построение списка доменов из файла на основании адреса отправителя (пример из документации):

domainlist domains = ${lookup{$sender_host_address} lsearch{/some/file}}

при этом сам файл должен выглядеть следующим образом:

192.168.3.4: domain1 : domain2 : ...

192.168.1.9: domain3 : domain4 : ...

При этом поиск осуществляется по первому полю. Отличие query-style-поиска в том, что мы явно не обозначаем, что искать, указывая вместо этого запрос. Так выглядит типичный запрос к SQL-базе:

${lookup driver{query}{action_if_query_succeed} {action_if_query_failed}}

Например:

domainlist domains = ${lookup pgsql{select domains from domains where sender="$sender_host_address"}{$value}fail}

При успешном выполнении запроса возвращается значение из базы, иначе совершается специальное действие fail, означающее неудачный запрос.

Несколько пугающими бывают запросы к LDAP. Разберу их поподробнее. Указание сервера и порта LDAP выглядит следующим образом:

ldap_default_servers = 127.0.0.1::389

Запросы к директории выглядят так:

${lookup ldap{ldap://ldap.test.ru/dc=${domain},ou=mail, o=tehnopark?mail?sub?(&(objectClass=inetOrgPerson)

    (mail=${local_part}@${domain}))}{$value} fail}

Форма запроса описана в стандарте, но, думаю, ее стоит дополнительно пояснить. В запросе мы указываем адрес LDAP-сервера (ldap://ldap.test.ru/), basedn для поиска (dc=${domain},ou=mail,o=tehnopark), значение, которое нужно вернуть (mail), описание запроса (также в постфиксной форме, характерной для функциональных языков: (&(objectClass=inetOrgPerson)(mail=${local_part}@${domain}))).

Когда требуется аутентификация на сервере, тогда просто указываем нечто вроде:

${lookup ldap {user="cn=manager,o=tehnopark of innovation,c=RU" pass=secret

    ldap:///o=tehnopark%20of%20innovation,c=RU?sn?sub?(cn=foo)}{$value}fail}

Заметьте необходимость замены пробелов на %20, как того требует стандарт. Более подробно обо всем этом можно узнать на http://www.exim.org/exim-html-4.30/doc/html/spec_9.html#CHAP9. Думаю, для дальнейшего понимания статьи этого вполне достаточно.

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

##########################################################

#          Runtime configuration file for Exim           #

##########################################################

 

# Здесь мы определяем макросы, описывающие различные пути

CONFIG_PREFIX=/usr/local/etc/exim

ACL_PREFIX=CONFIG_PREFIX/acls

CERTDIR=CONFIG_PREFIX/certs

# Здесь мы указываем, где находить наш PostgreSQL-сервер, соединение осуществляется через локальный сокет, команда hide

# помогает спрятать эту настройку при вызове exim -bP, когда exim выводит все конфигурационные опции в стандартный вывод.

# Учтите, что сам /usr/local/etc/exim/configure должен иметь владельца root:wheel и иметь права доступа 0600, что отличается

# от того, что принято по умолчанию (0644)

hide pgsql_servers = (/tmp/.s.PGSQL.5432)/users/pgsql/pAsSwOrD

# Тут мы описываем списки доменов Local_domains включает домены, считающиеся локальными, то есть те домены, для которых exim

# делает локальную доставку, для остальных доменов почта доставляется по MX записям в DNS. Обратите внимание на дополнительные

# файлы ACL_PREFIX/localdomains и ACL_PREFIX/hostingdomains, в которых перечислены домены, разделенные переводом строки

# (то есть по одному домену на каждую строку)

domainlist local_domains = unona.test.ru : ACL_PREFIX/localdomains : ACL_PREFIX/hostingdomains

# Дополнительная настройка

domainlist hosting_domains = ACL_PREFIX/hostingdomains

# Список хостов, почту на которые мы явно отвергаем

hostlist host_reject = ACL_PREFIX/hostreject

domainlist relay_to_domains =

# Список адресов, с которых разрешена передача почты во внешний мир

hostlist   relay_from_hosts = localhost : 192.168.1.0/24 :  ACL_PREFIX/relayfromhosts

# Проверка получателя

acl_smtp_rcpt = acl_check_rcptъ

# Проверка mime содержимого

acl_smtp_mime = acl_check_mime

# Проверка на спам и вирусы

acl_smtp_data = acl_check_virus

# Здесь мы описываем наш антивирус

av_scanner = clamd:127.0.0.1 3310

# И spamassasin

spamd_address = 127.0.0.1 783

# Настройки пользователя и группы по умолчанию

exim_user = mailnull

exim_group = mail

# Никогда не осуществляем доставку под рутом - root должен быть алиасом на другого локального пользователя.

# Кстати, это обязательное условие, заданное еще на этапе компиляции

never_users = root

# Настройки директории для очереди

spool_directory = /var/spool/exim

# Разделяем spool_directory на несколько более маленьких, аналог хеш-таблицы, ускоряет обработку spool

split_spool_directory

# Пытаемся сделать соответствие прямой и обратной зоны DNS для каждого хоста. Несколько затратно, но весьма полезно

host_lookup = *

# Убираем проверку identd на клиентской стороне. Из-за неправильно настроенных firewall это часто вызывает

# длительные тайм-ауты, кроме того, этот сервис поднят не у многих

rfc1413_query_timeout = 0s

# Указываем кое-какие лимиты (их назначение ясно из названия)

smtp_accept_max = 50

smtp_connect_backlog = 40

smtp_accept_max_per_host = 10

smtp_accept_queue = 22

smtp_accept_queue_per_connection = 10

recipients_max = 16

recipients_max_reject = true

message_size_limit = 16M

accept_8bitmime

# Игнорируем сообщения, которые приходят нам же, давность которых более 12 часов

ignore_bounce_errors_after = 12h

# Удаляем замороженные сообщения, давность которых больше недели.

timeout_frozen_after = 7d

# Настройки TLS

tls_certificate = CERTDIR/mailed.crt

tls_privatekey = CERTDIR/mailed.key

tls_advertise_hosts = *

tls_verify_certificates = *

# Следующая опция закомментирована, но весьма полезна, позволяя авторизироваться только через безопасный ssl-канал

#auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}

 

##########################################################

#                   ACL CONFIGURATION                    #

#  Specifies access control lists for incoming SMTP mail #

##########################################################

 

begin acl

# Этот список доступа описывает проверки, осуществляемые при вызове любой RCPT-команды

acl_check_rcpt:

# Вначале проверяем достоверность отправителя

require verify = sender

# Принимаем соединения от локальных MUA (то есть не через TCP/IP)

 accept  hosts = :

##########################################################

# Проверка соответствия почтового адреса стандарту  

deny       message      = Restricted characters in address

           domains      = +local_domains

           local_parts  = ^[.] : ^.*[@%!/|]

accept domains   = +local_domains

# Здесь прописаны так называемые dnsbl, то есть черные списки MTA с открытым релеем, мы проверяем IP-адрес

# отправителя на соответствие таким спискам и блокируем письмо, если отправитель был найден в таком списке

deny       message      = host is listed in $dnslist_domain

           dnslists     = blackholes.mail-abuse.org: dialups.mail-abuse.org: relays.mail-abuse.org: relays.ordb.org:

                               work.drbl.caravan.ru: dul.ru:sbl.spamhaus.org

# Правило на проверку всех почтовых адресов, кроме локальных (менее строгое)

 deny      message      = Restricted characters in address

           domains      = !+local_domains

           local_parts  = ^[./|] : ^.*[@%!] : ^.*/../

##########################################################

# Принимаем почту для пользователя postmaster локальных доменов, не взирая на отправителя

accept     local_parts  = postmaster

           domains      = +local_domains

# Deny unless the sender address can be verified

accept     domains      = +local_domains

           endpass

           verify       = recipient

# Если домен в списке relay_to_domains, то разрешаем релей

accept     domains      = +relay_to_domains

           endpass

           verify       = recipient

accept     domains      = +hosting_domains

           endpass

           verify       = recipient

  accept  hosts         = +relay_from_hosts

# Принимаем любые соединения, которые были успешно авторизованы

accept     authenticated = *

# Реализация нашего бан-листа

deny       hosts        = +host_reject

           message      = You are banned. Go away.

# Запрещаем все, что не разрешено, закрывая тем самым релей для спамеров

deny       message      = relay not permitted

 

# Список доступа для проверки mime-частей сообщения

acl_check_mime:

# Произодим декодирование mime-сообщений. Полезно для дальнейшей проверки на вирусы

warn decode = default

# Можно очень быстро отсеять сообщения, просто запретив некоторые mime-вложения, чаще всего содержащие вирусы,

# хотя, конечно, это не панацея

deny       message      = Blacklisted file extension detected

           condition    = ${if match {${lc:$mime_filename}} {N(.wav|.cpl|.pif|.bat|.scr|.lnk|.com)$N} {1}{0}}

# Много ли у нас людей, знающих китайский? А вот китайского спама это поубавит

deny       message      = Sorry, noone speaks chinese here

           condition    = ${if eq{$mime_charset}{gb2312}{1}{0}}

accept

# Проверка содержимого на вирусы и спам

acl_check_virus:

# Мы не запрещаем письма со спамом, а просто добавляем заголовок, содержащий количество спамерских очков, а пользователь

# на своей стороне уже просто настраивает свои фильтры. Так мы исключаем жалобы со стороны пользователей о потерянных письмах

    warn  message = X-Spam-Score: $spam_score ($spam_bar)

           spam = nobody:true

# Добавляем заголовки, указывающие, что письма были проверены SpamAsssasin

    warn message = X-Spam-Scanned: Yes

    warn message = X-Spam-Scanner: SpamAssassin running on mail.test.ru   

# Вот что-что, а вирусы нам не нужны

        deny     message      = Message rejected: virus found. Your message was successfully trashed.

                 Hosts        = *

                 Malware      = *

    accept 

 

###########################################################

#                      ROUTERS CONFIGURATION              #

#          Specifies how addresses are handled            #

###########################################################

# THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT!#

# An address is passed to each router in turn until it is #

# accepted.                                               #

###########################################################

 

begin routers

# Роутер, осуществляющий поиск по MX-записям в DNS

dnslookup:

  driver = dnslookup

  domains = ! +local_domains

  transport = remote_smtp

  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8

  no_more

# Все останльные роутеры обслуживают доставку локальной почты. Драйвер алиасов пользователя. Обратите внимание на lookup

# в pgsql-базе. Что интересно, этот lookup работает даже для иерархических алиасов, например,

# postmaster -> root -> cebka -> cebka@jet.msk.su. Также определяются транспорты для передачи почты в файл (>/path/to/file)

# и в pipe (|/usr/local/libexec/slocal)

system_aliases:

  driver = redirect

  allow_fail

  allow_defer

  data = ${lookup pgsql{select alias from aliases where mail ="$local_part@$domain"}{$value}fail}

  user = mailnull

  group = mail

  file_transport = address_file

  pipe_transport = address_pipe

# Для локальных пользователей также создаем возможность перенаправления почты через ~/.forward-файл. Если включена директива

# allow_filter, то в .forward-файле можно использовать язык sieve-фильтров. Для подробностей см. документацию на www.exim.org,

# т.к. на рассмотрение этой темы уйдет слишком много времени

userforward:

  driver = redirect

  check_local_user

  file = $home/.forward

  no_verify

  no_expn

  check_ancestor

# allow_filter

  file_transport = address_file

  pipe_transport = address_pipe

  reply_transport = address_reply

  condition = ${if exists{$home/.forward} {yes} {no} }

# Локальная доставка, если данный пользователь найден в базе

localuser:

  driver = accept

  condition = ${lookup pgsql {select uid from accounts where login = "$local_part@$domain"}{yes}{no}}

  transport = local_delivery

  cannot_route_message = Unknown user

 

#############################################################

#               TRANSPORTS CONFIGURATION                    #

#############################################################

#                      ORDER DOES NOT MATTER                #

#Only one appropriate transport is called for each delivery.#

#############################################################

 

begin transports

# Драйвер для доставки через соединения с удаленными smtp-серверами

remote_smtp:

  driver = smtp

# Этот транспорт доставляет почту в локальные maildir. Путь к maildir хранится опять же в таблице accounts. Разрешения

# на директорию 0700 для возможности работы с данными директориями imap-сервера. При этом владельцем является

# группа и пользователь из accounts (потому при включении записей в эту таблицу надо начинать значения uid с достаточно

# большого числа, например, 2000 и пересекаться с реальными пользователями оно должно, только если реальному пользователю

# нужен локальный доступ к maildir). Также из таблицы accounts извлекаются данные о размере квоты, и устанавливается порог в 75%

# от квоты, когда пользователю посылается указанное предупреждение об подходе к порогу квоты

local_delivery:

  driver = appendfile

  directory = ${lookup pgsql{select maildir from accounts where login = "$local_part@$domain"}{$value}fail}

  create_directory

  directory_mode = 0770

  maildir_format

  delivery_date_add

  envelope_to_add

  return_path_add

  group = ${lookup pgsql{select gid from accounts where login = "$local_part@$domain"}{$value}fail}

  user = ${lookup pgsql{select uid from accounts where login = "$local_part@$domain"}{$value}fail}

  mode = 0660

  no_mode_fail_narrower

  quota = ${lookup pgsql{select mailquota from accounts where login = "$local_part@$domain"}{$value}fail}M

  quota_warn_message = "

    To: $local_part@domain

    From: postmaster@test.ru

    Subject: Your maildir is going full

    This message is automaticaly gnerated by your mail server.

    This means, that your mailbox is 75% full. If you would

    override this limit new mail would not be delivered to you! "

  quota_warn_threshold = 75%

# Транспорт, осуществляющий доставку в pipe

address_pipe:

  driver = pipe

  return_output 

# Транспорт, осуществляющий доставку прямо в файл

address_file:

  driver = appendfile

  delivery_date_add

  envelope_to_add

  return_path_add

# Этот транспорт используется для автоматического ответа на сообщения об ошибках

address_reply:

  driver = autoreply

 

##########################################################

#                      RETRY CONFIGURATION               #

##########################################################

 

begin retry

# Настройки по умолчанию, которые я не трогал, управляют интервалом повторной передачи сообщений

# This single retry rule applies to all domains and all errors. It specifies retries every 15 minutes for 2 hours, then increasing

# retry intervals, starting at 1 hour and increasing each time by a factor of 1.5, up to 16 hours, then retries every 6 hours until

# 4 days have passed since the first failed delivery.

 

# Address or Domain Error  Retries

# ----------------- -----  -------

*                    *     F,2h,15m; G,16h,1h,1.5; F,4d,6h

 

##########################################################

#                      REWRITE CONFIGURATION             #

##########################################################

 

begin rewrite

# Создаем правило по переписыванию заголовка To: с *@test.ru на локальный smart-host - @unona.test.ru. Это было сделано

# для локальных пользователей, по идее с хранением пользователей в postgres уже не нужно, показано для примера.

*@test.ru $1@unona.test.ru T

 

##########################################################

#                   AUTHENTICATION CONFIGURATION         #

##########################################################

 

# Описания аутентификации

begin authenticators

# CRAM-MD5-аутентификация, требует наличия пароля в открытом виде, имя пользователя должно быть в формате user@domain,

# как оно хранится в таблице accounts

lookup_cram:

    driver = cram_md5

    public_name = CRAM-MD5

    server_secret = ${lookup pgsql {select password from accounts where login="$1"}{$value}fail}

    server_set_id = $1

# LOGIN-аутентификация - не требует хранения пароля в открытом виде, однако, по сети пароль передается в открытом виде –

# требуется лишь выполнение условия server_condition - $1 - имя пользователя, а $2 - пароль. LOGIN безопасен только

# при установлении ssl-соединения.

login:

    driver = plaintext

    public_name = LOGIN

    server_prompts = Username:: : Password::

    server_condition = ${lookup pgsql {select login from accounts where login="$1" and password="$2"}{yes}{no}}

    server_set_id = $1


##########################################################

#                  CONFIGURATION FOR local_scan()        #

##########################################################

 

# If you have built Exim to include a local_scan() function that contains tables for private options, you can define

# those options here. Remember to uncomment the "begin" line. It is commented by default because it provokes

# an error with Exim binaries that are not built with LOCAL_SCAN_HAS_OPTIONS set in the Local/Makefile. 

# begin local_scan 

# End of Exim configuration file

Далее необходимо создать сертификат для smtp-сервера. В ходе эксплуатации выяснилось, что некоторые клиенты, например, The Bat!, требуют, чтобы в CN-сертификате (подробнее о сертификатах и способах их генерации можно прочитать в моей статье из данного журнала, располагающейся по адресу http://cebka.pp.ru/my/openssl.txt) содержалось имя (FQDN) сервера. Например, для сервера на mail.test.ru серификат должен содержать CN: mail.test.ru. Содержание остальных полей некритично. Создать сертификат можно, например, так:

# openssl genrsa -out mailed.key 2048

# openssl req -new -x509 -key mailed.key -days 365 -out mailed.crt

При этом все поля сертификата будут запрошены. Учтите, что файл секретного ключа не должен быть зашифрован, иначе exim не сможет его прочитать, просто установите владельцем этого файла root:wheel и установите права 0600. После этого можно попробовать запустить exim в режиме отладки:

exim -bd -d+all

и понаблюдать за выводимыми сообщениями. Чтобы включить exim вместо sendmail, выполняем следующие действия: в файле /etc/rc.conf нужны строки:

sendmail_enable="NONE"

exim_enable="YES"

# А также для spamassasin и clamav:

clamav_clamd_enable="YES"

spamd_enable="YES"

Затем настраиваем доставку почты для локальных приложений через exim, для чего файл /etc/mail/mailer.conf у нас должен выглядеть следующим образом:

sendmail         /usr/local/sbin/exim

send-mail        /usr/local/sbin/exim

mailq            /usr/local/sbin/exim

newaliases       /usr/local/sbin/exim

hoststat         /usr/local/sbin/exim

purgestat        /usr/local/sbin/exim

После этого перейдем к настройке ClamAV: заходим в /usr/local/etc/ и копируем clamav.conf.sample в clamav.conf и правим его таким образом, чтобы он принимал соединения через tcp/ip, а не через локальный сокет, для чего в clamav.conf нужны следующие строки:

TCPSocket 3310

TCPAddr 127.0.0.1

Далее копируем freshclam.conf.sample в freshclam.conf. Этот файл указывает настройки для программы freshclam, использующейся для обновления антивирусных баз ClamAV.

Рисунок 1

SpamAssassin работает без дополнительных настроек.

Рисунок 2

Перейдем к следующей части – настройка courier. Этот imap-сервер для своей работы использует несколько процессов, которые, в свою очередь, настраиваются из различных конфигурационных файлов. В моем примере запущено 3 процесса – authdaemon, courier-imapd и courier-imapd-ssl. Причем во внешний мир открыт только courier-imapd-ssl. Для начала создадим сертификат для imapd-ssl и для TLS-соединений с imapd: правим файл /usr/local/etc/couier-imap/imapd.cnf на предмет своего dn для сертификата, для чего в части req_dn прописываем свои настройки (не забудьте, что cn должен совпадать с FQDN imap-сервера):

[ req_dn ]

C=RU

ST=Moskow region

L=Moskow

O=Tehnopark

OU=Internet technologies

CN=test.ru

emailAddress=postmaster@test.ru

Далее генерируем сертификат специальным скриптом:

cd /usr/local/share/courier-imap/

./mkimapdcert

После чего настроим imap-аутентификацию:

cd /usr/local/etc/courier-imap/

cp authdaemonrc.dist authdaemonrc

Далее в authdaemonrc заменяем список модулей для аутентификации на:

authmodulelist="authpgsql"

Теперь courier знает, что ему нужно аутентифицироваться через pgsql. Надо только настроить сам pgsql-модуль, настройки которого хранятся в authpqsqlrc. Он должен содержать следующее:

# Соединяемся с СУБД через локальный сокет (не указан адрес)

PGSQL_PORT              5432

PGSQL_USERNAME          pgsql

PGSQL_PASSWORD          pAsSwOrD

PGSQL_DATABASE          users

# Настройки таблицы для аутентификации, здесь мы указываем, в каких полях таблицы хранятся различные пользовательские данные:

PGSQL_USER_TABLE        accounts

PGSQL_CLEAR_PWFIELD     password

DEFAULT_DOMAIN          test.ru

PGSQL_UID_FIELD         uid

PGSQL_GID_FIELD         gid

PGSQL_LOGIN_FIELD       login

PGSQL_HOME_FIELD        home

PGSQL_NAME_FIELD        gecos

PGSQL_MAILDIR_FIELD     maildir

Перейдем к настройке непосредственно imapd: скопириуем imapd.dist в imapd. Правим следующие строчки (для остальных настроек вполне подходят значения по умолчанию):

# imapd слушает только на локальном адресе, для внешних соединений мы будем использовать imapd-ssl

ADDRESS=127.0.0.1

# По умолчанию в NO, делаем в YES, чтобы imapd мог запускаться

IMAPDSTART=YES

Этих настроек в принципе хватает. Далее копируем imapd-ssl.dist в imapd-ssl и правим следующие строчки:

IMAPDSSLSTART=YES

После чего делаем запуск courier-imap при старте системы. Для этого заходим в /usr/local/etc/rc.d и снова немного попереименовываем файлы:

# mv courier-imap-imapd-ssl.sh.sample courier-imap-imapd-ssl.sh

# mv courier-imap-imapd.sh.sample courier-imap-imapd.sh

После этого считаем, что наша почтовая система практически готова. Нужно только немного понастраивать SquirrelMail, для чего заходим в /usr/local/www/squirrelmail и запускаем скрипт ./configure. В принципе интерфейс конфигурации понятен без лишних пояснений, потому я не буду особо останавливаться на этой проблеме (не забудьте, главное, указать imap- и smtp-сервера). Делаем симлинк на /usr/local/www/squirrelmail из какого-либо VirtualHost или из-под непосредственно DocumentRoot самого apache. Вот в принципе, и все.

Рисунок 3

Есть некоторые особенности запуска SquirrelMail при включенном safe_mode в php. Во-первых, все php-файлы и каталоги SquirrelMail должны принадлежать тому пользователю, из-под которого работает apache (настройка VirtualHost или глобальная, по умолчанию – www:nogroup). Кроме того, необходимо сменить разрешения в /var/spool/squirrelmail:

# chmod 1777 /var/spool/squirrelmail/attach

# chmod 1777 /var/spool/squirrelmail/pref

Ну и владельца установить того же, что и на /usr/local/www/squirrelmail.

Комментарии вы можете присылать на cebka@jet.msk.su.

Cписок полезных ссылок:

  1. http://www.exim.org – сайт MTA exim, очень хорошая и подробная документация;
  2. ftp://ftp.exim.org/pub/exim/config.samples.tar.bz2 – примеры разнообразных конфигурационных параметров, полезно для ознакомления;
  3. http://duncanthrax.net/exiscan-acl – патч exiscan с сопутствующей документацией;
  4. http://www.clamav.net – сайт свободного антивируса ClamAV;
  5. http://www.spamassasin.org – официальный сайт SpamAssasin;
  6. http://www.courier-mta.org – ресурс courier продуктов, в том числе и courier-imap;
  7. http://www.squirrelmail.orgсайт web-mail-системы SquirrelMail;
  8. http://www.nixp.ru/cgi-bin/go.pl?q=articles;a=mta-home – exim+mutt+bmx – для домашней почтовой системы (хорошая и интересная статья);
  9. http://tomster.org/geek/freebsdcookbook – альтернативный вариант реализации почтовой системы, где вместо courier используется cyrus imapd;
  10. http://cebka.pp.ru/samag/clamstat.tar.bz2 – скрипт статистики ClamAV;
  11. http://cebka.pp.ru/samag/uidchk.pl – скрипт проверки пересечения uid из БД и системных.

Комментарии отсутствуют

Добавить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

               Copyright © Системный администратор

Яндекс.Метрика
Tel.: (499) 277-12-45
E-mail: sa@samag.ru