EXIM отличается от sendmail'а более понятным конфигом и который можно настроить практически на все случаи.
Расскажу, как сделать поддержку технологии greylist (серый список) в exim для обеспечения блокирования порядка 90% спама.
Технология greylist заключается в том, что при первой попытке отправить нам письмо, передающей стороне передается код
- Код: Выделить всё
451 Temporary reject
Это заставляет нормальный передающий узел повторить попытку передачи письма позднее (интервал повторов зависит от его настроек)
Через определенное время письмо перепосылается и мы его принимаем.
Таким образом, нормальный узел передает письмо с какой-то задержкой.
Спам рассылки, как правило, делаются либо через открытые релеи, либо через всякие прокси, либо напрямую. Если спамщики будут отрабатывать 4xx ошибку и делать переповторы отправки спама, то это резко уменьшит скорость рассылки (да и обработка факта отправки усложнится).
Поэтому, спамщики будут пытаться отправить спам через другие сервера, наивно предполагая, что заблокирован конкретный узел.
Разумеется, получат такой-же облом
Нужно:
настроенный exim версии 4.x с поддержкой mysql (я вообще всю инфу храню в базе, в т.ч. настройки)
Как настроить exim для работы с mysql рассказывать не буду - это тривиально.
Необходимо создать в базе табличку, для хранения текущей информации greylist:
- Код: Выделить всё
CREATE TABLE `Greylist` (
`id` bigint(20) NOT NULL auto_increment,
`relay_ip` char(15) default NULL,
`sender` char(64) default NULL,
`recipient` char(64) default NULL,
`block_expires` int(11) NOT NULL default '0',
`record_expires` int(11) NOT NULL default '0',
`create_time` int(10) unsigned NOT NULL default '0',
`pass_count` int(10) unsigned NOT NULL default '0',
`block_count` int(10) unsigned NOT NULL default '0',
`ehlo` char(64) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `relay_ip` (`relay_ip`,`sender`,`recipient`)
);
Теперь надо прописать в конфиг exim'а:
а) в самом начале прописать макросы:
- Код: Выделить всё
GREYLIST_TEST=SELECT concat("id=",id," ts=",(unix_timestamp()-block_expires)) \
from Greylist \
where relay_ip='${quote_mysql:$sender_host_address}' and \
sender='${quote_mysql:$sender_address}' and \
recipient='${quote_mysql:$local_part}@${quote_mysql:$domain}' limit 1
GREYLIST_ADD=INSERT into Greylist (relay_ip,sender,recipient,\
block_expires,record_expires,create_time,block_count,ehlo) \
values \
('${quote_mysql:$sender_host_address}',\
'${quote_mysql:$sender_address}',\
'${quote_mysql:$local_part}@${quote_mysql:$domain}',\
unix_timestamp()+60*15,unix_timestamp()+60*60*24,unix_timestamp(),1,\
'${quote_mysql:$sender_helo_name}')
GREYLIST_UPD1=UPDATE Greylist set pass_count=pass_count+1,\
record_expires=unix_timestamp()+60*60*24 where id=$acl_m2
GREYLIST_UPD2=UPDATE Greylist set block_count=block_count+1 where id=$acl_m2
в блоке ACL настроек после RCPT TO в нужном месте прописать сами директивы:
- Код: Выделить всё
# set variables
warn set acl_m1 = ${lookup mysql{GREYLIST_TEST}{$value}{id=-1 ts=0}}
set acl_m2 = ${extract{id}{$acl_m1}{$value}{unknown}}
set acl_m3 = ${extract{ts}{$acl_m1}{$value}{unknown}}
# defer if first attempt
defer hosts = ! +relay_hosts
condition = ${if < {$acl_m2}{0}{yes}{no}}
set acl_m4 = ${lookup mysql{GREYLIST_ADD}{$value}{0}}
# defer if time < block_time
defer hosts = ! +relay_hosts
condition = ${if > {$acl_m2}{0}{yes}{no}}
condition = ${if < {$acl_m3}{0}{yes}{no}}
set acl_m4 = ${lookup mysql{GREYLIST_UPD2}{$value}{0}}
# pass defers if time > block_time and update count
warn hosts = ! +relay_hosts
set acl_m4 = ${lookup mysql{GREYLIST_UPD1}{$value}{0}}
Описание:
а) при первой попытке отправить нам почту (когда тройка sender_host_address, sender_address, recipient_address отсутствует в таблице), письмо отвергается; факт попытки заносится в табличку
б) при попытке спустя время, меньшее 60*15 секунд, письмо отвергается; наращивается счетчик отвергнутых попыток
в) --//-- время большее 60*15 секунд - письмо принимается; апдейтится время устаревания записи и счетчик принятых попыток
Так-же, в cron полезно прописать следующее:
- Код: Выделить всё
mysql база -e 'delete from Greylist where unix_timestamp()>record_expires;'
чтобы удалять устаревшие записи, т.е. не было повторных писем спустя 60*60*24 секунд от последней попытки.
PS. информация дается AS IS. у меня всё работает.
PPS. разумеется, в конфиге должны быть и другие правила; поэтому важно "всунуть" эти настройки в нужное место. а так-же, ввести дополнительные проверки, например, у меня есть еще настройка срабатывания этих правил по конкретным адресам получателей. т.е. greylist работает не для всех.
PPPS. технология не моя. я только сделал всё средствами exim'а. до этого greylist работал через внешний скрипт.
Laa: Чтобы не раздувать тему, вставлю следующее сообщение этого же пользователя:
Я нашол ссылку
http://lug.ivanovo.ru/f/topic_show.pl?tid=259оставте сюда свое мнении