[Exim-users] совсем виртуальные пользователи и редирект

59 views
Skip to first unread message

Victor Sudakov

unread,
Sep 30, 2020, 3:28:41 AM9/30/20
to exim-...@mailground.net
Коллеги,

Переношу одну legacy почтовую систему на exim+dovecot. И еще прошу помощи.

Работает доставка в dovecot (см. ниже). Но ещё надо письма некоторым
адресатам из +dovecot_domains отправлять не в dovecot, а форвардить на
другие почтовые сервера согласно списку:

pup...@mydomain.ru : pup...@gmail.com
vas...@mydomain.com : pup...@gmail.com

При этом mydomain.ru и mydomain.com входят в +dovecot_domains.

Можно как-то перехватить роутинг до срабатывания router dovecot и
отправить в другой router и transport, который отправит почту для
pup...@mydomain.ru по MX на pup...@gmail.com?

Добавлять +dovecot_domains в local_domains не хотелось бы, если без
этого можно обойтись. Т.е. хотелось бы устроить нечто вроде нелокальных /etc/aliases.

# фрагмент текущей конфигурации

begin routers
dovecot:
driver = accept
domains = +dovecot_domains
transport = dovecot_lmtp

[...]

begin transports
dovecot_lmtp:
driver = lmtp
socket = /var/run/dovecot/lmtp

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________
Exim-users mailing list
Exim-...@mailground.net
http://mailground.net/mailman/listinfo/exim-users

dawnshade

unread,
Sep 30, 2020, 4:55:00 AM9/30/20
to Exim MTA на русском
Привет.
Ну алиасы точно так же работают с таким роутером перед довкотом:
 
user_aliases:
  driver = redirect
  allow_fail
  allow_defer
  data = ${lookup{$local_part@$domain}lsearch{/etc/exim/aliases}}
  user = exim
  group = mail
  file_transport = address_file
  pipe_transport = address_pipe
 
проблема в том, что очередь из-за этого забивается. тк едет весь dkim/spf/etc и удаленка не принимает письмо
Среда, 30 сентября 2020, 10:29 +03:00 от Victor Sudakov <v...@sibptus.ru>:
 
 
--
- -
 

Victor Sudakov

unread,
Sep 30, 2020, 5:57:43 AM9/30/20
to exim-...@mailground.net
dawnshade wrote:
>
> Привет.
> Ну алиасы точно так же работают с таким роутером перед довкотом:
>  
> user_aliases:
>   driver = redirect
>   allow_fail
>   allow_defer
>   data = ${lookup{$local_part@$domain}lsearch{/etc/exim/aliases}}
>   user = exim
>   group = mail
>   file_transport = address_file
>   pipe_transport = address_pipe

О, замечательно! А зачем тут user, group, pipe_transport и прочие
параметры, они точно нужны?

Я вот сейчас написал просто перед довкотом:

# Redirect virtual users
virtual_redirect:
driver = redirect
data = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}}


и оно вроде работает, по крайней мере "exim -bt" ожидаемо их резолвит
куда надо (реальную доставку не успел попробовать).

>  
> проблема в том, что очередь из-за этого забивается. тк едет весь dkim/spf/etc и удаленка не принимает письмо

Ну это проблема с форвардами всегда такая была со времен появления SPF, тут
только SRS спасет IMHO. Интересно, можно ли прикрутить SRS к redirect-у.

dawnshade

unread,
Sep 30, 2020, 6:40:35 AM9/30/20
to Exim MTA на русском
Да какие-то куски легаси, работает без них и хорошо.
Про SRS пишут местами что оно мертвое — https://bugs.exim.org/show_bug.cgi?id=1649
 
Среда, 30 сентября 2020, 12:59 +03:00 от Victor Sudakov <v...@sibptus.ru>:
 
 
--
- -
 

Victor Sudakov

unread,
Sep 30, 2020, 6:53:26 AM9/30/20
to exim-...@mailground.net
Victor Sudakov wrote:
>
> О, замечательно! А зачем тут user, group, pipe_transport и прочие
> параметры, они точно нужны?
>
> Я вот сейчас написал просто перед довкотом:
>
> # Redirect virtual users
> virtual_redirect:
> driver = redirect
> data = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}}
>
>
> и оно вроде работает, по крайней мере "exim -bt" ожидаемо их резолвит
> куда надо (реальную доставку не успел попробовать).

А вот такие 2 условия, добавленные в acl_check_rcpt (контекст тоже привожу),
нормально выглядят или можно улучшить? А как бы их в одно логическое выражение
объединить, не подскажете?

# Insist that a HELO/EHLO was accepted.

require message = nice hosts say HELO first
condition = ${if def:sender_helo_name}

# Accept mail for forwarded domains
accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}

# Accept valid recipient adresses in dovecot domains
accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}

# Insist that any other recipient address that we accept is either in one of
# our local domains, or is in a domain for which we explicitly allow
# relaying. Any other domain is rejected as being unacceptable for relaying.

require message = relay not permitted
domains = +local_domains : +relay_to_domains

George L. Yermulnik

unread,
Sep 30, 2020, 8:08:49 AM9/30/20
to exim-...@mailground.net
Hello!

On Wed, 30 Sep 2020 at 16:57:11 (+0700), Victor Sudakov wrote:

> > user_aliases:
> >   driver = redirect
> >   allow_fail
> >   allow_defer
> >   data = ${lookup{$local_part@$domain}lsearch{/etc/exim/aliases}}
> >   user = exim
> >   group = mail
> >   file_transport = address_file
> >   pipe_transport = address_pipe

> О, замечательно! А зачем тут user, group, pipe_transport и прочие
> параметры, они точно нужны?

"user, group" - очевидно вроде ж. для транспорта, если вдруг нужно
деливерить из-под юзера/группы, отличной от exim'овских.

pipe_transport - чтобы на пайпу форвардить.
file_transport - чтобы в файл деливерить.

allow_fail/allow_defer - чтобы фейлить или диферить прямо из data
например, можно в тот же aliases записать вот такое, чтобы давать
кастомные отлупы per $local_part@$domain:
pup...@domain.com :fail: Pupkin has gone for good

--
George L. Yermulnik
[YZ-RIPE]

George L. Yermulnik

unread,
Sep 30, 2020, 8:17:56 AM9/30/20
to exim-...@mailground.net
Hello!

On Wed, 30 Sep 2020 at 17:53:00 (+0700), Victor Sudakov wrote:

> А вот такие 2 условия, добавленные в acl_check_rcpt (контекст тоже привожу),
> нормально выглядят или можно улучшить? А как бы их в одно логическое выражение
> объединить, не подскажете?

> # Accept mail for forwarded domains


> accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}

> # Accept valid recipient adresses in dovecot domains
> accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}

По сути эти оба стейтмента покрываются тем, который ниже, т.к. он
пропустит только домены из списков +local_domains и +relay_to_domains,
но не закончит, а передаст нижеследующим стейтментам, если они есть.
Там где-то в конце блока acl_check_rcpt должен быть accept для всего,
что дошло до него. В него (или перед ним) можно (нужно?) добавить
проверку получателя, чтобы exim проверил его деливерабельность и выдал
отлуп, если получатель undeliverable.

> # Insist that any other recipient address that we accept is either in one of
> # our local domains, or is in a domain for which we explicitly allow
> # relaying. Any other domain is rejected as being unacceptable for relaying.

> require message = relay not permitted
> domains = +local_domains : +relay_to_domains

--
George L. Yermulnik
[YZ-RIPE]

Victor Sudakov

unread,
Sep 30, 2020, 9:01:32 AM9/30/20
to exim-...@mailground.net
George L. Yermulnik wrote:
> Hello!
>
> On Wed, 30 Sep 2020 at 16:57:11 (+0700), Victor Sudakov wrote:
>
> > > user_aliases:
> > >   driver = redirect
> > >   allow_fail
> > >   allow_defer
> > >   data = ${lookup{$local_part@$domain}lsearch{/etc/exim/aliases}}
> > >   user = exim
> > >   group = mail
> > >   file_transport = address_file
> > >   pipe_transport = address_pipe
>
> > О, замечательно! А зачем тут user, group, pipe_transport и прочие
> > параметры, они точно нужны?
>
> "user, group" - очевидно вроде ж. для транспорта, если вдруг нужно
> деливерить из-под юзера/группы, отличной от exim'овских.

> pipe_transport - чтобы на пайпу форвардить.
> file_transport - чтобы в файл деливерить.

Но какой у redirect-а транспорт? Он же просто переадресует письмо и оно
отправится дальше по роутерам, а у тех уже свои транспорты.

Или это чтобы в /etc/exim/aliases перенаправить в "| some_program" и т.п.?

>
> allow_fail/allow_defer - чтобы фейлить или диферить прямо из data
> например, можно в тот же aliases записать вот такое, чтобы давать
> кастомные отлупы per $local_part@$domain:
> pup...@domain.com :fail: Pupkin has gone for good

Проверил у себя. В моём случае ":fail: Pupkin has gone for good" в
aliases не срабатывает в SMTP сессии. В смысле сперва письмо
принимается, а потом генерится отлуп. В таком виде оно мне не надо,
наверное.

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Victor Sudakov

unread,
Sep 30, 2020, 9:11:20 AM9/30/20
to exim-...@mailground.net
George L. Yermulnik wrote:
>
> On Wed, 30 Sep 2020 at 17:53:00 (+0700), Victor Sudakov wrote:
>
> > А вот такие 2 условия, добавленные в acl_check_rcpt (контекст тоже привожу),
> > нормально выглядят или можно улучшить? А как бы их в одно логическое выражение
> > объединить, не подскажете?
>
> > # Accept mail for forwarded domains
> > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}
>
> > # Accept valid recipient adresses in dovecot domains
> > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}
>
> По сути эти оба стейтмента покрываются тем, который ниже, т.к. он
> пропустит только домены из списков +local_domains и +relay_to_domains,

Ну у меня dovecot-овские домены в отдельном списке +dovecot_domains, но
не суть.

> но не закончит, а передаст нижеследующим стейтментам, если они есть.

Нижеследующих там только "require verify = recipient", а потом accept. И
они мне не помогут отказать в приеме почты для несуществующих
пользователей в виртуальных доменах, потому что по LMTP невозможно
на ходу проверить, какие пользователи есть в dovecot, а каких нет.

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

Хотел бы только понять синтаксис, как эти два условия объединить в ИЛИ.

> Там где-то в конце блока acl_check_rcpt должен быть accept для всего,
> что дошло до него. В него (или перед ним) можно (нужно?) добавить
> проверку получателя, чтобы exim проверил его деливерабельность и выдал
> отлуп, если получатель undeliverable.

Не может он проверить деливерабельность по LMTP, в том и беда.


--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

dawnshade

unread,
Sep 30, 2020, 9:16:34 AM9/30/20
to Exim MTA на русском
А чего ЛМТП не заменить на dovecot-lda, последний вроде умеет проверку.

 
Среда, 30 сентября 2020, 16:12 +03:00 от Victor Sudakov <v...@sibptus.ru>:
 
 
--
- -
 

George L. Yermulnik

unread,
Sep 30, 2020, 9:27:04 AM9/30/20
to exim-...@mailground.net
Hello!

On Wed, 30 Sep 2020 at 20:01:06 (+0700), Victor Sudakov wrote:

> > > > user_aliases:
> > > >   driver = redirect
> > > >   allow_fail
> > > >   allow_defer
> > > >   data = ${lookup{$local_part@$domain}lsearch{/etc/exim/aliases}}
> > > >   user = exim
> > > >   group = mail
> > > >   file_transport = address_file
> > > >   pipe_transport = address_pipe

> > > О, замечательно! А зачем тут user, group, pipe_transport и прочие
> > > параметры, они точно нужны?

> > "user, group" - очевидно вроде ж. для транспорта, если вдруг нужно
> > деливерить из-под юзера/группы, отличной от exim'овских.

> > pipe_transport - чтобы на пайпу форвардить.
> > file_transport - чтобы в файл деливерить.

> Но какой у redirect-а транспорт? Он же просто переадресует письмо и оно
> отправится дальше по роутерам, а у тех уже свои транспорты.

> Или это чтобы в /etc/exim/aliases перенаправить в "| some_program" и т.п.?

Именно.

> > allow_fail/allow_defer - чтобы фейлить или диферить прямо из data
> > например, можно в тот же aliases записать вот такое, чтобы давать
> > кастомные отлупы per $local_part@$domain:
> > pup...@domain.com :fail: Pupkin has gone for good

> Проверил у себя. В моём случае ":fail: Pupkin has gone for good" в
> aliases не срабатывает в SMTP сессии. В смысле сперва письмо
> принимается, а потом генерится отлуп. В таком виде оно мне не надо,
> наверное.

Чтобы оно в smtp-сессии отлуп давало нужно в acl_check_rcpt добавить
соответствующую проверку.

Вот так это в дефолтном конфиге на Фре выглядит (у него финальный accept
в секции acl_check_rcot):
require verify = recipient

А вот так в кастомном (у меня deny в финале секции acl_check_rcpt):
accept domains = +all_local_domains
endpass
message = Final recipient verification failed
verify = recipient/callout=2m,use_sender,no_cache,defer_ok

--
George L. Yermulnik
[YZ-RIPE]

_______________________________________________

George L. Yermulnik

unread,
Sep 30, 2020, 9:37:37 AM9/30/20
to exim-...@mailground.net
Hello!

On Wed, 30 Sep 2020 at 20:10:52 (+0700), Victor Sudakov wrote:

> > > А вот такие 2 условия, добавленные в acl_check_rcpt (контекст тоже привожу),
> > > нормально выглядят или можно улучшить? А как бы их в одно логическое выражение
> > > объединить, не подскажете?

> > > # Accept mail for forwarded domains
> > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}

> > > # Accept valid recipient adresses in dovecot domains
> > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}

> Хотел бы только понять синтаксис, как эти два условия объединить в ИЛИ.

[--- cut ---]
11.8 Combining expansion conditions
-----------------------------------

Several conditions can be tested at once by combining them using the and and or
combination conditions. Note that and and or are complete conditions on their
own, and precede their lists of sub-conditions. Each sub-condition must be
enclosed in braces within the overall braces that contain the list. No
repetition of if is used.

or {{<cond1>}{<cond2>}...}

The sub-conditions are evaluated from left to right. The condition is true
if any one of the sub-conditions is true. For example,

${if or {{eq{$local_part}{spqr}}{eq{$domain}{testing.com}}}...

When a true sub-condition is found, the following ones are parsed but not
evaluated. If there are several "match" sub-conditions the values of the
numeric variables afterwards are taken from the first one that succeeds.

and {{<cond1>}{<cond2>}...}

The sub-conditions are evaluated from left to right. The condition is true
if all of the sub-conditions are true. If there are several "match"
sub-conditions, the values of the numeric variables afterwards are taken
from the last one. When a false sub-condition is found, the following ones
are parsed but not evaluated.
[--- cut ---]

Что-нить в таком духе:
accept condition = ${or {lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}} \
{lookup{$local_part@$domain}lsearch{/etc/dovecot/users}} \
}

--
George L. Yermulnik
[YZ-RIPE]

_______________________________________________

Victor Sudakov

unread,
Sep 30, 2020, 11:00:21 AM9/30/20
to exim-...@mailground.net
dawnshade wrote:
>
> А чего ЛМТП не заменить на dovecot-lda, последний вроде умеет проверку.

А черт его знает, наверное просто не нашёл хорошего howto по
exim+dovecot, собирал по немногу отовсюду да сам додумывал.

Если есть толковый best practice, с благодарностью приму ссылку.

Опять же, при LMTP о правах на файловой системе думать не надо. А
dovecot-lda поди придется делать setuid или setgid. В общем пошёл по
простому пути за неимением грамотного наставления.

Victor Sudakov

unread,
Sep 30, 2020, 11:03:50 AM9/30/20
to exim-...@mailground.net
George L. Yermulnik wrote:
>
> > > > > user_aliases:
> > > > >   driver = redirect
> > > > >   allow_fail
> > > > >   allow_defer
> > > > >   data = ${lookup{$local_part@$domain}lsearch{/etc/exim/aliases}}
> > > > >   user = exim
> > > > >   group = mail
> > > > >   file_transport = address_file
> > > > >   pipe_transport = address_pipe
>
> > > > О, замечательно! А зачем тут user, group, pipe_transport и прочие
> > > > параметры, они точно нужны?
>
> > > "user, group" - очевидно вроде ж. для транспорта, если вдруг нужно
> > > деливерить из-под юзера/группы, отличной от exim'овских.
>
> > > pipe_transport - чтобы на пайпу форвардить.
> > > file_transport - чтобы в файл деливерить.
>
> > Но какой у redirect-а транспорт? Он же просто переадресует письмо и оно
> > отправится дальше по роутерам, а у тех уже свои транспорты.
>
> > Или это чтобы в /etc/exim/aliases перенаправить в "| some_program" и т.п.?
>
> Именно.

Буду иметь в виду, но пока не нужно.

>
> > > allow_fail/allow_defer - чтобы фейлить или диферить прямо из data
> > > например, можно в тот же aliases записать вот такое, чтобы давать
> > > кастомные отлупы per $local_part@$domain:
> > > pup...@domain.com :fail: Pupkin has gone for good
>
> > Проверил у себя. В моём случае ":fail: Pupkin has gone for good" в
> > aliases не срабатывает в SMTP сессии. В смысле сперва письмо
> > принимается, а потом генерится отлуп. В таком виде оно мне не надо,
> > наверное.
>
> Чтобы оно в smtp-сессии отлуп давало нужно в acl_check_rcpt добавить
> соответствующую проверку.
>
> Вот так это в дефолтном конфиге на Фре выглядит (у него финальный accept
> в секции acl_check_rcot):
> require verify = recipient
>
> А вот так в кастомном (у меня deny в финале секции acl_check_rcpt):
> accept domains = +all_local_domains
> endpass
> message = Final recipient verification failed
> verify = recipient/callout=2m,use_sender,no_cache,defer_ok

Да вот не работает callout почему-то по LMTP.

А можно я кусок своего конфига покажу, где acl и роутеры?

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Victor Sudakov

unread,
Sep 30, 2020, 11:07:58 AM9/30/20
to Exim MTA на русском
George L. Yermulnik wrote:
> On Wed, 30 Sep 2020 at 20:10:52 (+0700), Victor Sudakov wrote:
>
> > > > А вот такие 2 условия, добавленные в acl_check_rcpt (контекст тоже привожу),
> > > > нормально выглядят или можно улучшить? А как бы их в одно логическое выражение
> > > > объединить, не подскажете?
>
> > > > # Accept mail for forwarded domains
> > > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}
>
> > > > # Accept valid recipient adresses in dovecot domains
> > > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}
>
> > Хотел бы только понять синтаксис, как эти два условия объединить в ИЛИ.

[dd]

>
> Что-нить в таком духе:
> accept condition = ${or {lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}} \
> {lookup{$local_part@$domain}lsearch{/etc/dovecot/users}} \
> }

Благодарю! Хотя не вижу тут {yes} почему-то, как я привык.

А как вообще в exim потестировать condition? Ну я ему строчку, а он мне в
ответ yes или no (с реальными /etc/dovecot/aliases и /etc/dovecot/users
разумеется).

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

dawnshade

unread,
Sep 30, 2020, 11:27:38 AM9/30/20
to Exim MTA на русском
в lda бонусом идут sieve фильтры.
dovecot_lda:
        driver = accept
        local_parts= ...
        domains =  +local_domains
        transport = dovecot_lda_transport
 
dovecot_lda_transport:
  driver = pipe
  command = /usr/libexec/dovecot/deliver -d $local_part@$domain  -f $sender_address
  message_prefix =
  message_suffix =
  log_output
  delivery_date_add
  envelope_to_add
  return_path_add

  user = exim
  group = mail
  #mode = 0660
  temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78
 
прав там никаких нинадо курочить (по крайней мере в центоси)
 
Среда, 30 сентября 2020, 18:01 +03:00 от Victor Sudakov <v...@sibptus.ru>:
 
 
--
- -
 

George L. Yermulnik

unread,
Sep 30, 2020, 11:49:29 AM9/30/20
to exim-...@mailground.net
Hello!

On Wed, 30 Sep 2020 at 22:03:26 (+0700), Victor Sudakov wrote:

> > > > allow_fail/allow_defer - чтобы фейлить или диферить прямо из data
> > > > например, можно в тот же aliases записать вот такое, чтобы давать
> > > > кастомные отлупы per $local_part@$domain:
> > > > pup...@domain.com :fail: Pupkin has gone for good

> > > Проверил у себя. В моём случае ":fail: Pupkin has gone for good" в
> > > aliases не срабатывает в SMTP сессии. В смысле сперва письмо
> > > принимается, а потом генерится отлуп. В таком виде оно мне не надо,
> > > наверное.

> > Чтобы оно в smtp-сессии отлуп давало нужно в acl_check_rcpt добавить
> > соответствующую проверку.

> > Вот так это в дефолтном конфиге на Фре выглядит (у него финальный accept
> > в секции acl_check_rcot):
> > require verify = recipient

> > А вот так в кастомном (у меня deny в финале секции acl_check_rcpt):
> > accept domains = +all_local_domains
> > endpass
> > message = Final recipient verification failed
> > verify = recipient/callout=2m,use_sender,no_cache,defer_ok

> Да вот не работает callout почему-то по LMTP.

Я сам не юзаю lmtp, но гугл имеет что сказать =)
Вот пару ссылок по теме:
https://wiki.dovecot.org/LMTP/Exim#Verifying_recipients_using_LMTP
https://lists.exim.org/lurker/message/20040427.231839.a37eddca.ca.html

Гуглил по "exim lmtp verify recipient callout" =)

> А можно я кусок своего конфига покажу, где acl и роутеры?

Только если там нет контента +18 =))

--
George L. Yermulnik
[YZ-RIPE]

_______________________________________________

George L. Yermulnik

unread,
Sep 30, 2020, 12:04:37 PM9/30/20
to exim-...@mailground.net
Hello!

On Wed, 30 Sep 2020 at 22:07:33 (+0700), Victor Sudakov wrote:

> > > > > А вот такие 2 условия, добавленные в acl_check_rcpt (контекст тоже привожу),
> > > > > нормально выглядят или можно улучшить? А как бы их в одно логическое выражение
> > > > > объединить, не подскажете?

> > > > > # Accept mail for forwarded domains
> > > > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}

> > > > > # Accept valid recipient adresses in dovecot domains
> > > > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}

> > > Хотел бы только понять синтаксис, как эти два условия объединить в ИЛИ.

> [dd]

> > Что-нить в таком духе:
> > accept condition = ${or {lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}} \
> > {lookup{$local_part@$domain}lsearch{/etc/dovecot/users}} \
> > }

> Благодарю! Хотя не вижу тут {yes} почему-то, как я привык.

А он там не нужен. Даже хуже может сделать.
В этом контексте это значение по умолчанию, которое вернёт лукап, если
зафейлится. А он же ж должен зафелить кондишен, если строка не была
найдена, а не вернуть "yes".

> А как вообще в exim потестировать condition? Ну я ему строчку, а он мне в
> ответ yes или no (с реальными /etc/dovecot/aliases и /etc/dovecot/users
> разумеется).

Можно как-то тестить конкретные acl, но я не помню как, а в доке лень
копаться. Можно протестить всю smtp-сессию:
exim -d -bh какой-нить-ip-адрес

Заменить "" на "-bhc" - чтобы callout'ы тоже выполнялись

Также для "-d" можно включить только определённую debug data. Но это
оставлю для "man exim" =)
Мне чаще всего хватает "-d-all+acl+expand+route+transport", чтобы
потестировать правила.
Либо "-d-all+acl+expand+route+transport+lists+lookup+rewrite", когда не
хватило предыдущего фильтра debug data.

--
George L. Yermulnik
[YZ-RIPE]

_______________________________________________

Victor Sudakov

unread,
Sep 30, 2020, 11:49:00 PM9/30/20
to exim-...@mailground.net
George L. Yermulnik wrote:
>
> > > > > allow_fail/allow_defer - чтобы фейлить или диферить прямо из data
> > > > > например, можно в тот же aliases записать вот такое, чтобы давать
> > > > > кастомные отлупы per $local_part@$domain:
> > > > > pup...@domain.com :fail: Pupkin has gone for good
>
> > > > Проверил у себя. В моём случае ":fail: Pupkin has gone for good" в
> > > > aliases не срабатывает в SMTP сессии. В смысле сперва письмо
> > > > принимается, а потом генерится отлуп. В таком виде оно мне не надо,
> > > > наверное.
>
> > > Чтобы оно в smtp-сессии отлуп давало нужно в acl_check_rcpt добавить
> > > соответствующую проверку.
>
> > > Вот так это в дефолтном конфиге на Фре выглядит (у него финальный accept
> > > в секции acl_check_rcot):
> > > require verify = recipient
>
> > > А вот так в кастомном (у меня deny в финале секции acl_check_rcpt):
> > > accept domains = +all_local_domains
> > > endpass
> > > message = Final recipient verification failed
> > > verify = recipient/callout=2m,use_sender,no_cache,defer_ok
>
> > Да вот не работает callout почему-то по LMTP.
>
> Я сам не юзаю lmtp, но гугл имеет что сказать =)
> Вот пару ссылок по теме:
> https://wiki.dovecot.org/LMTP/Exim#Verifying_recipients_using_LMTP
> https://lists.exim.org/lurker/message/20040427.231839.a37eddca.ca.html

То и беда, что гугл имеет много сказать, но не умеет (пока?) сказанное проверить.

>
> Гуглил по "exim lmtp verify recipient callout" =)

Аналогично. Откуда еще взялось мое утверждение, что callout в LMTP не работает?

Я пробовал и "use an SMTP transport ("smtp" driver), and set "protocol = lmtp"
как в другой вышеприведенной ссылке написано, но dovecot-lmtpd не нравится LHLO, ему HELO подавай.

Да и если честно, IMHO lookup по БД (даже если это просто текстовый
файл) быстрее и менее ресурсоёмок.

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

>
> > А можно я кусок своего конфига покажу, где acl и роутеры?
>
> Только если там нет контента +18 =))

Вот выложил https://termbin.com/tasy

Весь контент 18+ вырезан, в том числе комментарии (для более удобного
восприятия). Буду благодарен, если кто укажет на ошибки или предложит
улучшения.

Последовательные лукапы по двум файлам не успел слить в один лукап, но сделаю.

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Victor Sudakov

unread,
Oct 1, 2020, 12:49:23 AM10/1/20
to exim-...@mailground.net
George L. Yermulnik wrote:


>
> > А как вообще в exim потестировать condition? Ну я ему строчку, а он мне в
> > ответ yes или no (с реальными /etc/dovecot/aliases и /etc/dovecot/users
> > разумеется).
>
> Можно как-то тестить конкретные acl, но я не помню как, а в доке лень
> копаться. Можно протестить всю smtp-сессию:
> exim -d -bh какой-нить-ip-адрес

Про -bh я знаю и иногда пользуюсь, но это довольно трудоемко каждый раз
вводить MAIL FROM и прочее. Или на expect обертку писать нужно.

А вот так, чтобы ввел адрес получателя как в -bt - а оно провело его про ACL.

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Victor Sudakov

unread,
Oct 1, 2020, 1:54:28 AM10/1/20
to exim-...@mailground.net
George L. Yermulnik wrote:
>
> > > > > > А вот такие 2 условия, добавленные в acl_check_rcpt (контекст тоже привожу),
> > > > > > нормально выглядят или можно улучшить? А как бы их в одно логическое выражение
> > > > > > объединить, не подскажете?
>
> > > > > > # Accept mail for forwarded domains
> > > > > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}
>
> > > > > > # Accept valid recipient adresses in dovecot domains
> > > > > > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}
>
> > > > Хотел бы только понять синтаксис, как эти два условия объединить в ИЛИ.
>
> > [dd]
>
> > > Что-нить в таком духе:
> > > accept condition = ${or {lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}} \
> > > {lookup{$local_part@$domain}lsearch{/etc/dovecot/users}} \
> > > }
>
> > Благодарю! Хотя не вижу тут {yes} почему-то, как я привык.
>
> А он там не нужен. Даже хуже может сделать.
> В этом контексте это значение по умолчанию, которое вернёт лукап, если
> зафейлится. А он же ж должен зафелить кондишен, если строка не была
> найдена, а не вернуть "yes".

Не, в вышеприведенном виде не работает с ошибкой:

failed to expand ACL string "${or {lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}} {lookup{$local_part@$domain}lsearch{/etc/dovecot/users}} }": "${or" is not a known operator (or a } is missing in a variable reference)

Я уж попробовал и через "${if or {..." делать и всячески - не ест.
Нужна помощь клуба.

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Victor Sudakov

unread,
Oct 1, 2020, 6:13:47 AM10/1/20
to exim-...@mailground.net
Victor Sudakov wrote:
>
>
> >
> > > А как вообще в exim потестировать condition? Ну я ему строчку, а он мне в
> > > ответ yes или no (с реальными /etc/dovecot/aliases и /etc/dovecot/users
> > > разумеется).
> >
> > Можно как-то тестить конкретные acl, но я не помню как, а в доке лень
> > копаться. Можно протестить всю smtp-сессию:
> > exim -d -bh какой-нить-ip-адрес
>
> Про -bh я знаю и иногда пользуюсь, но это довольно трудоемко каждый раз
> вводить MAIL FROM и прочее. Или на expect обертку писать нужно.

Вот да, старый добрый expect не подведет.

#!/usr/bin/expect

spawn exim -d-all+acl -bh x.x.x.x
expect "220 XXXXXXXXXX.com ESMTP"
send "EHLO YYYY.ru\n"
expect "250 HELP"
send "MAIL FROM:<va...@YYYY.ru>\n"
expect "250 OK"
send "RCPT TO:<pro...@ZZZ.com>\n"
expect "250 Accepted"
interact
exit

А мог бы и на kermit написать. Поди никто уже не помнит, что это такое.

Victor Sudakov

unread,
Oct 1, 2020, 6:32:53 AM10/1/20
to exim-...@mailground.net
Victor Sudakov wrote:
>
> Нужна помощь клуба.

Пришел к такому варианту с бессчетными скобочками, но и он не работает.

accept condition = ${if or{\
{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} \
{${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} \
} {yes}}


failed to expand ACL string "${if or{{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} } {yes}}": condition name expected, but found "${lookup{$local_" inside "or{...}" condition

Гуру, подскажите работающий вариант пожалуйста.

Le...@lena.kiev.ua

unread,
Oct 1, 2020, 6:51:23 AM10/1/20
to Exim MTA на русском
> Пришел к такому варианту с бессчетными скобочками, но и он не работает.
>
> accept condition = ${if or{\
> {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} \
> {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} \
> } {yes}}

accept condition = ${if or{\

{bool{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{1}{0}}}}\
{bool{${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{1}{0}}}}\
}}

Скобочки удобно проверять во встроенном редакторе Midnight Commander.
Его можно вызвать и отдельно: mcedit имяфайла
При наведении курсора на скобочку подсвечивается другая соответствующая скобочка.

В ACL можно обойтись без {1}{0} перед самой последней скобочкой
(закрывающей or). А в роутерах надо.

George L. Yermulnik

unread,
Oct 1, 2020, 7:13:06 AM10/1/20
to exim-...@mailground.net
Hello!

On Thu, 01 Oct 2020 at 17:32:30 (+0700), Victor Sudakov wrote:

> > Нужна помощь клуба.

> Пришел к такому варианту с бессчетными скобочками, но и он не работает.

Я свой пример слишком на скорую руку сделал. Сорри.
Вот более детальный пример. Но, опять же, я не проверял в действии + могут быть ошибки синтаксиса.

condition = ${if or {\

{ eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} {yes} }\
{ eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} {yes} }\
} {yes}}

> accept condition = ${if or{\
> {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} \
> {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} \
> } {yes}}

> failed to expand ACL string "${if or{{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} } {yes}}": condition name expected, but found "${lookup{$local_" inside "or{...}" condition

> Гуру, подскажите работающий вариант пожалуйста.

--
George L. Yermulnik
[YZ-RIPE]

George L. Yermulnik

unread,
Oct 1, 2020, 7:40:38 AM10/1/20
to exim-...@mailground.net
Hello!

On Wed, 30 Sep 2020 at 19:04:03 (+0300), George L. Yermulnik wrote:

> > Благодарю! Хотя не вижу тут {yes} почему-то, как я привык.

> А он там не нужен. Даже хуже может сделать.
> В этом контексте это значение по умолчанию, которое вернёт лукап, если
> зафейлится. А он же ж должен зафелить кондишен, если строка не была
> найдена, а не вернуть "yes".

На всякий случай исправлюсь: смотрел невнимательно и почему-то мне
показалось, что {yes} возвращается, если lookup не найдёт совпадение в
файле. А сейчас перечитал и увидел, что lookup возвращает "yes", если
совпадение найдено. Прошу прощения за невнимательность.

Но само утверждение, что {yes} в данном контексте в конце не нужен,
верно, т.к. "${if" возвращает строку "true", если кондишен вернул true,
что и ожидает "condition = "

Victor Sudakov

unread,
Oct 1, 2020, 8:03:50 AM10/1/20
to exim-...@mailground.net
Le...@lena.kiev.ua wrote:
> > Пришел к такому варианту с бессчетными скобочками, но и он не работает.
> >
> > accept condition = ${if or{\
> > {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} \
> > {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} \
> > } {yes}}
>
> accept condition = ${if or{\
> {bool{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{1}{0}}}}\
> {bool{${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{1}{0}}}}\
> }}

OMG, тут что-то вроде приведения типа надо делать? Работает, очень
большое спасибо.

Я уже в попытках до такого дошел:

accept condition = ${if or {\

{eq{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}{yes}}} \
{eq{${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}{yes}}} \
} {yes}}

И всё равно не работало (интересно почему. Или уже не интересно).

>
> Скобочки удобно проверять во встроенном редакторе Midnight Commander.
> Его можно вызвать и отдельно: mcedit имяфайла
> При наведении курсора на скобочку подсвечивается другая соответствующая скобочка.

А, спасибо, мне vim хорошо подсвечивает скобочки. Даже прямо при
написании этого письма.

>
> В ACL можно обойтись без {1}{0} перед самой последней скобочкой
> (закрывающей or). А в роутерах надо.

Пусть уж будет везде единообразно.

Мне сбивает с толку мысль, что в выражении
accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}
правая часть - вполне себе condition (так и написано же - "condition" :-) ). Но
оказывается чтобы сделать AND или OR между такими conditions - надо их
обернуть в bool{...} - почему?


--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Victor Sudakov

unread,
Oct 1, 2020, 8:15:59 AM10/1/20
to exim-...@mailground.net
George L. Yermulnik wrote:
> Hello!
>
> On Thu, 01 Oct 2020 at 17:32:30 (+0700), Victor Sudakov wrote:
>
> > > Нужна помощь клуба.
>
> > Пришел к такому варианту с бессчетными скобочками, но и он не работает.
>
> Я свой пример слишком на скорую руку сделал. Сорри.
> Вот более детальный пример. Но, опять же, я не проверял в действии + могут быть ошибки синтаксиса.
>
> condition = ${if or {\
> { eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} {yes} }\
> { eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} {yes} }\
> } {yes}}

Работает вроде. Интересно, а чем же тогда мой:


accept condition = ${if or {\

{eq{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}{yes}}} \


{eq{${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}{yes}}} \
} {yes}}

не подошёл, вроде такой же по смыслу, через eq{...}. "{yes}" не там, что ли.


--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

George L. Yermulnik

unread,
Oct 1, 2020, 8:40:35 AM10/1/20
to exim-...@mailground.net
Hello!

On Thu, 01 Oct 2020 at 19:15:35 (+0700), Victor Sudakov wrote:

> > Вот более детальный пример. Но, опять же, я не проверял в действии + могут быть ошибки синтаксиса.

> > condition = ${if or {\
> > { eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}} {yes} }\
> > { eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}} {yes} }\
> > } {yes}}

> Работает вроде. Интересно, а чем же тогда мой:

> accept condition = ${if or {\
> {eq{${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}}{yes}}} \
> {eq{${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}{yes}}} \
> } {yes}}

> не подошёл, вроде такой же по смыслу, через eq{...}. "{yes}" не там, что ли.

Нет там. Я поэтому для ридабилти разделяю обычно пробелами части.
Первый "yes" - это то, что вернёт в случае удачи lookup и что будет
являться первой частью для eq, а второй "yes" - это то, с чем будет
сравниваться первый.
Т.е. в, так сказать, полной нотации это должно выглядеть так:


condition = ${if or {\

{ eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}{no}}} {yes} }\
{ eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}{no}}} {yes} }\
} {yes}{no}}

"{no}" в lookup'ах можно убрать, т.к. в данном случае не важно, что
вернёт lookup, если совпадение не найдёт (абы только не "yes").

"{yes}{no}" в конце всего кондишена тоже можно убрать, т.к. в случае
удачи if вернёт строку "true", а в случае неудачи вернёт пустую строку,
что для "condition" равноценно false.
Собственно как можно убрать только "{no}", тогда соответственно в случае
удачи вернёт "yes", а в случае неудачи - пустую строку, от чего
функциональность не изменится =)
В примере Лены yes/no|true/false заменено на 1/0 через bool, но в итоге
для exim это всё равнозначные удача/неудача.

--
George L. Yermulnik
[YZ-RIPE]

_______________________________________________

Vladimir Sharun

unread,
Oct 1, 2020, 9:01:27 AM10/1/20
to Exim MTA на русском
Привет,

Потому что сейчас девелоперы exim'а работают над соблюдением типизации.

Если раньше конструкции типа condition = {lookup} (без if) работали, то сейчас - с очень переменным успехом.

Я вот такого типа конструкции проверяю через exim -be - выпадаешь в консоль expression'ов и можно тестировать, только вместо expansion variables надо использовать живые значения. Лукапы как минимум в mysql он в консоли делает ок. Можно включить дебаг - покажет что он с чем сравнивает и почему факап.

Да, в консоли я хз что там за редактор (если он вообще есть), лучше копипастой вставлять готовые строки и enter.

вторая тема - я бы врапнул вот эти длинные лукапы в named list - легче читать

и третья тема (смое важное) - результат лукапа - это value, которое при bool сравнении всегда будет или false или true - уже не помню;
если вам надо "есть или нет" надо использовать конструкцию типа {bool{${lookup{$item}nwildlsearch{some_file}...}

Вот над этой конструкцией я потел часа два:
condition = ${if forall{<\n ${lc:${lookup dnsdb{ptr=$sender_host_address}}}} {bool{${lookup{$item}nwildlsearch{/lists/HOSTS_REGEX}{1}{0}}}}}

Тут все три секса сразу: и цикл forall, и передача $item в lookup, и приведение к boolean результата лукапа.

njoy


1 жовтня 2020, 15:04:09, від "Victor Sudakov" <v...@sibptus.ru>:

Le...@lena.kiev.ua

unread,
Oct 1, 2020, 9:49:46 AM10/1/20
to Exim MTA на русском
> Мне сбивает с толку мысль, что в выражении
> accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}
> правая часть - вполне себе condition (так и написано же - "condition" :-)

Нет, не expansion condition.

https://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html

or описано в разделе 8,
а исчерпывающий перечень expansion conditions - в разделе 7.

Igor Karpov

unread,
Oct 1, 2020, 8:11:57 PM10/1/20
to Exim MTA на русском
On 1 Oct 2020, at 13:13, Victor Sudakov wrote:

> А мог бы и на kermit написать. Поди никто
> уже не помнит, что это такое.
>
> --
> Victor Sudakov, VAS4-RIPE, VAS47-RIPN
> 2:5005/49@fidonet http://vas.tomsk.ru/

Ладно, ладно, мы еще живы. Kermit, C-Kermit, archie,
gopher... Я в случае нужды и в ed
редактировать могу.

Victor Sudakov

unread,
Oct 2, 2020, 3:24:23 AM10/2/20
to exim-...@mailground.net
Le...@lena.kiev.ua wrote:
> > Мне сбивает с толку мысль, что в выражении
> > accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}}
> > правая часть - вполне себе condition (так и написано же - "condition" :-)
>
> Нет, не expansion condition.
>
> https://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html
>
> or описано в разделе 8,

Я читал. Оно там так красиво и хорошо описано:
or {{<cond1>}{<cond2>}...}

А что условие

${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}{no}}
или


${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{1}{0}}

надо еще через bool{...} пропускать - это я не сообразил. Оно ведь и так
"yes|1" или "no|0" возвращает в зависимости от успешного или неуспешного лукапа.

> а исчерпывающий перечень expansion conditions - в разделе 7.

--

Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Victor Sudakov

unread,
Oct 2, 2020, 3:36:01 AM10/2/20
to exim-...@mailground.net
Vladimir Sharun wrote:
> Привет,
>
> Потому что сейчас девелоперы exim'а работают над соблюдением типизации.
>
> Если раньше конструкции типа condition = {lookup} (без if) работали, то сейчас - с очень переменным успехом.

То есть есть шанс, что рано или поздно и конструкция
"accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}{no}}"
работать перестанет? Надо будет везде оборачивать в bool{...} ?

>
> Я вот такого типа конструкции проверяю через exim -be - выпадаешь в консоль expression'ов и можно тестировать, только вместо expansion variables надо использовать живые значения. Лукапы как минимум в mysql он в консоли делает ок. Можно включить дебаг - покажет что он с чем сравнивает и почему факап.
>
> Да, в консоли я хз что там за редактор (если он вообще есть), лучше копипастой вставлять готовые строки и enter.

Можно на stdin ему. Я так и смотрю:
echo '${lookup{v...@XXXX.com}lsearch{/etc/dovecot/aliases}{yes}{no}}' | exim -be
потом стрелкой верх и меняю параметр.

>
> вторая тема - я бы врапнул вот эти длинные лукапы в named list - легче читать

Примерчик можно?

>
> и третья тема (смое важное) - результат лукапа - это value, которое
> при bool сравнении всегда будет или false или true - уже не помню;
> если вам надо "есть или нет" надо использовать конструкцию типа
> {bool{${lookup{$item}nwildlsearch{some_file}...}

Зачем, почему? Работает же так

root@mail3:/etc/exim4# echo 'bool{${lookup{v...@XXXX.com}lsearch{/etc/dovecot/users}{yes}{no}}}' | exim -be
> bool{yes}
>
root@mail3:/etc/exim4# echo 'bool{${lookup{va...@XXXX.com}lsearch{/etc/dovecot/users}{yes}{no}}}' | exim -be
> bool{no}


>
> Вот над этой конструкцией я потел часа два:
> condition = ${if forall{<\n ${lc:${lookup dnsdb{ptr=$sender_host_address}}}} {bool{${lookup{$item}nwildlsearch{/lists/HOSTS_REGEX}{1}{0}}}}}
>
> Тут все три секса сразу: и цикл forall, и передача $item в lookup, и приведение к boolean результата лукапа.

Для истинных поклонников sendmail.cf, чтобы не расслаблялись :-)

Victor Sudakov

unread,
Oct 2, 2020, 3:49:49 AM10/2/20
to exim-...@mailground.net
George L. Yermulnik wrote:

[dd]

> Первый "yes" - это то, что вернёт в случае удачи lookup и что будет
> являться первой частью для eq, а второй "yes" - это то, с чем будет
> сравниваться первый.
> Т.е. в, так сказать, полной нотации это должно выглядеть так:
> condition = ${if or {\
> { eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}{no}}} {yes} }\
> { eq {${lookup{$local_part@$domain}lsearch{/etc/dovecot/users}{yes}{no}}} {yes} }\
> } {yes}{no}}
>
> "{no}" в lookup'ах можно убрать, т.к. в данном случае не важно, что
> вернёт lookup, если совпадение не найдёт (абы только не "yes").
>
> "{yes}{no}" в конце всего кондишена тоже можно убрать, т.к. в случае
> удачи if вернёт строку "true", а в случае неудачи вернёт пустую строку,
> что для "condition" равноценно false.
> Собственно как можно убрать только "{no}", тогда соответственно в случае
> удачи вернёт "yes", а в случае неудачи - пустую строку, от чего
> функциональность не изменится =)
> В примере Лены yes/no|true/false заменено на 1/0 через bool, но в итоге
> для exim это всё равнозначные удача/неудача.

С bool{...} как-то стройнее и нагляднее получается, чем с eq. Он уже

В общем главный вывод для меня из этой истории - что нельзя "or" и "and"
подсовывать результат лукапа, хотя этот лукап тоже можно использоваться
(в других местах) как condition, но это не expansion condition. А
expansion conditions - только из строгого списка.

Вот про bool{} пишут, что This condition turns a string holding a true
or false representation into a boolean state. It parses “true”, “false”,
“yes” and “no” (case-insensitively); also integer numbers map to true if
non-zero, false if zero. An empty string is treated as false.

Кто им мешал "or" и "and" сделать столь же всеядными?

--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Vladimir Sharun

unread,
Oct 2, 2020, 4:59:23 AM10/2/20
to Exim MTA на русском
02 жовтня 2020, 10:36:20, від "Victor Sudakov" <v...@sibptus.ru>:

Vladimir Sharun wrote:
> Привет,
> 
> Потому что сейчас девелоперы exim'а работают над соблюдением типизации.
> 
> Если раньше конструкции типа condition = {lookup} (без if) работали, то сейчас - с очень переменным успехом.

То есть есть шанс, что рано или поздно и конструкция
"accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}{no}}"
работать перестанет? Надо будет везде оборачивать в bool{...} ?

Я бы проверил работают ли они всё еще уже сейчас :)

> 
> Я вот такого типа конструкции проверяю через exim -be - выпадаешь в консоль expression'ов и можно тестировать, только вместо expansion variables надо использовать живые значения. Лукапы как минимум в mysql он в консоли делает ок. Можно включить дебаг - покажет что он с чем сравнивает и почему факап.
> 
> Да, в консоли я хз что там за редактор (если он вообще есть), лучше копипастой вставлять готовые строки и enter.

Можно на stdin ему.  Я так и смотрю:
echo '${lookup{v...@XXXX.com}lsearch{/etc/dovecot/aliases}{yes}{no}}' | exim -be
потом стрелкой верх и меняю параметр.

> 
> вторая тема - я бы врапнул вот эти длинные лукапы в named list - легче читать

Примерчик можно?

hostlist    TRUSTED_MASSMAIL = partial2-lsearch;/lists/TRUSTED_MASSMAIL : /lists/TRUSTED_NETWORKS


Что-то типа макросов.
Потом используется (например) как
hosts = +TRUSTED_MASSMAIL
и всё понятно и нет тяжелых-длинных-непонятных конструкций
> 
> и третья тема (смое важное) - результат лукапа - это value, которое
> при bool сравнении всегда будет или false или true - уже не помню;
> если вам надо "есть или нет" надо использовать конструкцию типа
> {bool{${lookup{$item}nwildlsearch{some_file}...}

Зачем, почему? Работает же так

я bool и имел в виду. На каком-то моменте в 4.9х перестал работать мехнизм "если лукап что-то вернул - это true, а если ничего - false".

Строго говоря правая часть кондишна - это bool, а логические операции также обязаны оперировать с bool, т.е. {if or {cond1} {cond2}}, вот эти condN - это должен быть bool тоже и если нет, то факапы ойой вылазят.
> 
> Вот над этой конструкцией я потел часа два:
> condition = ${if forall{<\n ${lc:${lookup dnsdb{ptr=$sender_host_address}}}} {bool{${lookup{$item}nwildlsearch{/lists/HOSTS_REGEX}{1}{0}}}}}
> 
> Тут все три секса сразу: и цикл forall, и передача $item в lookup, и приведение к boolean результата лукапа.

Для истинных поклонников sendmail.cf, чтобы не расслаблялись :-)

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

Victor Sudakov

unread,
Oct 3, 2020, 4:00:14 AM10/3/20
to exim-...@mailground.net
Vladimir Sharun wrote:
> >
> > Потому что сейчас девелоперы exim'а работают над соблюдением типизации.
> >
> > Если раньше конструкции типа condition = {lookup} (без if) работали, то сейчас - с очень переменным успехом.
>
> То есть есть шанс, что рано или поздно и конструкция
> "accept condition = ${lookup{$local_part@$domain}lsearch{/etc/dovecot/aliases}{yes}{no}}"
> работать перестанет? Надо будет везде оборачивать в bool{...} ?
> Я бы проверил работают ли они всё еще уже сейчас :)

Работают, в моём примере было два ACL condition подряд таких и работали. Я и думал, что
можно их через "or" объединить, однако же оказалось нельзя.

И самое обидное - я же не предлагал and/or кушать результат лукапа или
пустое множество, я специально для него определил список возможных ответов: {yes}{no} и всё.

А кстати коли зашла речь, нельзя ли тут еще что-нибудь усовершенствовать в https://termbin.com/tasy ?

>
> >
> > вторая тема - я бы врапнул вот эти длинные лукапы в named list - легче читать
>
> Примерчик можно?
>
> hostlist    TRUSTED_MASSMAIL = partial2-lsearch;/lists/TRUSTED_MASSMAIL : /lists/TRUSTED_NETWORKS
>
> https://www.exim.org/exim-html-current/doc/html/spec_html/ch-domain_host_address_and_local_part_lists.html
>
> Что-то типа макросов.
> Потом используется (например) как
> hosts = +TRUSTED_MASSMAIL
> и всё понятно и нет тяжелых-длинных-непонятных конструкций

Когда приходится ссылаться на одно и то же в нескольких местах - я
польуюсь подобным, например:
domainlist dovecot_domains = dsearch;/home/vmail


> >
> > и третья тема (смое важное) - результат лукапа - это value, которое
> > при bool сравнении всегда будет или false или true - уже не помню;
> > если вам надо "есть или нет" надо использовать конструкцию типа
> > {bool{${lookup{$item}nwildlsearch{some_file}...}
>
> Зачем, почему? Работает же так
>
> я bool и имел в виду. На каком-то моменте в 4.9х перестал работать
> мехнизм "если лукап что-то вернул - это true, а если ничего - false".

> Строго говоря правая часть кондишна - это bool, а логические операции
> также обязаны оперировать с bool, т.е. {if or {cond1} {cond2}}, вот
> эти condN - это должен быть bool тоже и если нет, то факапы ойой
> вылазят.

Еще раз почитал раздел про File and database lookups, не нашёл отличий
между lsearch и nwildlsearch в плане типа возвращаемого результата. Всё
отличие вроде в возможности использовать "*" в лукапе, а результат вроде
должен одинаковый для обоих быть (то что нашли, или пусто).

Victor Sudakov

unread,
Oct 3, 2020, 4:51:03 AM10/3/20
to exim-...@mailground.net
Интересно, почему в документации "bool {<string>}" и подобные
называются expansion *conditions*, хотя по смыслу bool здесь - оператор
или функция. Берёт одни данные, возвращает другие - это оператор.

Le...@lena.kiev.ua

unread,
Oct 3, 2020, 7:34:05 AM10/3/20
to Exim MTA на русском
> Еще раз почитал раздел про File and database lookups, не нашёл отличий
> между lsearch и nwildlsearch в плане типа возвращаемого результата. Всё
> отличие вроде в возможности использовать "*" в лукапе, а результат вроде
> должен одинаковый для обоих быть (то что нашли, или пусто).

Это если нет третьего и четвертого параметров.
Если в файле нет : в каждой строке, то
то, что нашли, тоже пустое.

Если третий и четвертый есть, например {1}{0} , то в результате один из них
в зависимости от нашли или нет.

> Интересно, почему в документации "bool {<string>}" и подобные
> называются expansion *conditions*, хотя по смыслу bool здесь - оператор
> или функция. Берёт одни данные, возвращает другие - это оператор.

Нет в документации к Exim такого термина "оператор". Есть expansion items,
среди них if. Первый параметр if должен быть из перечня expansion conditions.
И в "or" тоже должны быть expansion conditions, а не что хочется.

Кроме bool, еще есть bool_lax.
Вместо bool можно использовать eq, просто bool нагляднее.

Victor Sudakov

unread,
Oct 3, 2020, 10:33:05 AM10/3/20
to exim-...@mailground.net
Le...@lena.kiev.ua wrote:
> > Еще раз почитал раздел про File and database lookups, не нашёл отличий
> > между lsearch и nwildlsearch в плане типа возвращаемого результата. Всё
> > отличие вроде в возможности использовать "*" в лукапе, а результат вроде
> > должен одинаковый для обоих быть (то что нашли, или пусто).
>
> Это если нет третьего и четвертого параметров.
> Если в файле нет : в каждой строке, то
> то, что нашли, тоже пустое.
>
> Если третий и четвертый есть, например {1}{0} , то в результате один из них
> в зависимости от нашли или нет.

То так, но я не об этом отвечал Владимиру, а том что lsearch и
nwildlsearch, как я понимаю, не отличаются в плане типа данных, который
возвращают.

>
> > Интересно, почему в документации "bool {<string>}" и подобные
> > называются expansion *conditions*, хотя по смыслу bool здесь -
> > оператор или функция. Берёт одни данные, возвращает другие - это
> > оператор.
>
> Нет в документации к Exim такого термина "оператор".

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

> Есть expansion items, среди них if.

И if у всех нормальных :-) людей - это условный оператор, а не какой-то
"item". Я не ради наезда на exim, но интересно было бы понять, зачем такая
странная терминология использована.

> Первый параметр if должен быть из перечня expansion conditions.
> И в "or" тоже должны быть expansion conditions, а не что хочется.
>
> Кроме bool, еще есть bool_lax.
> Вместо bool можно использовать eq, просто bool нагляднее.

IMHO bool удобнее, потому что универсален: it parses “true”, “false”,


“yes” and “no” (case-insensitively); also integer numbers map to true if

non-zero, false if zero. An empty string is treated as false. Leading
and trailing whitespace is ignored...

А с eq придется жестко прописывать, что чему должно быть равно?


--
Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Le...@lena.kiev.ua

unread,
Oct 3, 2020, 10:55:16 AM10/3/20
to Exim MTA на русском
> И if у всех нормальных :-) людей - это условный оператор, а не какой-то
> "item". Я не ради наезда на exim, но интересно было бы понять, зачем такая
> странная терминология использована.

Внутри eval можно некоторые операторы.
А в остальных местах есть только expansion.
В отличие от C или Perl. Зато памяти мало жрет.

Alexander Titaev

unread,
Oct 6, 2020, 2:11:13 AM10/6/20
to Exim MTA на русском
Здравствуйте, Victor.

Вы писали 1 октября 2020 г., 18:13:11:

# exim -bh 1.2.3.4 < /usr/local/etc/exim/tt.msg

# cat /usr/local/etc/exim/tt.msg
HELO mail.wangbaijia.com.tw
mail from: <yan...@eroverein.com>
rcpt to: agaf...@irgiredmet.ru
data
Received: from localhost (localhost [127.0.0.1])
by mail.wangbaijia.com.tw (Postfix) with ESMTP id 69DA01A53ED;
Thu, 1 Feb 2018 15:35:58 +0800 (CST)
...
.
#

>> Про -bh я знаю и иногда пользуюсь, но это довольно трудоемко каждый раз
>> вводить MAIL FROM и прочее. Или на expect обертку писать нужно.

> Вот да, старый добрый expect не подведет.

> #!/usr/bin/expect

> spawn exim -d-all+acl -bh x.x.x.x
> expect "220 XXXXXXXXXX.com ESMTP"
> send "EHLO YYYY.ru\n"
> expect "250 HELP"
> send "MAIL FROM:<va...@YYYY.ru>\n"
> expect "250 OK"
> send "RCPT TO:<pro...@ZZZ.com>\n"
> expect "250 Accepted"
> interact
> exit

> А мог бы и на kermit написать. Поди никто уже не помнит, что это такое.


--
С уважением,
Alexander mailto:t...@irk.ru

Victor Sudakov

unread,
Oct 6, 2020, 3:42:43 AM10/6/20
to exim-...@mailground.net
Привет, Alexander!

Я не знал, что в режиме -bh можно не дожидаться ответов от exim. Думал
тут всё как в настоящей SMTP сессии.

--

Victor Sudakov, VAS4-RIPE, VAS47-RIPN
2:5005/49@fidonet http://vas.tomsk.ru/

_______________________________________________

Reply all
Reply to author
Forward
0 new messages