Exim, группы рассылки в AD

EXIM, sendmail, postfix, Dovecot и прочие. Решение проблем связанных с работой электронной почты

Модератор: xM

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
blade_007
ст. прапорщик
Сообщения: 571
Зарегистрирован: 2010-03-12 12:59:08
Контактная информация:

Exim, группы рассылки в AD

Непрочитанное сообщение blade_007 » 2010-05-26 14:14:33

Добрый день.
Возник вопрос на тему группы рассылки в AD.
На данном форму было найдено рабочее решение одного товарища.
Данный роутер ищет в AD группу рассылки (grouptype=2) и если в поле Эл. адрес значение совпадает с текущим обрабатываемым адресом, то составляется список из почтовых адресов, передаваемых роутеру ldapuser.

В данный роутер на мой взгляд необходимо добавить следующий функционал, а именно условие по которому на адреса данной группы могут писать ТОЛЬКО пользователи определенных подсетей (свои подсети, подсети партнеров и т.п.) ИЛИ если в описании группы AD есть какое-то ключевое слово (например, public)

Собственно роутер, найденный на форуме

Код: Выделить всё

adsi_group_check:
        driver = redirect
        domains = +local_domains
        allow_defer
        data = ${sg{${map {<\n \
           ${sg{${lookup ldapm { \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///LDAP_AD_BASE?member?sub?\
              (&\
                  (objectClass=group)\
                  (grouptype=2)\
                  (mail=${quote_ldap:${local_part}@${domain}})\
              )\
           }}}{\N, \N}{\n}}} \
           {${lookup ldap{ \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///${quote_ldapdn:$item}?mail?base?}} \
           }}}{\N\n\N}{, } \
            }
        redirect_router = ldapuser
Собственно, условие, логика которого вышеописана.

Код: Выделить всё

        condition = ${if or{ \
            {match_ip{$sender_host_address}{iplsearch;/etc/exim/allow_auth_hosts}}\
            {eq {public}{lookup ldap{ \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///LDAP_AD_BASE?description?sub?\
              (&\
                  (objectClass=group)\
                  (grouptype=2)\
                  (mail=${quote_ldap:${local_part}@${domain}})\
              )\
           }}}\
            }\
        }
Дебаг.

Код: Выделить всё

13:49:13 10660 dnslookup router skipped: domains mismatch
13:49:13 10660 --------> adsi_group_check router <--------
13:49:13 10660 local_part=testgroup domain=******
13:49:13 10660 checking domains
13:49:13 10660 cached yes match for +local_domains
13:49:13 10660 cached lookup data = NULL
13:49:13 10660 ****** in "+local_domains"? yes (matched "+local_domains" - cached)
13:49:13 10660 checking "condition"
13:49:13 10660 expanding: $sender_host_address
13:49:13 10660    result: 10.1.16.119
13:49:13 10660 expanding: iplsearch;/etc/exim/allow_auth_hosts
13:49:13 10660    result: iplsearch;/etc/exim/allow_auth_hosts
13:49:13 10660 search_open: iplsearch "/etc/exim/allow_auth_hosts"
13:49:13 10660   cached open
13:49:13 10660 search_find: file="/etc/exim/allow_auth_hosts"
13:49:13 10660   key="10.1.16.119" partial=-1 affix=NULL starflags=0
13:49:13 10660 LRU list:
13:49:13 10660   5/etc/exim/allow_auth_hosts
13:49:13 10660   End
13:49:13 10660 internal_search_find: file="/etc/exim/allow_auth_hosts"
13:49:13 10660   type=iplsearch key="10.1.16.119"
13:49:13 10660 cached data used for lookup of 10.1.16.119
13:49:13 10660   in /etc/exim/allow_auth_hosts
13:49:13 10660 lookup failed
13:49:13 10660 10.1.16.119 in "iplsearch;/etc/exim/allow_auth_hosts"? no (end of list)
13:49:13 10660 expanding: public
13:49:13 10660    result: public
13:49:13 10660 expanding: CN=exim,CN=Users,DC=********=com
13:49:13 10660    result: CN=exim,CN=Users,DC=******,DC=com
13:49:13 10660 expanding: ${local_part}@${domain}
13:49:13 10660    result: testgroup@********
13:49:13 10660 expanding: lookup ldap{ user=${quote_ldap:CN=exim,CN=Users,DC=*****DC=com} pass=*** ldap:///DC=*****,DC=com?description?sub?(&(objectClass=group)(grouptype=2)(mail=${quote_ldap:${local_part}@${domain}}))
13:49:13 10660    result: lookup ldap{ user=CN%3Dexim%2CCN%3DUsers%2CDC******2CDC%3Dcom pass=*** ldap:///DC=*****DC=com?description?sub?(&(objectClass=group)(grouptype=2)(mail=testgroup%40*****))
13:49:13 10660 condition: or{ {match_ip{$sender_host_address}{iplsearch;/etc/exim/allow_auth_hosts}}{eq {public}{lookup ldap{ user=${quote_ldap:CN=exim,CN=Users,DC=*****,DC=com} pass=*** ldap:///DC=***,DC=com?description?sub?(&(objectClass=group)(grouptype=2)(mail=${quote_ldap:${local_part}@${domain}}))}}}
13:49:13 10660    result: false
13:49:13 10660 expanding: ${if or{ {match_ip{$sender_host_address}{iplsearch;/etc/exim/allow_auth_hosts}}{eq {public}{lookup ldap{ user=${quote_ldap:CN=exim,CN=Users,DC=***,DC=com} pass=*** ldap:///DC=***,DC=com?description?sub?(&(objectClass=group)(grouptype=2)(mail=${quote_ldap:${local_part}@${domain}}))}}}}}
13:49:13 10660    result: }
13:49:13 10660 calling adsi_group_check router

Скорее всего условие немного неправильное. Любые идеи - Welcom.

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2460 рублей (8 CPU, 8Gb RAM, 2x500Gb HDD, RAID 3ware 9750):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

blade_007
ст. прапорщик
Сообщения: 571
Зарегистрирован: 2010-03-12 12:59:08
Контактная информация:

Re: Exim, группы рассылки в AD

Непрочитанное сообщение blade_007 » 2010-05-26 14:29:50

PS:

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

exim -be

Код: Выделить всё

> ${lookup ldap{ user=${quote_ldap:CN=exim,CN=Users,DC=*********,DC=com} pass=*** ldap:///DC=*****,DC=com?description?sub?(&(objectClass=group)(grouptype=2)(mail=testgroup@*****))}}
public
>
Дополнительный вопрос к настройке кеширования запрос в exim. Если несколько раз менять description (поле, которое ищется этим запросом), то exim будет возвращать одно и тоже значение, только спустя какой-то время (час/два) он заметит изменения. Кто как с этим борется?

blade_007
ст. прапорщик
Сообщения: 571
Зарегистрирован: 2010-03-12 12:59:08
Контактная информация:

[SOLVED] Exim, группы рассылки в AD

Непрочитанное сообщение blade_007 » 2010-05-28 14:15:37

Вот рабочее решение. Оказалось, что я сам себя запутал в условии. Итак, данный роутер у меня вставляется ПОСЛЕ роутера dnslookup и ДО роутера ldapuser, что вообщем то логично. Переменные:

Код: Выделить всё

ldap_default_servers = <;  172.16.***:3268 ; 10.1.***:3268
LDAP_AD_BINDDN =${quote_ldap:CN=exim,CN=Users,DC=****,DC=com}
LDAP_AD_PASS =123123
LDAP_AD_BASE =DC=********,DC=com
LDAP_AD_RCPT =user=LDAP_AD_BINDDN \
pass=LDAP_AD_PASS \
ldap:///LDAP_AD_BASE?mail?sub?\
(&\
    (|\
    (objectclass=user)(objectclass=person)\
    )\
    (!(userAccountControl:1.2.840.113556.1.4.803:=2))\
    (mail=${quote_ldap:$local_part}@${quote_ldap:$domain})\
)
Файл со списками подсетей, которым разрешено писать на групповые адреса (указываются в основном частные "серые" подсети, хотя можно указать и "белые" - выбор за Вами).

Код: Выделить всё

cat allow_auth_hosts 
#10.0.0.0/8
172.16.0.0/12
Немного о данном роутере. Роутер redirect не имеет опции transport, потому как при срабатывании генерирует один (или ни одного) или несколько адресов. Данные адреса либо возвращаются в начало процесса роутинга, либо передаются указанному роутеру (см. опцию redirect_router). Самое главное условие для data найденно на этом форуме (glukky если не ошибаюсь http://forum.lissyara.su/viewtopic.php?f=20&t=10382) и немного изменено. В поле data возвращается список адресов для обработки. Поиск среди групп рассылки, для которых в поле Эл. адрес указан заданный адрес для проверки, результат, возвращаемый функцией ldapm - список DN, разделенных запятыми. Для данного списка применяется функция sg, которая заменяет символы ", " (запятая и пробел) на \n. Затме этот список DN\nDN\n подается на вход функции map, которая для каждого DN вытягивает поле mail. Полученный список mail\nmail\n подается на вход функции sg, которая заменяет \n на ", " (запятую и пробел).
Условие, написанное мной намного проще. ЛИБО адрес IP-адрес отправителя является разрешенным (входит в указанные в файле allow_auth_hosts диапазоны), ЛИБО для заданного эл. адреса ищется поле описание (description) группы, и если оно совпадает с заданным мной ключевым словом (в данном случае - public), то роутер отправляется искать данные для редиректа (собственно, все те действия, что описаны выше).

Код: Выделить всё

adsi_group_check:
        driver = redirect
        domains = +local_domains
        allow_defer
        condition = \
        ${if or{ \
           { eq {${lookup ldap{ \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///LDAP_AD_BASE?description?sub?\
              (&\
                  (objectClass=group)\
                  (grouptype=2)\
                  (mail=${quote_ldap:${local_part}@${domain}})\
              )\
           }}}{public}}\
           {match_ip{$sender_host_address}{iplsearch;/etc/exim/allow_auth_hosts}}\
            }\
        }
        data = ${sg{${map {<\n \
           ${sg{${lookup ldapm { \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///LDAP_AD_BASE?member?sub?\
              (&\
                  (objectClass=group)\
                  (grouptype=2)\
                  (mail=${quote_ldap:${local_part}@${domain}})\
              )\
           }}}{\N, \N}{\n}}} \
           {${lookup ldap{ \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///${quote_ldapdn:$item}?mail?base?}} \
           }}}{\N\n\N}{, } \
            }
        redirect_router = ldapuser
Тесты:

Ввел в поле description public1

Код: Выделить всё

[]# /usr/sbin/exim -bt testgroup
testgroup@******* is undeliverable: Unrouteable address
Ввел в поле description public

Код: Выделить всё

[]# /usr/sbin/exim -bt testgroup
test@******
    <-- testgroup@********
  router = ldapuser, transport = dovecot_delivery
Немного сумбурно описано, но работает и мне пока понятно как.
Всем спасибо.

Larin
лейтенант
Сообщения: 975
Зарегистрирован: 2008-01-29 20:08:41
Откуда: РБ, Минск

Re: Exim, группы рассылки в AD

Непрочитанное сообщение Larin » 2010-10-11 22:33:27

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

blade_007
ст. прапорщик
Сообщения: 571
Зарегистрирован: 2010-03-12 12:59:08
Контактная информация:

Re: Exim, группы рассылки в AD

Непрочитанное сообщение blade_007 » 2010-10-16 21:44:08

Более подробней об алиасах расскажите. И о том, что именно ожидаете.
Навскидку можно написать еще один роутер, который ищет уже по полю proxyAddresses в AD, и передает данные роутеру ldapuser (в моем случае). Роутер ldapuser получает на вход список адресов для доставки (если поиск успешен и список не пуст) и вызывает dovecot-lda с параметрами -d $local_part@$domain. dovecot-lda согласно конфигу ищет home/mail директории пользователя, который относится к обслуживаемому домену, в нескольких(!) местах (для этого используются 2 ldap-запроса: один для поиска по полю mail, другой по полю proxyAddresses). Примерно такой ход мыслей.

Larin
лейтенант
Сообщения: 975
Зарегистрирован: 2008-01-29 20:08:41
Откуда: РБ, Минск

Re: Exim, группы рассылки в AD

Непрочитанное сообщение Larin » 2010-10-17 11:38:13

для юзеров которым нужен алиас создал отдельную группу в которую входит только один юзер...
получается по рассылке через группы юзер получает письмо.

blade_007
ст. прапорщик
Сообщения: 571
Зарегистрирован: 2010-03-12 12:59:08
Контактная информация:

Re: Exim, группы рассылки в AD

Непрочитанное сообщение blade_007 » 2010-10-21 15:49:47

Поругайте данное решение, на мой взгляд есть где подправить.

В моем случае в качестве БД пользователей используется Active Directory. Стандарта нет, но я использую поле mail для обозначения основного почтового аккаунта, поле otherMailbox - список алиасов данного аккаунта, поле proxyAddresses - список аккаунтов для пересылки (редиректа).

Основные макросы:

Код: Выделить всё

ldap_default_servers = <;  172.27.1.2:3268 ; 10.1.11.3:3268
LDAP_AD_BINDDN =${quote_ldap:CN=exim,CN=Users,DC=***,DC=****,DC=com}
LDAP_AD_PASS =badm-123
LDAP_AD_BASE =DC=****,DC=****,DC=com

# макрос для извлечения поля mail (у меня аккаунты вида user@domain), поменял адрес ldap-сервера просто для тестов
LDAP_AD_SRV = 172.27.1.2:389
LDAP_AD_RCPT2 =user=LDAP_AD_BINDDN \
pass=LDAP_AD_PASS \
ldap://LDAP_AD_SRV/LDAP_AD_BASE?mail?sub?\
(&\
    (|\
    (objectclass=user)(objectclass=person)\
    )\
    (!(userAccountControl:1.2.840.113556.1.4.803:=2))\
    (otherMailbox=${quote_ldap:$local_part}@${quote_ldap:$domain})\
)

LDAP_AD_RCPT =user=LDAP_AD_BINDDN \
pass=LDAP_AD_PASS \
ldap:///LDAP_AD_BASE?mail?sub?\
(&\
    (|\
    (objectclass=user)(objectclass=person)\
    )\
    (!(userAccountControl:1.2.840.113556.1.4.803:=2))\
    (mail=${quote_ldap:$local_part}@${quote_ldap:$domain})\
)
Алиас: ящик не существует в базе аккаунтов (всевозможные аккаунты вида noc@DOMAIN, sysadmin@DOMAIN)

Код: Выделить всё

system_aliases:
        driver = redirect
        allow_defer
        allow_fail
#       #data = ${lookup mysql{SELECT recipients FROM aliases WHERE local_part='${local_part}' AND domain='${domain}'}}
        data = ${lookup ldap{LDAP_AD_RCPT2}}
Редирект: ящик существует в базе аккаунтов (всевозможные пересылки на существующие в AD аккаунты. Имеет вид: smtp:user1@domain, smtp:user2@domain, sip:user@domain). Поскольку в proxyAddresses встречаются адреса вида sip:user@domain (иногда используется MS Live Meeting), то нужно выбрать только адреса вида smtp:*. Главный lookup выбирает поле proxyAddresses для заданного почтового ящика (user@domain.XX). Если возвращается что-то (список вида smtp:user1@domain, smtp:user2@domain, sip:user@domain), то к нему применяется функция filter. Данная функция для каждого элемента списка (по умолчанию элементы разделяются ':', но я переопределяю на ',') производит сравнение с неким регулярным выражением (в моем случае, \N^smtp\N). На выходе получается новая строка, содержащая только элементы вида smtp:user1@domain, smtp:user2@domain, которая подается на вход функции sg. SG удаляет каждое вхождение 'smtp:' из строки. Собственно все.

Код: Выделить всё

adsi_redirect:
       driver = redirect
       domains = +local_domains
       data = ${sg\
       {\
           ${filter\
               {<,\
               ${lookup ldap{user=LDAP_AD_BINDDN pass=LDAP_AD_PASS ldap:///LDAP_AD_BASE?proxyAddresses?sub?(&(objectClass=user)(mail=${quote_ldap:${local_part}@${domain}}))}}\
               }\
               {match {$item}{\N^smtp\N}}\
               }\
       }\
           {smtp:}\
           {}\
       }
       redirect_router = ldapuser
Роутер, используемый для поиска аккаунтов, если конечно они есть

Код: Выделить всё

ldapuser:
        driver = accept
        domains = +local_domains
        condition = ${if !eq{}{${lookup ldapdn{LDAP_AD_RCPT}}}{yes}{no}}
        transport = dovecot_delivery
Транспорт:

Код: Выделить всё

dovecot_delivery:
        driver = pipe
        command = /usr/libexec/dovecot/deliver -d $local_part@$domain
        message_prefix =
        message_suffix =
        log_output
        delivery_date_add
        envelope_to_add
        return_path_add
        user = mailnull
        group = mail

blade_007
ст. прапорщик
Сообщения: 571
Зарегистрирован: 2010-03-12 12:59:08
Контактная информация:

Re: Exim, группы рассылки в AD

Непрочитанное сообщение blade_007 » 2010-10-29 20:32:01

Нет желающих покритиковать данное решение? :smile:
Кстати, можно убрать пересылку на конкретный роутер, чтоб заново запускался процесса роутинга почты. Только важно следить, чтоб не было транзитивного замыкания (otherMailbox = mail = proxyAddresses и по новой). Как-то так...

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35066
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: Exim, группы рассылки в AD

Непрочитанное сообщение Alex Keda » 2010-11-03 20:45:27

если работает - нормальное решение
чё ругать-то
Убей их всех! Бог потом рассортирует...

Viks
проходил мимо

Exim, группы рассылки в AD

Непрочитанное сообщение Viks » 2018-05-15 9:53:57

Добрый день
Пытаюсь настроить групу рассылки по даному ману
Но походу потому что у меня АД на 2008 то Ldap немного не такой результат отдает
Вот что я получаю:

Код: Выделить всё

LDAP attr loop
LDAP value loop member:CN=emailtest,OU=office unit,DC=DoMaIn,DC=local
LDAP value loop member:CN=Кирилица,OU=office unit,DC=DoMaIn,DC=local
search ended by ldap_result yielding 115
ldap_parse_result: -14
ldap_parse_result yielded 0: Success
LDAP search: returning: CN=emailtest,,OU=office unit,,DC=DoMaIn,,DC=local,CN=Кирилица,,OU=office unit,,DC=DoMaIn,,DC=local
В резуьлтате вместо вдух срок с двумя разными узерами я получаю одну строку и соответственно эта строка итед в

Код: Выделить всё

map: $item =
Подскажите плз как правильно SG сказать об замене?

Сорри за глупый вопрос)

Viks
проходил мимо

Exim, группы рассылки в AD

Непрочитанное сообщение Viks » 2018-05-15 12:32:06

Разобрался)
Мне подошла такая замена

Код: Выделить всё

        data = ${sg{${map {<\n \
           ${sg{${sg{${lookup ldapm { \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///LDAP_AD_BASE?member?sub?\
              (&\
                  (objectClass=group)\
                  (grouptype=2)\
                  (mail=${quote_ldap:${local_part}@${domain}})\
              )\
           }}}{\Nlocal,CN=\N}{local\nCN=}}}{\N,,\N}{,}}} \
           {${lookup ldap{ \
               user=LDAP_AD_BINDDN \
               pass=LDAP_AD_PASS \
               ldap:///${quote_ldapdn:$item}?mail?base?}} \
           }}}{\N\n\N}{, } \
            }