ZImbra: нетривиальная маршрутизация почты - часть 1

LDAP
Zimbra — замечательный Collaboration Suite, но с точки зрения тонкой настройки собственно почтового сервиса MTA (в качестве которого, как мы все знаем, используется Postfix) её веб-интерфейс сильно хромает, а местами так и просто обескураживает.
Например, есть у меня Zimbra на внутреннем почтовике, она полностью закрыта от внешнего доступа и всю исходящую корреспонденцию шлёт внешнему серверу-шлюзу, от него же и принимает оную. Плюс настроен Split-Domain (как именно — см. Split Domain: Configuring Zimbra as the Secondary System), потому что пока на внешнем шлюзе есть нехилый кусок нашего корпоративного домена. Ну да это не суть важно, а важно то, что в моём случае Zimbra по дефолту не может отправлять любую почту, кроме адресованной локальным получателям, куда-либо, кроме того самого внешнего шлюза.
И всё было бы хорошо, если бы в дополнение к собственному домену Zimbra, назовём его domain.com, не появился ещё один внутренний домен с именем lists.domain.com, хостящийся буквально по соседству (VLAN/подсетка совпадают, так что не требуется дополнительная маршрутизация). И вот тут дефолтная конфигурация уже перестала меня устраивать: ведь в этот «соседний» домен тоже нужно каким-то образом отправлять почту, но если оставить всё как есть, то получится абсурдная ситуация: сначала Zimbra будет отправлять сообщение в lists.domain.com через интернет-шлюз на почтовый шлюз, а затем последний уже отправит это письмо обратно через интернет-шлюз… почти туда же, откуда оно и ушло. Таким образом, мы получили бы маршрутизацию почты в lists.domain.com аля «путешествие Афанасия Никитина за три моря» и массу потенциального геморроя.
Решил я тогда посмотреть, а как же в подобных случаях Zimbra предлагает своими собственными средствами настраивать маршрутизацию? Оказалось, что либо весьма кривым способом, либо вообще никак. Единственный доступный метод предполагает, что я должен завести в Zimbra фиктивный «локальный» домен, который на самом деле находится на другом сервере, и правилами CatchAll (аж три штуки!) настроить перенаправление всей почты, адресованной данному домену, по транспорту smtp. Меня такой метод, разумеется, не устроил в виду своей кривизны, ведущей к появлению в списке доменов чего-то совершенно постороннего, что к данному серверу вообще не относится.
Желание сделать всё несколько менее тяжеловесным и более предсказуемым образом, подтолкнуло меня к изучению конфигурации Postfix в составе Zimbra на предмет того, как же там организованы transport_maps. Поначалу так даже была шальная мысль добавить свой собственный файл транспортов, но после изучения файла /opt/zimbra/conf/ldap-transport.cf выяснилось, что менять конфигурацию Postfix и рисковать перезаписью оной при первом же обновлении совершенно ни к чему.
Собственно вот каким образом осуществляется поиск транспорта в ZCS 6.0.10:

query_filter = (&(|(zimbraMailDeliveryAddress=%s)(zimbraDomainName=%s))(zimbraMailStatus=enabled))
result_attribute = zimbraMailTransport

Да, я понимаю, что это нужно бы расшифровать :) Всё очень просто: в каталоге ищется запись, отвечающая следующему условию:
значение атрибута zimbraMailDeliveryAddress или атрибута zimbraDomainName должно быть равно «левой части» транспорта (в данном случае тому самому внутреннему домену), плюс обязательно атрибуту zimbraMailStatus должно быть присвоено значение enabled.
Правая же часть (то есть собственно, описание транспорта) должна находиться в атрибуте zimbraMailTransport той же записи.
Иными словами, если в обычном файле transport_maps для Postfix мы записали бы строчку:
lists.domain.com  smtp:[host.domain.com]:25
То в LDAP-каталоге для достижения аналогичного эффекта нам нужно, чтобы у какого-либо объекта присутствовали атрибуты: zimbraMailDeliveryAddress=lists.domain.com и zimbraMailTransport=smtp:[host.domain.com]:25
Сказано — сделано. После недолгого изучения схемы LDAP-каталога выяснилось, что атрибуты zimbraMailDeliveryAddress и zimbraMailStatus есть в одном из базовых (являющихся родительским для многих других классов Zimbra) objectClass с именем zimbraMailRecipient. Этот класс объявлен как AUXILIARY, так что его можно свободно добавлять к любой уже существующей записи. В моём случае DNS внутренней зоны также хранится в LDAP, поэтому запись того самого целевого домена lists.domain.com, разумеется, уже была. Зная же, что такое по сути transport_maps и как это работает, мне совсем не трудно было модифицировать запись каталога нужным образом:
dn: dc=lists,dc=domain,dc=com
changeType: modify
add: objectClass
objectClass: zimbraMailRecipient
-
add: zimbraMailDeliveryAddress
zimbraMailDeliveryAddress: lists.extel.ru
-
add: zimbraMailTransport
zimbraMailTransport: smtp:[host.domain.com]:25
-
add: zimbraMailStatus
zimbraMailStatus: enabled

Здесь, как вы уже, наверное, догадались, smtp:[host.domain.com]:25 — это описание транспорта для отправки в домен lists.domain.com, а host.domain.com — это целевое имя сервера.
В результате же запись для данного домена стала выглядеть следующим образом:


dn: dc=lists,dc=domain,dc=com
objectClass: dNSDomain2
objectClass: domainRelatedObject
objectClass: zimbraMailRecipient
associatedDomain: lists.domain.com
sOARecord: ldap.domain.com. noc.domain.com. 2011010600 3600 900 36000 3600
nSRecord: ldap.domain.com
dc: lists
mXRecord: 10 host.domain.com
aRecord: 192.168.3.71
zimbraMailTransport: smtp:[host.domain.com]:25
zimbraMailStatus: enabled
zimbraMailDeliveryAddress: lists.domain.com

Ну и коль скоро есть MX-запись, можно транспорт указать ещё следующим образом: smtp:lists.domain.com:25 — тогда Zimbra сама определит по MX'у, куда ей слать почту.

Вуаля! Всё работает, почта в домен ходит напрямую в пределах одной сети — несмотря на коварные происки врагов, по умолчанию пытающихся всё без разбору перебрасывать на внешний почтовый шлюз :)

В следующей части я расскажу вам, как не изменяя конфигурацию Zimbra создавать почтовые алиасы, указывающие на «чужие» для Zimbra домены (да-да-да, ldapmodify и в этом случае просто назаменим :) ).

ZImbra: нетривиальная маршрутизация почты — часть 2

0 комментариев

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