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

LDAP
Первая часть тут

Положим, поставила перед вами нелёгкая судьбина следующую задачу: добавить в Zimbr'у alias, он же псевдоним. Но псевдоним тот не простой, а виртуальный, указывающий не на пользователя в локальном домене, обслуживаемом Zimbra, а на некий «внешний» почтовый адрес.
Как законопослушный гражданин, вы наверняка первым делом загрузите интерфейс администрирования Zimbra и в меню Создать выберете «Псевдоним». После совершения указанной манипуляции пред ваши очи предстанет такое вот окно:

В этом окне вы, возможно, захотите заполнить поле «Псевдоним», указав почтовый адрес локального пользователя (как удобно, домен даже не нужно вводить, можно просто выбрать из списка!), а в поле «Целевая учётная запись» впишете нашего внешнего получателя.
И вот тут-то вас подкараулит из-за угла жесточайший облом: дело в том, что формулировка «Целевая учётная запись» абсолютно точна и здесь принцип «не верь глазам своим», безотказный в случае с наспех сделанными интерфейсами и корявыми переводами, совершенно не действует: Zimbra переведена на русский правильно и точно, так что… таки да, вам придётся указать именно учётную запись и ничто иное :) Хорошо, а если поменять местами: пусть «Псевдонимом» будет внешний почтовый адрес, а «Целевой учётной записью» — некий наперёд созданный локальный пользователь (будем считать, что таковой уже есть). В этот момент (или же чуть раньше ;) ) и выясняется весьма неприятный факт: удобное «автодополнение» домена настолько удобно, что даже абсолютно безальтернативно, ведь это отнюдь не поле ввода текста, каким оно кажется, а простой выпадающий список!
Вы уже задумались над сакраментальным вопросом о том, почему в Zimbra всё так печально даже с простейшими механизмами маршрутизации почты? Может быть, это какие-то ограничения и глюки веб-интерфейса на AJAX, может быть, утилитами командной строки всё делается элементарно?
С целью выяснить данный момент я конечно же первым делом обратился к первоисточнику — каковым для Zimbra является LDAP-каталог (слава Богу, хотя бы здесь это не какая-нибудь уродливая базёнка на MySQL с невнятной схемой и кучей ненужных полей).
Итак, создайте псевдоним, положим, vpupkin@domain.com, который ссылается на учётную запись pupkin-vi@domain.com и посмотрите, как это выглядит в LDAP: доберитесь до ветки ou=people,dc=domain,dc=com и откройте объект uid=vpupkin. Вот он:
dn: uid=vpupkin,ou=people,dc=domain,dc=com
zimbraId: c120b7a2-1c3f-48d7-8cd6-baeafdc09b2f
uid: vpupkin
zimbraAliasTargetId: e393c4a0-8f73-4d28-a9d1-0905394d16b7
zimbraCreateTimestamp: 20110110075113Z
objectClass: zimbraAlias

«Ба, да где же, собственно, доменная часть?», — спросите вы. Так её и нету там, потому что алиас в понимании Zimbra — это лишь то, что вы можете видеть в файле aliases обычного sendmail-совместимого почтовика, а не то, о чём вы могли подумать, будучи знакомым с несколько более совершенными методиками марщрутизации почты. Алиас в понимании Zimbra — это не более, чем второе имя для уже заведённого пользователя, настолько прочно с ним ассоциированное, что вы даже можете авторизоваться на сервере по имени алиаса, но с паролем целевой учётной записи.
Хорошо, теперь мы убедились в том, что Псевдоним — это не совсем то, что нам нужно. Но, я думаю, вы обратили внимание на то, что при создании обычной учётной записи пользователя (а также при изменении оной) можно указать адрес пересылки для его почты? Превосходно, давайте же создадим новый аккаунт, пусть это будет test@domain.com, и укажем ему адрес пересылки test@lists.domain.com (вы угадали, это тот самый домен, ради которого мы затевали весь сыр-бор в первой части статьи :))
Вот как это будет выглядеть в момент создания аккаунта:

Не забудьте только поставить галочку рядом с опцией «не хранить локальные копии сообщений» — это важно, потому что иначе Zimbra начнёт складывать в свою базу данных то, что вообще совсем не ей предназначалось. Нажмите «Готово» — и вуаля, теперь вся почта, адресованная данной учётной записи, будет пересылаться без сохранения.
Что же мы в итоге имеем? С точки зрения механизма работы почты мы получили именно то, что и хотели: пересылку корреспонденции, адресованной локальному получателю, на внешний адрес.
И на этом вы можете с чистой совестью завершить чтение статьи, пойти сварить кофе или пригубить апперитив (очень полезен бывает в особенности на сон грядущий), победным образом завершив свои мытарства: всё работает как задумано и даже форвардер этот свежесозданный вы можете легко отредактировать из веб-интерфейса, например, добавив дополнительные адреса пересылки.
Но если вы такой же пытливый и дотошный человек, как я, то нет-нет, да и промелькнёт у вас в голове шальная мысль: а то ли по сути мы сейчас получили, что на самом деле хотели или же это Zimbra некоторым образом «заставляет» нас захотеть то, что мы получили? Ведь вот эта штука с кое-как привинченным к ней императивом пересылки «на деревню дедушке» — разве не избыточна для простой перезаписи адреса получателя и отправки письма дальше по инстанциям? И вообще разве для этого была задумана опция пересылки в настройках учётной записи?
Смотрите, как выглядит созданный с помощью веб-интерфейса Zimbra объект в LDAP-каталоге:
dn: uid=test,ou=people,dc=domain,dc=com
zimbraMailTransport: lmtp:mx-host.domain.com:7025
zimbraAccountStatus: active
zimbraMailDeliveryAddress: test@domain.com
zimbraPrefMailForwardingAddress: test@lists.domain.com
zimbraPrefMailLocalDeliveryDisabled: TRUE
sn: test
zimbraMailStatus: enabled
zimbraId: 0eaa69bf-d988-4c05-89c5-d1fc7f85ea62
zimbraCreateTimestamp: 20110110113052Z
mail: test@domain.com
displayName: test
uid: test
objectClass: organizationalPerson
objectClass: zimbraAccount
objectClass: amavisAccount
cn: test
zimbraMailHost: mx-host.domain.com

Да… Представляете, и ведь из всего этого нагромождения атрибутов вам нужно-то, не считая собственно uid'а (который неплохо смотрится в rdn :)), всего два: zimbraMailDeliveryAddress и zimbraPrefMailForwardingAddress. Но ради них пришлось городить полноценный Zimbra-аккаунт со всеми вытекающими отсюда последствиями, самым неприятным из которых является то, что если записи пользователей Zimbra нужны ещё какими-либо приложениям, то вам ведь придётся каким-то образом дать им понять, что вот этот объект LDAP — он и не пользователь вовсе, он всего лишь лишь фикция!
Выход же из данной ситуации достаточно тривиален: как и в прошлый раз, нам придётся использовать возможности самого Postfix'а напрямую. А это в данном случае замечательный механизм virtual_alias_maps.
Что ж, вот и они, карты виртуальных псевдонимов, описаны в файле /opt/zimbra/conf/ldap-vam.cf:
search_base =
query_filter = (&(|(zimbraMailDeliveryAddress=%s)(zimbraMailAlias=%s)(zimbraMailCatchAllAddress=%s))(zimbraMailStatus=enabled))
result_attribute = zimbraMailDeliveryAddress,zimbraMailForwardingAddress,zimbraPrefMailForwardingAddress,zimbraMailCatchAllForwardingAddress

Фильтр, безусловно, выглядит несколько странным, а тот факт, что множество искомых атрибутов пересекается с множеством возвращаемых (тех, что в result_attribute) — впечатляет ещё больше. Но… как говорится, понятнее LDAP может быть только x.500 (шутка), так что после недолгих ковыряний в схеме я нашёл нужное сочетание для создания подходящей записи в Каталоге. Оказывается, как и в случае, описанном в первой части статьи, здесь можно использовать всё тот же базовый объектный класс zimbraMailRecipient.
Для поиска в LDAP соответствия нашему локальному адресу test@domain.com будет использован атрибут zimbraMailAlias=test@domain.com, а в качестве результата преобразования будет возвращаться атрибут zimbraMailDeliveryAddress=test@lists.domain.com.
В итоге полная запись для виртуального алиаса примет следующий вид:
dn: uid=test,dc=lists,dc=domain,dc=com
objectClass: account
objectClass: zimbraMailRecipient
uid: test
zimbraMailAlias: test@domain.com
zimbraMailDeliveryAddress: test@lists.domain.com
zimbraMailStatus: enabled

А вот теперь сравните это с листингом для полноценной учётной записи «пользователя» с перенаправлением и оцените, насколько всё-таки просто решается задача, если абстрагироваться от привносимой Zimbra специфики в виде искусственной терминологии и сильно ограниченных методов работы с маршрутизацией почты. Заметьте особо, что благодаря «пустому» search_base, то есть указывающему в самый «корень» LDAP-каталога, вы можете размещать свои записи маршрутизации (любые, а не только virtual_alias_maps) там, где это удобно и логично делать, а не там, где посчитает нужным создать их сама Zimbra (если она это вообще сумеет сделать адекватным образом!).

Итак, перед вами теперь целых два решения проблемы:
1) не требующее дополнительных знаний простое, но весьма «топорное», использующее «хак» в виде галочки «Не сохранять локальные копии» в настройках фиктивного аккаунта, который постоянно будет вам потом мешаться и вылезать там, где вы его совсем не ждёте;
2) несколько более сложное, но элегантное решение с ручным (имеется в виду конечно ваш любимый LDAP-браузер) созданием нужной записи в Каталоге.
Последний вариант, разумеется, предполагает понимание вами как минимум LDAP basics и наличия небольшого опыта работы с Postfix, но в общем если вы всерьёз собираетесь использовать Zimbra для решения широкого круга задач, разобраться в её «фундаменте» всё равно придётся.

Выбор, как обычно, за вами! За сим позвольте ненадолго попрощаться с вами, мои дорогие радиослушатели :)
До новых встреч в прямом эфире на волне свободы и неограниченных возможностей!

1 комментарий

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