Exim и ограничения при отправке почты

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

Модератор: xM

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
wein72
рядовой
Сообщения: 14
Зарегистрирован: 2008-06-16 10:04:32

Exim и ограничения при отправке почты

Непрочитанное сообщение wein72 » 2008-06-16 10:18:51

Доброго времени суток!

Вот возникла задачка такая: есть почтовый сервер с mta exim (база юзеров в mysql), на нём необходимо сделать так, чтобы одни пользователи могли отсылать почту куда угодно, а другие - лишь в пределах локального домена. Всё усложняется тем, что только часть клиентов находится в одной локальной сети с сервером. Остальные цепляются к нему с инета с одного фиксированного ip-адреса.
Идея такая: в таблице users, где хранятся данные об акаунтах, я создал ещё одно доп. поле relay. Полагается сделать так, чтобы почту отправлять во внешний мир могли только пользователи, для которых relay=1.
Собственно вопрос: откуда плясать? Мануалы читал, но что-то просветление не настало :(
Пробовал в acl_check_rcpt завязать при помощи endpass дополнительное условие к accept autenthicated, но что-то не попёрло, либо я lookup неправильно построил, либо идея в корне не верна была :-)
В общем, научите как надо, люди добрые! Заранее благодарствую.

С уважением, Алексей.

Хостинговая компания 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: Exim и ограничения при отправке почты

Непрочитанное сообщение dikens3 » 2008-06-16 10:29:08

Ты всё верно мыслишь, только недоконца.

1. Определиться, как отличать всех своих пользователей. (Лучше наверное аутентификацией абсолютно для всех, и пускай бегают как хотят)
2. Разрешить отправку почты куда угодно аутентифицированным у которых relay = 1.

Всё.

Кратко acl_smtp_rcpt выглядит так:

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

acl_check_rcpt:

# Принимаем почту пришедшую не по TCP/IP, localhost имеется ввиду
  accept  hosts = :

# Принимаем аутентифицированных для внешних доменов
  accept    authenticated = *
            !domains       = +local_domains
            + тут проверка на relay = 1

# Принимаем письма для нашего домена
  accept    domains       = +local_domains
            endpass
            message       = "Unknown user"
            verify        = recipient

# Остальных прибиваем
  deny     message       = relay not permitted
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

wein72
рядовой
Сообщения: 14
Зарегистрирован: 2008-06-16 10:04:32

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение wein72 » 2008-06-16 10:59:27

1. Определиться, как отличать всех своих пользователей. (Лучше наверное аутентификацией абсолютно для всех, и пускай бегают как хотят)
Ну так я и думаю примерно. Т.е. аутентификация для всех абсолютно, а после проверка на relay=1 из базы
2. Разрешить отправку почты куда угодно аутентифицированным у которых relay = 1.
а вот тут вопрос: а что будет с аутентифицированными, у которых relay<>1? ;-) они по идее должны иметь право слать почту только адресатам из локального домена

Мой alc сейчас выглядит вот так (это в принципе дефолтовый конфиг из virtual exim):

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

acl_check_rcpt:

  accept  hosts = :

  # Include Vexim specific rcpt ACLs
  .include /usr/local/exim/vexim-acl-check-rcpt.conf
  #  тут ничего особенного, лишь список dns blacklists

  deny    local_parts   = ^.*[@%!/|] : ^\\.
  accept  local_parts   = postmaster
          domains       = +local_domains
  accept  domains       = +local_domains
          endpass
          verify        = recipient
  accept  domains       = +relay_to_domains
          endpass
          verify        = recipient
  accept  hosts         = +relay_from_hosts

# вот тут я экспериментировал, пробуя различные условия, раскоментируя различные комбинации, но в итоге ничего не заработало :-(

#  accept  authenticated = *
#  endpass 
#  accept  condition = ${lookup mysql{SELECT username FROM users WHERE relay = 1}{yes}{no}}
#  accept  condition     = ${if match{lookup mysql{select relay from users where username="$sender_address"}}{1}{yes}{no}}
#  accept  condition     = ${lookup mysql {SELECT relay FROM users WHERE username=$sender_address}{1}{yes}{no}}
#  endpass
#  accept  authenticated = *
#  endpass
#  accept  condition     = ${if match{lookup mysql{select relay from users where username="$sender_address"}}={"1"}{yes}{no}}
#  accept  condition     = ${if eq {${lookup mysql{select relay from users where username="$sender_address"}{"1"}{yes}{no}}
#  endpass

  accept  authenticated = *  
  deny    message       = relay not permitted
Вот как условие прописать правильно - я заступорился честно говоря :(

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

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение dikens3 » 2008-06-16 12:22:09

Вот как условие прописать правильно - я заступорился честно говоря
Я делаю так.
1. Составляю сами запросы (Они у меня в отдельном файле):

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

# Полная квота почтового ящика
MYSQL_QUOTA             = SELECT `quota-max` FROM users WHERE username='${quote_mysql:$local_part}' LIMIT 1
DEFAULT_QUOTA_LIMIT     = 25M

# Системные пользователи, им почту посылать нельзя
MYSQL_SYSTEM_USERS      = SELECT dst_username FROM aliases WHERE dst_username='${quote_mysql:$local_part}' AND active='S' LIMIT 1

# Список доменов
MYSQL_DOMAINS           = SELECT domain FROM domains WHERE domain='${quote_mysql:$domain}' AND active='Y' LIMIT 1

# Список алиасов
MYSQL_ALIASES           = SELECT recipient FROM aliases WHERE dst_username='${quote_mysql:$local_part}' AND active!='N' LIMIT 1
2. Далее в acl_smtp_rcpt я выполняю запрос и загоняю результат в переменную:

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

set acl_m19  = ${lookup mysql{MYSQL_SYSTEM_USERS}}
3. И затем работаю с этой переменной.

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

condition     = ${if eq{$acl_m19}{1}{yes}{no}}
4. В итоге у тебя получается примерно следующее:

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

# Принимаем аутентифицированных для внешних доменов
  accept    authenticated = *
            !domains       = +local_domains
            set acl_m19  = ${lookup mysql{MYSQL_RELAY_USERS}}
            condition     = ${if eq{$acl_m19}{1}{yes}{no}}
Желательно именно в таком порядке, чтобы зря базу mysql не гонять. Только для аутентифицированных и при отправке во внешний мир произойдёт запрос к базе и значение отправится в acl_m19, которое и будет сравниваться с 1 (единицей).
а вот тут вопрос: а что будет с аутентифицированными, у которых relay<>1? ;-) они по идее должны иметь право слать почту только адресатам из локального домена
Просто блок (который я привёл чёть выше) несработает и действие перейдёт к следующему блоку, в котором произойдёт приём письма для твоего домена.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

wein72
рядовой
Сообщения: 14
Зарегистрирован: 2008-06-16 10:04:32

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение wein72 » 2008-06-17 6:45:52

В итоге у тебя получается примерно следующее:

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

# Принимаем аутентифицированных для внешних доменов
  accept    authenticated = *
            !domains       = +local_domains
            set acl_m19  = ${lookup mysql{MYSQL_RELAY_USERS}}
            condition     = ${if eq{$acl_m19}{1}{yes}{no}}
Желательно именно в таком порядке, чтобы зря базу mysql не гонять. Только для аутентифицированных и при отправке во внешний мир произойдёт запрос к базе и значение отправится в acl_m19, которое и будет сравниваться с 1 (единицей).
Ну общую мыслю я понял вроде твою. Только теперь бы ещё запрос сформировать правильно :-) Вот смотри, таблица users, в ней поле relay (0 или 1). Как будет выглядеть запрос для MYSQL_RELAY_USERS примерно?

Кстати, нагрузка на базу не критична в моем случае :-) Тама 10-15 юзеров всего в почте и сервак мощный весьма.

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

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение dikens3 » 2008-06-17 8:59:13

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

MYSQL_RELAY_USERS = select relay from users where user = '${quote_mysql:$local_part}' LIMIT 1
примерно так, только потребуется ещё одно поле, в котором содержатся имена пользователей без домена? Я его назвал user.

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

wein72
рядовой
Сообщения: 14
Зарегистрирован: 2008-06-16 10:04:32

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение wein72 » 2008-06-17 12:07:14

dikens3 писал(а):

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

MYSQL_RELAY_USERS = select relay from users where user = '${quote_mysql:$local_part}' LIMIT 1
примерно так, только потребуется ещё одно поле, в котором содержатся имена пользователей без домена? Я его назвал user.
Ну у меня есть такое поле по умолчанию, называется localpart.
Для составления запроса требуется 2-а поля. relay + то, в котором хранятся пользователи + как именно хранятся пользователи (с доменом или без)
А это так принципиально как они хранятся? У меня есть там 2 поля: localpart и username. В первом только имена без доменов, во втором - полное имя с доменом соответственно.
Получается для моего случая необходимо добавить в конфиг следующее:

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

MYSQL_RELAY_USERS = select relay from users where localpart = '${quote_mysql:$local_part}' LIMIT 1 
# или всё же тут вместо localpart использовать username?

# ну и добавить в конец acl
accept    authenticated = *
            !domains       = +local_domains
            set acl_m19  = ${lookup mysql{MYSQL_RELAY_USERS}}
            condition     = ${if eq{$acl_m19}{1}{yes}{no}}
Примерно так?

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

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение dikens3 » 2008-06-17 14:04:09

Не в конец, а в начало. Млин ну думай уже, вверху всё описано очень доходчиво. Перечитай и подумай.

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

wein72
рядовой
Сообщения: 14
Зарегистрирован: 2008-06-16 10:04:32

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение wein72 » 2008-06-25 14:11:40

dikens3 писал(а):Не в конец, а в начало. Млин ну думай уже, вверху всё описано очень доходчиво. Перечитай и подумай.
Перечитал. Подумал. Что-то не хочет всё равно :st: При таком раскладе говорит что релей закрыт в любом случае, независимо от значения поля relay.

Получил я вот такой конфиг:

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

#добавил к прочим запросам вот этот
RELAY_USERS = SELECT relay FROM users WHERE localpart = '${quote_mysql:$local_part}' LIMIT 1
#тут localpart - имя пользователя без домена, есть в таблице такое отдельным полем
Запрос верный видимо, проверял в мускле - похоже возвращает как надо всё:

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

mysql> SELECT relay FROM users WHERE localpart = 'test' LIMIT 1;
+-------+
| relay |
+-------+
| 1     |
+-------+
1 row in set (0.00 sec)
Это для пользователя test, у которого relay=1.

ACL выглядел вот так:

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

acl_check_rcpt:

  accept  hosts = :

  # Include Vexim specific rcpt ACLs
  .include /usr/local/exim/vexim-acl-check-rcpt.conf

  deny    local_parts   = ^.*[@%!/|] : ^\\.
  accept  local_parts   = postmaster
          domains       = +local_domains
  accept  authenticated = *
	  !domains = +local_domains
	  set acl_m19  = ${lookup mysql{RELAY_USERS}}
	  condition = ${if eq{$acl_m19}{1}{yes}{no}}
  accept  domains       = +local_domains
          endpass
          verify        = recipient
  accept  domains       = +relay_to_domains
          endpass
          verify        = recipient
  accept  hosts         = +relay_from_hosts
  deny    message       = relay not permitted
В include ничего кроме списка dns-блэклистов нету.

Где что я опять делаю не так? :(

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

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение dikens3 » 2008-06-25 14:56:35

Лог где?

Скорее всего пользователь не аутентифицировался.

Есть ещё например такое действие logwrite = :panic: $acl_m19

Использовать так:

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

  accept  authenticated = *
     !domains = +local_domains
     set acl_m19  = ${lookup mysql{RELAY_USERS}}
     logwrite = :panic: "значение m19: $acl_m19"
     condition = ${if eq{$acl_m19}{1}{yes}{no}}
Как только дойдёт до logwrite в paniclog будет переменная $acl_m19
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

wein72
рядовой
Сообщения: 14
Зарегистрирован: 2008-06-16 10:04:32

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение wein72 » 2008-06-26 9:04:08

dikens3 писал(а):Лог где?

Скорее всего пользователь не аутентифицировался.
Естественно не аутентифицировался ибо сообщает:

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

2008-06-26 10:26:28 H=(admin) [192.168.1.10] F=<test@xx.ru> rejected RCPT <wein72@gm__l.com>: relay not permitted
Есть ещё например такое действие logwrite = :panic: $acl_m19
Да, похоже переменная пустая :(

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

2008-06-26 10:26:28 "value of m19: "

Т.е. видимо затык где-то тут:

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

RELAY_USERS = SELECT relay FROM users WHERE localpart = '${quote_mysql:$local_part}' LIMIT 1
Получается что если запрос вида:

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

mysql> SELECT relay FROM users WHERE localpart = 'test' LIMIT 1;
возвращает то, что надо, то грабли где-то в этой части?

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

localpart = '${quote_mysql:$local_part}' LIMIT 1
Точно запрос то верный тогда? У меня localpart - это имя пользователя БЕЗ доменной части.

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

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение dikens3 » 2008-06-26 10:07:16

зафискируй весь запрос и всё узнаешь.

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

accept  authenticated = *
        !domains = +local_domains
        logwrite = :panic: "Мой запрос будет: RELAY_USERS"
        set acl_m19  = ${lookup mysql{RELAY_USERS}}
        condition = ${if eq{$acl_m19}{1}{yes}{no}}
Потом то, что будет в логе выполни руками в mysql.
Лучше установить FreeBSD, чем потратить 30 лет на Linux'ы и выяснить какой из них хуже.

wein72
рядовой
Сообщения: 14
Зарегистрирован: 2008-06-16 10:04:32

Re: Exim и ограничения при отправке почты

Непрочитанное сообщение wein72 » 2008-06-26 11:07:13

Всё заработало!
Правильный запрос к базе выглядит так:

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

RELAY_USERS = SELECT relay FROM users WHERE username = '${quote_mysql:$authenticated_id}' LIMIT 1
Надо отметить, что username - это полное имя пользователя С ДОМЕНОМ.
Ну и сам ACL в принципе без изменений, первым условием идёт:

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

  accept  authenticated = *
	  !domains = +local_domains
	  set acl_m19  = ${lookup mysql{RELAY_USERS}}
	  condition = ${if eq{$acl_m19}{1}{yes}{no}}
Моё огромное человеческое спасибо товарисчу dikens3!