Все знают про такой почтовый сервер 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 работал через внешний скрипт.
"No! Try not! Do. Or do not. There is no try." -- Yoda