Документация по ОС FreeBSD Среда, 08.05.2024, 08:05
Приветствую Вас Гость | RSS
Меню сайта

Категории каталога
Apache [58]
DNS [25]
FTP [27]
Mail [74]
Samba [24]
Squid [46]
SSH [23]
VPN [35]
РРР [20]
Net [173]

Главная » Статьи » Сеть » Mail

Настройка exim (relay) и M$ exchange (почтарь внутри локалки) Часть 1 [2008]
Предистория. Делалось по заказу одного товарисча, с далёкого Сахалина. Ему нужен был, фактически, просто почтовый релей внутрь локалки, где стоял M$ Exchange. Однако, просто релей с перезаписью адресов - неинтересно. Поэтому, за основу был взят мой текущий конфиг exim+dovecot и допилен под текущие нужды. В частности, ввиду того, что внутри локалки используется адресация user@domain.local, была настроена перезапись адресов, с учётом, что внешних доменов у организации два - один с коротким именем, другой — с длинным (short-dom.ru и long-domain.ru). Отсюда - излишняя, пожалуй, сложность для просто релея.
   Разумная критика приветствуется, однако, бред не по теме будет удалён :)

   Итак. Исходные данные задачи. Два сервера на FreeBSD6.2, на каждом по два интерфейса - один наружу, другой внутрь. Два - потому, что нужна надёжность. Настройки будут разниться тока в части имён и IP, которые по возможности вынесены в макроопределения в начале конфига. Для проверки существоваания пользователей в домене (цель - генерить отлупы до приёма сообщения, на уровне "rcpt to:" - иначе, они могут пойти по фальшивому обратному адресу), exim будет лазить напрямую в виндовый ldap - для этого заведён специальный пользователь в домене, без права логинитсья.
   Для удобства, конфиг почтаря был разбит на несколько кусков, т.к. с одним очень большим стало нереально тяжело работать (особенно на Сахалине, с лагом в две секунды на каждое действие). Была реализована схема с т.н. "белыми списками", подсказанная ded3axap`ом. Реализация, правда не его, моя собственная. Также, с сайта http://www.iana.org/ был утянут список всех доменов верхнего уровня - он используется в проверках HELO - существует ли такой домен (проверка регулярным выражением на синтаксис - всё же не так эффективна).
   Итак. Обновляем порты, ставим exim. Для выставления всех опций один раз, и чтоб в дальнейшем не мучаться - как же я его собирал, выставляем нужные опции в /etc/make.conf, у меня он получился такой:
# default MySQL version
DEFAULT_MYSQL_VER=50
# default PHP version
DEFAULT_PHP_VER=4

PORTSDIR?= /usr/ports
.if ${.CURDIR} == ${PORTSDIR}/mail/exim
# Поддержка MySQL
WITH_MYSQL= yes
LOG_FILE_PATH?= syslog
# Контентное сканирование
WITH_CONTENT_SCAN= yes
# Дефолтовая кодировка заголовков
WITH_DEFAULT_CHARSET?= koi8-r
# Отключаем IPv6
WITHOUT_IPV6= yes
# Подрубаем LDAP
WITH_OPENLDAP= yes
# Версия BDB - в чём ведёт свои БД подсказок
WITH_BDB_VER= 1
# Проверки SPF
WITH_SPF= yes
# Подержка перекодировки (для заголовков)
WITH_ICONV= yes
.endif

# for perl5.8
.if ${.CURDIR} == ${PORTSDIR}/lang/perl5.8
WITH_THREADS=yes
.endif

# MySQL server
.if ${.CURDIR} == ${PORTSDIR}/databases/mysql50-server
BUILD_OPTIMIZED=yes
BUILD_STATIC=yes
WITH_CHARSET=cp1251
WITH_COLLATION=cp1251_bin
#WITH_LINUXTHREADS=yes
WITH_PROC_SCOPE_PTH=yes
.endif

# MySQL client
.if ${.CURDIR} == ${PORTSDIR}/databases/mysql50-client
BUILD_OPTIMIZED=yes
BUILD_STATIC=yes
WITH_CHARSET=cp1251
WITH_COLLATION=cp1251_bin
.endif

# vim
.if ${.CURDIR} == ${PORTSDIR}/editors/vim
WITHOUT_X11= yes
.endif
   Соответственно - вовсе не обязательно вносить все пункты, но я решил быть дословным :). После чего, можно ставить exim:

mail$ cd /usr/ports/mail/exim
mail$ make install clean

   И сервер MySQL (exim притащит, как зависимость, лишь клиента) - если он будет стоять на этой машине:

mail$ cd /usr/ports/databases/mysql50-server/
mail$ make install clean

   Собственно - насчёт муси - насколько обязательна версия 5.0 - утверждать не берусь, ибо лень лезть в документацию, но, что в 4.0 отстутствуют функции используемые в конфигурации - это абсолютно точно. Также, не забываем поставить антивирус, я ставил с опциями по-умолчанию:

mail$cd /usr/ports/security/clamav
mail$ make install clean

   Далее - рисуем конфиги. По ним комментариев немного, они и сами неплохо прокоментированы (заодно оставил все старые ошмётки, от процесса их создания - может кому-то пригодятся). Прошу тока обратить внимание на имена файлов, был уже прикол, когда боролись с глюками у одного товарисча, а оказалось что не инклюдятся файлы - и, фактически, он работал на пустом конфиге :).
/usr/local/etc/exim/configure:

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

# Инклюдим главные настройки
.include_if_exists /usr/local/etc/exim/includes/100.main.conf

### конфигурация ACL для входящей почты
begin acl
# Эти правила срабатывают для каждого получателя
acl_check_rcpt:

# Начало файла ACL - те, кого срубаем сразу же
.include_if_exists /usr/local/etc/exim/includes/200.acl_check_rcpt.conf
# Проверки на спам - по хостам и прочему.
.include_if_exists /usr/local/etc/exim/includes/300.acl_check_rcpt_spam_rule.conf
# Конец конфигурации - блэк-листы, задержки и прочее
.include_if_exists /usr/local/etc/exim/includes/400.acl_check_rcpt_end.conf

# Тут идут ACL проверяющие содержимое (тело) письма.
# Без них будут пропускаться все сообщения.
acl_check_data:
# Инклюдим конфигурацию проверки тела письма
.include_if_exists /usr/local/etc/exim/includes/500.acl_check_data.conf

# чё делаем с почтой
begin routers
# Инклюдим конфигурацию роутреров
.include_if_exists /usr/local/etc/exim/includes/600.routers.conf

# начинаются транспорты - как доставляем почту
begin transports
# Инклюдим транспорты
.include_if_exists /usr/local/etc/exim/includes/700.transports.conf

# Конфигурация повторов и перезаписи
.include_if_exists /usr/local/etc/exim/includes/800.retry_and_rewrite.conf

# Секция авторизации при отправке писем. Ввиду того,
# что почтовых клиентов много, и все всё делают
# по-своему, то и механизмов авторизации три...
begin authenticators
# Аутентификация юзеров.
.include_if_exists /usr/local/etc/exim/includes/900.authenticators.conf

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

/usr/local/etc/exim/includes/100.main.conf:

# Главняе настройки

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

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

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

# Эксчейнджевый домен
MS_EXCHANGE_DOMAIN = long-domain.local

# внутренний IP машины
INTERNAL_IP = 192.168.205.253

# внимание - изменённ дефолтовый разделитель списка!
ldap_default_servers = <; 192.168.205.2:3268 
#; dc2.domain.org:3268

# макросы для работы с LDAP
LDAP_AD_BINDDN = exim
LDAP_AD_PASS = pass_user_exim_in_domain
LDAP_AD_BASE_DN = DC=long-domain,DC=local

# макрос для проверки пользователей в домене
LDAP_AD_MAIL_RCPT = \
user=LDAP_AD_BINDDN \
pass=LDAP_AD_PASS \
ldap:///LDAP_AD_BASE_DN?mail?sub?\
(&(|(objectClass=user)(objectClass=publicFolder)(objectClass=group))\
(|(proxyAddresses=${quote_ldap:${local_part}@MS_EXCHANGE_DOMAIN})\
(proxyAddresses=smtp:${quote_ldap:${local_part}@MS_EXCHANGE_DOMAIN}))\
(!(userAccountControl:1.2.840.113556.1.4.803:=2)))

# Делаем список локальных доменов. Далее этот
# список будет фигурировать в виде +local_domains
# В данном случае домены выбираются из БД MySQL. Также
# можно их просто перечислить через двоеточие. Есть интересная
# возможность, можно указать юзер@[хост] - lissyara@[222.222.4.5]
domainlist local_domains = mail.short-dom.ru : relay.long-domain.ru

# делаем список доменов с которых разрешены релеи.
# Далее этот список будет в виде +relay_to_domains
# Можно использовать символы подстановки, типа:
# .... = *.my.domen.su : !spam.my.domen.su : first.su
# тогда пропускается всё, что похоже на *.my.domen.su, но
# от spam.my.domen.su релеится почта не будет.
domainlist relay_to_domains = long-domain.ru : short-dom.ru

# Составляем список хостов с которых разрешён неавторизованый
# релей. Обычно в нём находятся локальные сети, и локалхост...
# ЛокалХост в двух видах был внесён сознательно - пару раз
# сталкивался с кривым файлом /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

# Прикручиваем антивирус - при условии, что exim собран
# с его поддержкой. В качестве антивиря юзаем ClamAV,
# ибо - ПО должно быть свободным! :)
# Итак, указываем местоположение сокета clamd.
av_scanner = clamd:/var/run/clamav/clamd

# Адрес куда слать на проверку спама (SpamAssasin), но я
# это не юзаю. Не так много у меня спама...
# spamd_address = 127.0.0.1 783

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

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

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

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

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

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

# Проверяем соответствие прямой и обратной зон для всех хостов.
# Тока зачем это нужно - даже и незнаю... Спам на этом не режется...
# Зато возможны проблемы - если сервер зоны скажет `сервер файлед`
# то почту от этого хоста Вы не получите :)
#host_lookup = *

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

# По дефолту, экзим отфутболивает все `неквалифицированные` адреса,
# состоящие тока из локальной части. Для того чтобы разрешить такие письма
# определённых хостов используются эти директивы:
# для `неквалифицированных` отправителей
sender_unqualified_hosts = +relay_from_hosts
# для `неквалифицированных` получателей
recipient_unqualified_hosts = +relay_from_hosts

# Интересный пункт, тока я не вполне понимаю его логику.
# Позволяет выполнять что-то типа - пришло сообщение на
# локальный ящик user%test.su@lissyara.su и
# переправляет его на user@test.su. Делается это для
# перечисленного списка доменов (* - все):
# percent_hack_domains = *

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

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

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

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

# Список хостов, почта от которых принимается, несмотря
# на ошибки в 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 = 64M

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

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

# Выбираем, что мы будем логировать
# + - писать в логи,
# - - Не писать в логи.
# +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 \
# -incoming_port \
# -incoming_interface \
 -arguments \
 -smtp_connection \
 -lost_incoming_connection \
 -queue_run

# Системный фильтр, копирование проходящей почты
system_filter = /usr/local/etc/exim/filters/system-filter
system_filter_pipe_transport = address_pipe
system_filter_user = mailnull
system_filter_group = mail

# Убираем собственную временную метку exim`a из логов, её ставит
# сам syslogd - нефига дублировать
syslog_timestamp = no
log_file_path = syslog : /var/log/exim/%s-%D.log

/usr/local/etc/exim/includes/200.acl_check_rcpt.conf:

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

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

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

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

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

#  accept  local_parts   = postmaster
#          domains       = +local_domains

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

  # Запрещщаем тех, кто не обменивается приветственными
  # сообщениями (HELO/EHLO)
deny message = "HELO/EHLO require by SMTP RFC"
condition = ${if eq{$sender_helo_name}{}{yes}{no}}
delay = 30s

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

# Рубаем нах, тех, кто подставляет свой IP в HELO
deny message = We don't allow domain literals, many spam...
hosts = !+relay_from_hosts:*
condition = ${if isip{$sender_helo_name}{yes}{no}}
delay = 30s

# Рубаем хело с нашим именем
deny condition = ${if match_domain{$sender_helo_name} \
{$primary_hostname:+local_domains:+relay_to_domains} \
{true}{false}}
message = Message was delivered by ratware - own
log_message = remote host used our name in HELO/EHLO.
delay = 30s

# Рубаем мудаков с недопустимыми символами в helo (пока видел тока такие)
  deny    condition     = ${if match{$sender_helo_name}{\N_\N}{yes}{no}}
          hosts         = !127.0.0.1 : !localhost : !+relay_from_hosts : *
          set acl_m0    = ${eval:$acl_m0+20}

# Ограничения эксчейнджа - юзер не может начинаться/заканчиваться точкой.
  deny          message =       Invalid address
                senders =       \N^\.|\.@\N

 


Источник: http://www.lissyara.su/?id=1453
Категория: Mail | Добавил: oleg (02.07.2008) | Автор: lissyara
Просмотров: 2356 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Beastie

Друзья сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
links

Copyright MyCorp © 2024