Страница 1 из 1
Exim и ограничения при отправке почты
Добавлено: 2008-06-16 10:18:51
wein72
Доброго времени суток!
Вот возникла задачка такая: есть почтовый сервер с mta exim (база юзеров в mysql), на нём необходимо сделать так, чтобы одни пользователи могли отсылать почту куда угодно, а другие - лишь в пределах локального домена. Всё усложняется тем, что только часть клиентов находится в одной локальной сети с сервером. Остальные цепляются к нему с инета с одного фиксированного ip-адреса.
Идея такая: в таблице users, где хранятся данные об акаунтах, я создал ещё одно доп. поле relay. Полагается сделать так, чтобы почту отправлять во внешний мир могли только пользователи, для которых relay=1.
Собственно вопрос: откуда плясать? Мануалы читал, но что-то просветление не настало
Пробовал в acl_check_rcpt завязать при помощи endpass дополнительное условие к accept autenthicated, но что-то не попёрло, либо я lookup неправильно построил, либо идея в корне не верна была :-)
В общем, научите как надо, люди добрые! Заранее благодарствую.
С уважением, Алексей.
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-16 10:29:08
dikens3
Ты всё верно мыслишь, только недоконца.
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
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-16 10:59:27
wein72
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
Вот как условие прописать правильно - я заступорился честно говоря

Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-16 12:22:09
dikens3
Вот как условие прописать правильно - я заступорился честно говоря
Я делаю так.
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. И затем работаю с этой переменной.
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?

они по идее должны иметь право слать почту только адресатам из локального домена
Просто блок (который я привёл чёть выше) несработает и действие перейдёт к следующему блоку, в котором произойдёт приём письма для твоего домена.
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-17 6:45:52
wein72
В итоге у тебя получается примерно следующее:
Код: Выделить всё
# Принимаем аутентифицированных для внешних доменов
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 юзеров всего в почте и сервак мощный весьма.
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-17 8:59:13
dikens3
Код: Выделить всё
MYSQL_RELAY_USERS = select relay from users where user = '${quote_mysql:$local_part}' LIMIT 1
примерно так, только потребуется ещё одно поле, в котором содержатся имена пользователей без домена? Я его назвал user.
Для составления запроса требуется 2-а поля. relay + то, в котором хранятся пользователи + как именно хранятся пользователи (с доменом или без)
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-17 12:07:14
wein72
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}}
Примерно так?
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-17 14:04:09
dikens3
Не в конец, а в начало. Млин ну думай уже, вверху всё описано очень доходчиво. Перечитай и подумай.
P.S. Mysql запрос верный. (можно проверить руками зайдя в mysql)
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-25 14:11:40
wein72
dikens3 писал(а):Не в конец, а в начало. Млин ну думай уже, вверху всё описано очень доходчиво. Перечитай и подумай.
Перечитал. Подумал. Что-то не хочет всё равно

При таком раскладе говорит что релей закрыт в любом случае, независимо от значения поля 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-блэклистов нету.
Где что я опять делаю не так?

Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-25 14:56:35
dikens3
Лог где?
Скорее всего пользователь не аутентифицировался.
Есть ещё например такое действие 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
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-26 9:04:08
wein72
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
Да, похоже переменная пустая
Т.е. видимо затык где-то тут:
Код: Выделить всё
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 - это имя пользователя БЕЗ доменной части.
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-26 10:07:16
dikens3
зафискируй весь запрос и всё узнаешь.
Код: Выделить всё
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.
Re: Exim и ограничения при отправке почты
Добавлено: 2008-06-26 11:07:13
wein72
Всё заработало!
Правильный запрос к базе выглядит так:
Код: Выделить всё
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!