[Карта]                [Начало]                [Sendmail-ссылки]                [Синтаксис]                [Типовые задачки]                  [Задачки по маршрутизации]                  [Задачки по маcкарадингу]                  [SendmailACL]                  [Spamooborona]                  [VadeRetro]                  [Regex]                  [Тонкости]                  [Недок.особен.]                  [Несущ.юзеры]                  [Прячемся!]                  [RFC1893.Цитаты]                  [ТП.Эмоции]                  [Антиспам&Разум]                  [Экзерсисы]                 


Владивостоку посвящается ...
Sendmail ACL


Итак, то, о чем меня так часто спрашивали, и до чего никак не доходили руки - Sendmail Access Control List.
Посвящаю это решение первому человеку, кто об этом спросил давным-давно, замечательному и удивительному человеку ... и его не менее замечательному городу Владивостоку ... Хотя ему это решение в конце концов не понадобилось ... Но ни для кого другого SendmailACL я делать бы не стала.

Перловый скрипт от Askon для тестирования (perl-parser for rules).
Первоначальная постановка задачи от Askon на sysadmins.ru, на comp.mail.sendmail (English), блок-схема explain.jpg.
Составляющие решения: Советую обратить внимание на эти два решения ([1], [2]), возможно, это то, что нужно именно вам.
Так как мой набор правил получился довольно тяжеловесным, то такие простые одиночные задачи, как
- запрет приема внешней почты, подписанной вашим доменом ([1]),
- ограничение в правах пользователя ([1], [2], [3], [4] ),
- ограничение локальной перепиской группы пользователей ([1]),
лучше решать по простому.

Итак, нам понадобятся два файла (/etc/mail/allow & /etc/mail/deny) с правами локальных пользователей и по необходимости файлы почтовых групп.
Каждая строка этих файлов состоит из 4 компонентов:
1. метки From: или To: в зависимости от того, отправляет или получает _локальный_ пользователь почту
2. имени локального пользователя или локальной группы или локального алиаса или
авторизационного имени, указанного юзером в настройках почтовой программы в smtp-авторизации
3. внешнего получателя или отправителя
4. разрешения на получение почты (ALLOW) или запрещения (DENY) (табуляция перед словом обязательна)

Если вы выберете политику "все, что не запрещено - разрешено", то в файле /etc/mail/allow нужно перечислить разрешенные пары локальный пользователь:внешний получатель(отправитель), которые являются исключениями из запрещенных пар, соответственно в /etc/mail/deny - _все_ запрещенные пары.
При этом локальным пользователям, не упомянутым в DENY, по умолчанию будет разрешено общение с любым адресом.

Если вы выберете политику "все, что не разрешено - запрещено", то в файле /etc/mail/allow нужно перечислить _все_ разрешенные пары локальный пользователь:внешний получатель(отправитель), соответственно в /etc/mail/deny - запрещенные пары, которые являются исключениями из разрешенных пар.
При этом локальным пользователям, не упомянутым в ALLOW, по умолчанию будет запрещено общение с кем бы то ни было.

Вне зависимости от выбранной политики локальная почта (от локального юзера - локальному) будет доставляться всегда.
Локальность почты для отправителя определяется либо по ip-адресу (ip прописан в /etc/mail/relay-domains или указан в /etc/mail/access с ключом RELAY), либо по smtp-авторизации.

Локальность почты для получателя определяется только по почтовому домену: он должен быть пописан либо в /etc/mail/local-host-names либо в /etc/hosts
(если не используется define(`confDONT_PROBE_INTERFACES',`True'))

Пары можно задать 5-ю способами:
# Первый: локальный юзер или группа:внешний e-mail
# Второй: локальный юзер или группа:внешний почтовый домен
# Третий: локальный юзер или группа:весь внешний мир
# Четвертый: все локальные юзеры:внешний e-mail
# Пятый: все локальные юзеры:внешний почтовый домен

Файл allow имеет приоритет перед deny. Благодаря этому можно делать исключения.
Например, выбираем политику "все, что не запрещено - разрешено" и в allow пишем:
From:ivanov:petrov<@mail.ru.> [TAB] ALLOW
В deny:
From:ivanov:<@mail.ru.> [TAB] DENY
В итоге ivanov сможет посылать почту куда-угодно кроме домена mail.ru
за исключением единственного адреса этого домена petrov@mail.ru.

Или наоборот, в
В deny:
To:ivanov:<@mail.ru.> [TAB] DENY
Теперь ivanov может отправлять почту куда угодно (all), кроме домена mail.ru.
Обращаю ваше внимание, что в этом случае запись в allow:
To:ivanov:all [TAB] ALLOW
лишняя, так как наша политика разрешает всю не запрещенную почту.

Если бы мы выбрали политику "все, что не разрешено - запрещено", тогда должны бы были сделать следующее:
В allow обязательно:
To:ivanov:all [TAB] ALLOW
В deny:
To:ivanov:<@mail.ru.> [TAB] DENY

Набор правил CheckACL, проверяющий права пользователей, движется
- от разрешения к запрещению (в наборе идет последовательный
перебор вариантов задания пары, и для каждого варианта первым проверяется наличие пары в allow, и только затем в deny).
- от малого(полный e-mail) к большему (домен или all),
- от малочисленного (один локальный пользователь) к многочисленному (группа).

Например, в deny имеем:
To:ivanov:<@mail.ru.> [TAB] DENY
To:ivanov:petrov<@mail.ru.> [TAB] DENY
Тогда первой сработает блокировка To:ivanov:petrov<@mail.ru.> [TAB] DENY.

Или, включим ivanov в группу group1, а в allow напишем:
From:group1:<@mail.ru.> [TAB] ALLOW
From:ivanov:<@mail.ru.> [TAB] ALLOW
Тогда первым сработает разрешение, выданное второй строкой лично товарищу Иванову.
Конечно, смысла в таком дублировании нет.

При необходимости можно использовать группы локальных пользователей.
Тогда каждую группу нужно прописать отдельным файлом (group1, group2, etc) в директории /etc/mail.
Каждое редактирование этих файлов потребует перезапуск sendmail.
В моем наборе правил используются только две группы.
При необходимости их число можно увеличить, но это потребует дописывания правил
"по образу и подобию" в CheckACL.

И еще о delay_check. Если вы используете эту фичу, раскомментируйте
все строки с # delay_check:
В обычной конфигурации последовательность основных ruleset'ов такая:
check_relay
check_mail
check_rcpt
Мой набор входит в check_rcpt, и всякие неправильности с ip-адресом релея, с доменным именем релея, с адресом отправителя будут блокированы до него. Если же вы используете delay_check, то последовательность рулсетов изменится:
check_rcpt
check_relay
check_mail
Таким образом вне зависимости от "правильности" релея и адреса отправителя, мой набор правил будет исполнен. Для того, чтобы этого избежать, в набор добавлены дополнительные проверки, они помечены # delay_check: Раскомментируйте эти правила, чтобы блокировки срабатывали сразу.

"Все, что не запрещено, то разрешено" со знаками табуляции в формате uuencode - здесь. Протестировано.

"Все, что не разрешено, то запрещено" со знаками табуляции в формате uuencode - здесь. Не тестировалось. Исправлено из предыдущего набора правил по смыслу. Будьте острожны.

Некоторые проверки здесь казалось бы излишние, потому что их можно делать через
/etc/mail/access.
Пункт 1.2.1 равносилен включению feature(`compat_check') с последующим
редактированием /etc/mail/access:
Compat:user@mail.ru<@>user@localdomain.ru REJECT
Но !
1. С группами эта блокировка работать не будет.
2. Не существует подобной штатной фичи для разрешения общения паре.
3. При использовании этой фичи отлуп произойдет в рулсете check_compat, а это означает, что письмо сначала будет принято целиком, потом проанализировано, а потом будет выслан отлуп отправителю, ну а если этот отправитель не существует, то постмастер получит всем знакомую летопись.

Пункт 4.1 равносилен
user@domain.ru OK

Пункт 4.2 равносилен
user@domain.ru REJECT

Пункт 5.1 равносилен
domain.ru OK (исполнится в check_relay)
или
From:domain.ru OK (исполнится в check_mail)

Пункт 5.2 равносилен
domain.ru REJECT
или
From:domain.ru REJECT

Несмотря на очевидное дублирование некоторых функций, я оставляю все, как есть.
Коли уж я использую файлы allow & deny, удобнее все права пользователей держать в одном месте.
Тем не менее, все ограничения, выставленные в access, будут исполнены вне зависимости, разрешает ли подобное мой allow.
А наоборот неверно.
Все разрешения, выставленные в access, _не_ будут исполнены, если в файле deny есть соответствующее ограничение.

И первое, и второе произойдет именно так потому, что мой набор правил помещен в Local_check_rcpt, который вызывается из check_rcpt, и в случае блокировки check_rcpt сразу прекращает свою работу, в противном случае check_rcpt продолжает разбор полетов.

Ну а здесь выкладываю вариант "все, что не запрещено, то разрешено" с выводом промежуточной информации в лог и со всеми комментариями , которые я обычно пишу для себя, и которые, как показали 5 лет существования раздела, никто и никогда не читает.
Этот вариант будет полезен в случае каких-либо проблем.
Буду весьма признательна, если вы вместо сообщения "ниче не работает!" запустите этот "болтливый" вариант SendmailACL и затем вышлете мне
egrep process_number /var/log/maillog
"Болтливый" вариант политики "все, что не разрешено, то запрещено" - здесь.

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

Так как у меня не было достаточно времени на
- тщательное тестирование ACL,
- тяжкие думы по поводу взаимодействия access и моих allow&deny
- поиск всяких нерулезностей,
я с благодарностью приму любые замечания-предложения по всему вышеизложенному.
Спасибо.
sciurus@mail.ru
Тема "Sendmail" в письме обязательна: я не получаю быстрые извещения о новых письмах с другими темами.


Выложено: 23 октября 2007г.
Последнее обновление: 25 октября 2007г.
1. Добавлена блокировка на входящую почту, подписанную локальным доменом, но отправленную не с локальных адресов.
Если вам это не нужно, закомментируйте строку
R $+<@$=w.> $| $+<@$+>         $#error $: "553 Please use your own domain name."

2. Добавлена блокировка почты с несуществующего домена или на несуществующий домен:
R$+<@$+> $| $+<@$+>         $: $1<@$2> $| $3<@$4>
R$+<@$+.> $| $+<@$+.>         $: $1<@$2.> $| $3<@$4.>
R$+          $#error $: "553 5.1.8 Domain of sender/recipient address does not exist."

11.03.2008.
3. Выложен перловый скрипт для тестирования. Автор - Askon.



Попытка обсуждения Sendmail ACL.