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