Не работают whilelist

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

Модератор: xM

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Не работают whilelist

Непрочитанное сообщение princeps » 2008-04-14 16:48:19

В прикрепленной теме "Полезные скрипты и настройки для Exim" в посте про вайт-листы есть такой текст:

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

warn      set acl_m3    = ${lookup mysql{MYSQL_DOMAINS}}
      set acl_m4    = $local_part
      set acl_m5    = $domain 
А макрос MYSQL_DOMAINS нигде до этого не определен, в результате чего экзим при загрузке ругается на неправильный SQL-запрос. Это ошибка или я чего-то пропустил? Я с Exim недавно, и в синтаксисе конфига пока разбираюсь со скрипом, поэтому помогите понять, в чем дело. Я наугад поставил туда MYSQL_TESTCLIENTMYLIST, может ли у меня поэтому в бд в поле dst_email писаться просто "@" без локальной части и имени домена? Или это какие-то проблемы с присвоением значений set acl_m4 и set acl_m4?
Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

Хостинговая компания 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/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение dikens3 » 2008-04-14 20:18:34

А макрос MYSQL_DOMAINS нигде до этого не определен, в результате чего экзим при загрузке ругается на неправильный SQL-запрос. Это ошибка или я чего-то пропустил?
Завтра добавлю в скрипты и тебе отпишусь сюда.
Я наугад поставил туда MYSQL_TESTCLIENTMYLIST, может ли у меня поэтому в бд в поле dst_email писаться просто "@" без локальной части и имени домена?
Нет, т.к. данный запрос (SELECT ... ) никаких изменений в базе данных не производит.
Или это какие-то проблемы с присвоением значений set acl_m4 и set acl_m5?
Не знаю.. Вполне может быть.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение princeps » 2008-04-14 20:28:16

dikens3 писал(а):Нет, т.к. данный запрос (SELECT ... ) никаких изменений в базе данных не производит.
]
Он не производит, да. Но его результат присваивается acl_m3, которая потом сравнивается с acl_m19 и на основании этого вносятся изменения в базу - это если я правильно все понял в конфиге. Вот я думаю, может быть тут где-то оно влияет.
Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение dikens3 » 2008-04-15 11:18:07

Поправил:

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

MYSQL_DOMAINS           = SELECT domain FROM domains WHERE domain='${quote_mysql:$domain}' AND active='Y' LIMIT 1

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

warn
          authenticated = *
          set acl_m19   = ${lookup mysql{MYSQL_TESTMYLIST}{$value}{0}}
Тут в переменной m19 окажется некое значение (зависит от результата запроса)
Выглядит в работе так:

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

mysql> SELECT CASE WHEN now() - record_expires > 0 THEN 2 ELSE 1 END FROM mylist WHERE src_email='user@domain.ru' AND dst_email='user@bk.ru';
+--------------------------------------------------------+
| CASE WHEN now() - record_expires > 0 THEN 2 ELSE 1 END |
+--------------------------------------------------------+
|                                                      2 |
+--------------------------------------------------------+
1 row in set (0.00 sec)
Тут смысл условия поиска такой - искать записи по некоторым критериям. Если записи найдены и соответствуют реалиям (10 дней не прошло), тогда 2, иначе 1. А если записей вообще нет, тогда возвращается 0 (нуль).

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

# Если существует, изменяем поле record_expire
warn
          authenticated = *
          condition     = ${if and {{eq{$acl_m3}{}}{!eq{$acl_m19}{0}}}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_UPDATEMYLIST}}
Здесь двойная проверка.
1. Сравнение acl_m3 с пустым значением (Оно будет пустое, т.к. warn set acl_m3 = ${lookup mysql{MYSQL_DOMAINS}} его таким сделает, если письмо будет не для нашего домена). Тупо проверка для нашего домена письмо или нет?
2. Проверка чтобы acl_m19 было не равно 0 (нулю)
3. Обновление записи, если выполнены первые два условия.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение princeps » 2008-04-15 13:39:01

Спасибо, поменял. Проблема, действительно, не решилась :) - в dst_email пишется просто собака, видимо переменные не присваиваются. Помогите разобраться в чем дело. У меня есть подозрения, что я куда-то не туда или не в той последовательности сунул настройки из темы про вайт-листы. Вот ниже мой acl_smtp_rcpt:

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

# Эти правила срабатывают для каждого получателя
acl_check_rcpt:

  # устанавливаем переменныя для белого списка
warn      set acl_m3    = ${lookup mysql{MYSQL_TESTCLIENTMYLIST}}
             set acl_m4    = $local_part
             set acl_m5    = $domain

  accept  hosts = :
  deny    message       = "Недопустимые символы в адресе"
          domains       = +local_domains
          local_parts   = ^[.] : ^.*[@%!/|]

  deny    message       = "Недопустимые символы в адресе"
          domains       = !+local_domains
          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./

  accept  local_parts   = postmaster
          domains       = +local_domains

  require verify        = sender

  deny    message       = "HELO/EHLO обязано быть по SMTP RFC"
          condition     = ${if eq{$sender_helo_name}{}{yes}{no}}

  # Принимаем сообщения от тех, кто аутентифицировался
  accept  authenticated = *
          domains       = +local_domains
          endpass
          message       = "Неизвестный пользователь"
          verify        = recipient

# Проверяем, существует ли домен получателя
  deny     log_message   = "Получателя не существует"
           authenticated = *
           !verify        = recipient

# Белые списки:
# Для наших пользователей записываем наш $sender_address и адрес получателя($lo
# Существуют записи для данной пары src-dst email? Если нет, вернёт 0.
warn
          authenticated = *
          set acl_m19   = ${lookup mysql{MYSQL_TESTMYLIST}{$value}{0}}

# Белые списки:
# Если существует, изменяем поле record_expire
warn
          authenticated = *
          condition     = ${if and {{eq{$acl_m3}{}}{!eq{$acl_m19}{0}}}{yes}{no}
          set acl_m19   = ${lookup mysql{MYSQL_UPDATEMYLIST}}
# Белые списки:
# Если не существует такой записи, добавляем в базу.
warn
          authenticated = *
          condition     = ${if and {{eq{$acl_m3}{}}{eq{$acl_m19}{0}}}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_WHITELIST}}

# Рубаем нах, тех, кто подставляет свой IP в HELO
  deny    message       = "Не надо пихать свой IP в качестве HELO!"
          hosts         =  *:!+relay_from_hosts
          condition     = ${if eq{$sender_helo_name}\
                          {$sender_host_address}{true}{false}}

# Рубаем тех, кто в HELO пихает мой IP 
  deny    condition     = ${if eq{$sender_helo_name}\
                          {$interface_address}{yes}{no}}
          hosts         = !127.0.0.1 : !localhost : *
          message       = "Это мой IP-адрес! Пшёл прочь!"

# Рубаем тех, кто в HELO пихает только цифры
  deny    condition     = ${if match{$sender_helo_name}\
                          {\N^\d+$\N}{yes}{no}}
          hosts         = !127.0.0.1:!localhost:*
          message       = "В HELO не могут быть тока цифры!"

  # Рубаем хосты типа *adsl*; *dialup*; *pool*;....
  deny    message       = "Не нравится мне Ваш хост..."
          condition     = ${if match{$sender_host_name} \
                               {adsl|dialup|pool|peer|dhcp} \
                               {yes}{no}}
  # Рубаем тех, кто в блэк-листах.
  deny    message       = "Ваш адрес в блэклисте - $dnslist_domain \n $dnslist_
          dnslists      = opm.blitzed.org : \
                          proxies.blackholes.easynet.nl : \
                          cbl.abuseat.org : \
                          bl.spamcop.net : \
                          bl.csma.biz : \
                          dynablock.njabl.org : \

  # Задержка.
  warn
        # ставим дефолтовую задержку в 20 секунд
        set acl_m0 = 15s
  warn
        # ставим задержку в 0 секунд своим хостам и
        # дружественным сетям (соседняя контора :))
        hosts = +relay_from_hosts : spaceweb.ru
        set acl_m0 = 0s
  warn
        # пишем в логи задержку (если оно вам надо)
        logwrite = Delay $acl_m0 for $sender_host_name \
        [$sender_host_address] with HELO=$sender_helo_name. Mail \
        from $sender_address to $local_part@$domain.
        delay = $acl_m0

  # Проверка получателя в локальных доменах.
  accept  domains       = +local_domains
          endpass
          message       = "В этом домене нет такого пользователя"
          verify        = recipient

  # Проверяем получателя в релейных доменах
  accept  domains       = +relay_to_domains
          endpass
          endpass
          message       = "В этом домене нет такого пользователя"
          verify        = recipient

  # Проверяем получателя в релейных доменах
  accept  domains       = +relay_to_domains
          endpass
          message       = "Моя сервера не знать маршрут на этот хост..."
          verify        = recipient

  # Разрешаем почту от доменов в списке relay_from_hosts
  accept  hosts         = +relay_from_hosts

# Белые списки
  warn      set acl_m19  = ${lookup mysql{MYSQL_TESTCLIENTMYLIST}{$value}{0}}

  accept    domains       = +local_domains
            condition     = ${if eq{$acl_m19}{1}{yes}{no}}
            endpass
            message       = "Неизвестный пользователь"
            verify        = recipient
# Белые списки
warn
          set acl_m19   = ${substr{6}{4}{$tod_zulu}}
          condition     = ${if eq{$acl_m19}{0112}{yes}{no}}
          set acl_m19   = ${lookup mysql{MYSQL_DELMYLISTEXPIRED}}

  # Если неподошло ни одно правило - чувак явно ищет
  # открытый релей. Пшёл прочь. :)
  deny    message       = "Свободен. Это тебе не ОпенРелей."

Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение dikens3 » 2008-04-15 13:57:25

Да нормально вроде как. (acl_m3 ты справить должен был)

есть такое действие logwrite, используется примерно так:

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

warn
       logwrite = :panic: "Переменная acl_m3: $acl_m3"
Можешь погонять и посмотреть где, что и как.

И ещё, прогони вот такую конструкцию и посмотри:

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

#!/bin/sh

# Тестирование от mail.ru
(echo "EHLO mxs.mail.ru"; echo "MAIL FROM:user@mail.ru"; echo "RCPT TO: user@mydomain.ru"; echo "DATA"; echo "Subject: test"; echo "."; echo "QUIT";) | exim -d -bhc 194.67.23.20 > testlog 2>&1
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение princeps » 2008-04-15 17:15:58

dikens3 писал(а):warn
logwrite = :panic: "Переменная acl_m3: $acl_m3"
Вставил в конфиг до и после присвоения значений переменной. Вот так:

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

warn
       logwrite = :panic: "Переменная acl_m4: $acl_m4"

  # устанавливаем переменныя для белого списка
warn      set acl_m3    = ${lookup mysql{MYSQL_DOMAINS}}
          set acl_m4    = $local_part
          set acl_m5    = $domain
warn
       logwrite = :panic: "Переменная acl_m4: $acl_m4"
В результате в panic_log свалилась куча записей такого содержания:

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

2008-04-15 16:05:44 "\360\305\322\305\315\305\316\316\301\321 acl_m4: "
Т.е., как я понимаю, ни до, ни после set acl_m4 = $local_part ей не было присвоено никакого значения. Почему, черт возьми, такое происходит? Тут же нету никаких условий, просто надо присвоить значение переменной и все :(. Может я где лишний пробел поставил или табуляцию?
Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

princeps
майор
Сообщения: 2684
Зарегистрирован: 2007-09-25 10:20:59
Откуда: Сочи, Москва
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение princeps » 2008-04-15 17:37:28

Все! Разобрался! Помог магический скрипт от mail.ru, который в какой-то момент выдал следующее:

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

processing "warn"
search_open: mysql "NULL"
search_find: file="NULL"
  key="SELECT domain FROM domains WHERE domain='mail.mydomain.ru' AND active='Y' LIMIT 1" partial=-1 affix=NULL star
LRU list:
internal_search_find: file="NULL"
  type=mysql key="SELECT domain FROM domains WHERE domain='mail.mydomain.ru' AND active='Y' LIMIT 1"
database lookup required for SELECT domain FROM domains WHERE domain='mail.mydomain.ru' AND active='Y' LIMIT 1
MySQL query: SELECT domain FROM domains WHERE domain='mail.mydomain.ru' AND active='Y' LIMIT 1
MYSQL new connection: host=localhost port=0 socket=NULL database=exim user=exim
MYSQL: query failed: Table [b]'exim.domains' doesn't exist[/b]

lookup deferred: MYSQL: query failed: [b]Table 'exim.domains' doesn't exist[/b]

warn: condition test deferred
LOG: MAIN

В самом деле, я не став разбираться в определение макроса, просто скопипастил его в в свой конфиг. А у меня эта таблица в единственном числе - domain. Соответственно условие не работало и следующие команды утверждения warn не выполнялись. По этому поводу в документации экзима прочитал следующее:
Если любое условие в утверждении “warn” не может быть завершено (т.е. своего рода отсрочка), строки заголовков не добавляются, и сконфигурированные строки логов не записываются. Никакие дальнейшие условия или модификаторы в утверждении “warn” не обрабатываются. Инцидент логгируется, но ACL продолжает обрабатываться, со следующего утверждения.
Т.е., получается, что изначально причиной того, что конфиг не работал, было неправильное указание MYSQL_DOMAINS. Дикенс, большое спасибо за помощь, может быть, осенью буду в Нижнем, как что - с меня пиво ;).
Deus quos vult perdere dementat prius
http://www.itforum-sochi.ru

Аватара пользователя
dikens3
подполковник
Сообщения: 4856
Зарегистрирован: 2006-09-06 16:24:08
Откуда: Нижний Новгород
Контактная информация:

Re: Не работают whilelist

Непрочитанное сообщение dikens3 » 2008-04-15 19:09:45

Да ладно.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.