De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
GrayList no servdir de emails (EXIM, MYSQL) - Mini tutorial
Colaboração: Silmar A. Marca
Data de Publicação: 30 de Maio de 2005
Graylist é uma lista "cinza", onde o servidor rejeita a
mensagem por um determinado tempo. Tal atitude forca a
mensagem a ser re-enviada, o que geralmente não acontece
caso a mesma seja enviada por um servidor de SPAM ou por
inúmeros tipos de VIRUS. Uma vez a mensagem conseguir ser
enviada, o servidor que a enviou poderá postar sucessivas
mensagens sem atraso.
Funciona bem na versão 4.50 ou superior do EXIM. É
pré-requisito compilar o exim com suporte a mysql.
Vale a pena ressaltar que o GrayList apresentado é
modificado do padrão original. O mesmo valida apenas o
dominio de quem envia e a rede do mesmo. Valida também
mensagens de erro (Bounce). Tal modificação tem apresentado
os efeitos positivos de diminuir atrasos na entrega da
mensagem em caso de round-robing nos ips de entrega,
isto sem causar impacto na eficiencia da ferramenta.
Observa se que é importante adicionar o graylist no final
das clausulas rcpt e data e não no inicio! Adicionar
antes do aceite final para qualquer hosts! A mesma não
impede usuarios autenticados, relay Hosts e SPF validados
(caso habilitado).
Partes do código foram baseados em diversos tutorias na internet.
Criar tabela no mysql:
#
# Estrutura da tabela ``greylist``
#
CREATE TABLE ``greylist`` (
``id`` bigint(20) NOT NULL auto_increment,
``relay_ip`` varchar(20) default NULL,
``sender_type`` enum('NORMAL','BOUNCE') NOT NULL default 'NORMAL',
``sender`` varchar(150) default NULL,
``recipient`` varchar(150) default NULL,
``block_expires`` datetime NOT NULL default '0000-00-00 00:00:00',
``record_expires`` datetime NOT NULL default '9999-12-31 23:59:59',
``create_time`` datetime NOT NULL default '0000-00-00 00:00:00',
``TYPE`` enum('AUTO','MANUAL') NOT NULL default 'MANUAL',
``passcount`` bigint(20) NOT NULL default '0',
``last_pass`` datetime NOT NULL default '0000-00-00 00:00:00',
``blockcount`` bigint(20) NOT NULL default '0',
``last_block`` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (``id``),
UNIQUE KEY ``relay_ip`` (``relay_ip``,``sender``,``recipient``,``sender_type``)
) TYPE=MyISAM COMMENT='GrayList ';
# --------------------------------------------------------
#
# Estrutura da tabela ``greylist_log``
#
CREATE TABLE ``greylist_log`` (
``id`` bigint(20) NOT NULL auto_increment,
``listid`` bigint(20) NOT NULL default '0',
``timestamp`` datetime NOT NULL default '0000-00-00 00:00:00',
``kind`` enum('deferred','accepted') NOT NULL default 'deferred',
PRIMARY KEY (``id``)
) TYPE=MyISAM COMMENT='GrayList Log';
Arquivo exim.conf:
<..Outras configuracoes iniciais...>
#Comentar caso nao haja base Mysql
MYSQL_SERVER = "localhost/baseexim/usuarioeximbd/senhaeximbd"
#-DEF: Lista GreyList (Defer Temporario)
.ifdef MYSQL_SERVER
GREYLIST_ENABLED_GREY = yes
# GREYLIST_ENABLED_LOG = yes
GREYLIST_INITIAL_DELAY = 12 MINUTE
GREYLIST_INITIAL_LIFETIME = 4 HOUR
GREYLIST_WHITE_LIFETIME = 36 DAY
GREYLIST_BOUNCE_LIFETIME = 7 DAY
GREYLIST_RECORD_LIFETIME = 90 DAY
GREYLIST_TABLE = greylist
GREYLIST_LOG_TABLE = greylist_log
# GREYLIST_SKPSPF = yes
.endif
<..Outras configuracoes iniciais...>
.ifdef MYSQL_SERVER
.ifdef GREYLIST_ENABLED_GREY
GREYLIST_TEST = SELECT CASE \
WHEN now() > block_expires THEN "accepted" \
ELSE "deferred" \
END AS result, id \
FROM GREYLIST_TABLE \
WHERE (now() < record_expires) \
AND (sender_type = ${if def:sender_address_domain{'NORMAL'}{'BOUNCE'}}) \
AND (sender = '${quote_mysql:${if def:sender_address_domain{$sender_address_domain}{${domain:$h_from:}}}}') \
AND (recipient = '${quote_mysql:${if def:domain{$domain}{${domain:$h_to:}}}}') \
AND (relay_ip = '${quote_mysql:${mask:$sender_host_address/24}}') \
ORDER BY result DESC LIMIT 1
GREYLIST_ADD = REPLACE INTO GREYLIST_TABLE \
(relay_ip, sender_type, sender, recipient, block_expires, \
record_expires, create_time, type) \
VALUES ( '${quote_mysql:${mask:$sender_host_address/24}}', \
${if def:sender_address_domain{'NORMAL'}{'BOUNCE'}}, \
'${quote_mysql:${if def:sender_address_domain{$sender_address_domain}{${domain:$h_from:}}}}', \
'${quote_mysql:${if def:domain{$domain}{${domain:$h_to:}}}}', \
DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_DELAY), \
DATE_ADD(now(), INTERVAL GREYLIST_INITIAL_LIFETIME), \
now(), \
'AUTO' \
)
GREYLIST_DEFER_HIT = UPDATE GREYLIST_TABLE \
SET blockcount=blockcount+1, last_block=now() \
WHERE id = $acl_m9
GREYLIST_OK_COUNT = UPDATE GREYLIST_TABLE \
SET passcount=passcount+1, last_pass=now() \
WHERE id = $acl_m9
GREYLIST_OK_NEWTIME = UPDATE GREYLIST_TABLE \
SET record_expires = DATE_ADD(now(), INTERVAL GREYLIST_WHITE_LIFETIME) \
WHERE id = $acl_m9 AND type='AUTO'
GREYLIST_OK_BOUNCE = UPDATE GREYLIST_TABLE \
SET record_expires = DATE_ADD(now(), INTERVAL GREYLIST_BOUNCE_LIFETIME) \
WHERE id = $acl_m9 AND type='AUTO'
GREYLIST_CLEAN = DELETE FROM GREYLIST_TABLE \
WHERE (record_expires > DATE_ADD(now(), INTERVAL GREYLIST_RECORD_LIFETIME)) AND (type='AUTO')
GREYLIST_LOG = INSERT INTO GREYLIST_LOG_TABLE \
(listid, timestamp, kind) \
VALUES ($acl_m9, now(), '$acl_m8')
.endif
.endif
<..Outras configuracoes iniciais...>
#-Definicao da ACL. Clausula GreyList (ocorre antes do rcpt e do data):
.ifdef GREYLIST_ENABLED_GREY
greylist_acl:
# Limpar tabela automaticamente 09:3xBRST 10:3xBRDT (horario normal)
warn condition = ${if eq {${substr{9}{3}{$tod_zulu}}} {123}{yes}{no}}
set acl_m4 = ${lookup mysql{GREYLIST_CLEAN}}
warn set acl_m8 = ${lookup mysql{GREYLIST_TEST}{$value}{result=unknown}}
set acl_m9 = ${extract{id}{$acl_m8}{$value}{-1}}
set acl_m8 = ${extract{result}{$acl_m8}{$value}{unknown}}
accept
condition = ${if eq {$acl_m8} {unknown} {yes}}
condition = ${lookup mysql{GREYLIST_ADD}{yes}{no}}
.ifdef GREYLIST_ENABLED_LOG
warn condition = ${lookup mysql{GREYLIST_LOG}}
.endif
accept
condition = ${if eq{$acl_m8} {deferred} {yes}}
condition = ${lookup mysql{GREYLIST_DEFER_HIT}{yes}{yes}}
warn condition = ${lookup mysql{GREYLIST_OK_COUNT}}
warn !senders = : postmaster@* : Mailer-Daemon@*
condition = ${lookup mysql{GREYLIST_OK_NEWTIME}}
warn senders = : postmaster@* : Mailer-Daemon@*
condition = ${lookup mysql{GREYLIST_OK_BOUNCE}}
deny
.endif
<..Outras configuracoes de ACL...>
acl_check_rcpt:
<... Outras configuracoes deste rcpt. Como verificações de sender, aceitar relay_hosts e autenticados...>
<... Geralmente coloca se esta clausula antes do accept final para quem não é ralay_host e autenticado...>
.ifdef GREYLIST_ENABLED_GREY
defer hosts = !+relay_from_hosts
!authenticated = *
.ifdef GREYLIST_SKPSPF
!spf = pass
.endif
acl = greylist_acl
message = GreyListed: please try again later
delay = 15s
.endif
.endif
<..Outras configuracoes. Outros ACLs...>
acl_check_data:
<... Outras configuracoes deste rcpt. Como verificações de sender, aceitar relay_hosts e autenticados...>
<... Geralmente coloca se esta clausula antes do accept final para quem não é ralay_host e autenticado...>
.ifdef GREYLIST_ENABLED_GREY
defer
.ifdef GREYLIST_SKPSPF
!spf = pass
.endif
acl = greylist_acl
message = GreyListed: please try again later
delay = 15s
.endif
Silmar A. Marca, GrupoGSN - Desenvolvimento, Implantação e Verificação de Servidores
Profissionais baseados em Linux/Novell