This is based (but modify) on tutorial writing by Tor Slettnes <tor@???>.
I have a tested implementation of modify graylist simplest: this gray list
compare only domain of sender and a mask/24 of sender to domain of rcpt. Have a
auto clean of gray list old recordes...
It is a fast gray list and work!!!
#Create Sql bd
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 ' AUTO_INCREMENT=199 ;
-----------------------------------------------------
#Exim.conf file
GREYLIST_ENABLED_GREY = 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
#....
.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')
.endif
#...
#-GreyList (before rcpt and data):
.ifdef GREYLIST_ENABLED_GREY
greylist_acl:
# clean greylist records as 09:3xBRST 10:3xBRDT (horario normal)
warn condition = ${if eq {${substr{8}{3}{$tod_zulu}}} {123}{yes}{no}}
set acl_m4 = ${lookup mysql{GREYLIST_CLEAN}}
# For regular deliveries, check greylist.
# check greylist tuple, returning "accepted", "deferred" or "unknown"
# in acl_m8, and the record id in acl_m9
warn set acl_m8 = ${lookup mysql{GREYLIST_TEST}{$value}{result=unknown}}
# here acl_m8 = "result=x id=y"
set acl_m9 = ${extract{id}{$acl_m8}{$value}{-1}}
# now acl_m9 contains the record id (or -1)
set acl_m8 = ${extract{result}{$acl_m8}{$value}{unknown}}
# now acl_m8 contains unknown/deferred/accepted
# check if we know a certain triple, add and defer message if not
accept
# if above check returned unknown (no record yet)
condition = ${if eq {$acl_m8} {unknown} {1}}
# then also add a record
condition = ${lookup mysql{GREYLIST_ADD}{yes}{no}}
# check if the triple is still blocked
accept
# if above check returned deferred then defer
condition = ${if eq{$acl_m8} {deferred} {1}}
# and note it down
condition = ${lookup mysql{GREYLIST_DEFER_HIT}{yes}{yes}}
# use a warn verb to count records that were hit
warn condition = ${lookup mysql{GREYLIST_OK_COUNT}}
# use a warn verb to set a new expire time on automatic records,
# but only if the mail was not a bounce, otherwise set to now().
warn !senders = : postmaster@* : Mailer-Daemon@*
condition = ${lookup mysql{GREYLIST_OK_NEWTIME}}
warn senders = : postmaster@* : Mailer-Daemon@*
condition = ${lookup mysql{GREYLIST_OK_BOUNCE}}
deny
.endif
#....
acl_check_rcpt:
#....<put is in end of rcpt acl, before accept clause>
.ifdef GREYLIST_ENABLED_GREY
defer hosts = !+relay_from_hosts
!authenticated = *
!senders = : postmaster@* : Mailer-Daemon@*
acl = greylist_acl
message = GreyListed: please try again later
.endif
<the end clause accept is here>
#....
acl_check_data:
#....<put is in end of data acl, before accept clause>
.ifdef GREYLIST_ENABLED_GREY
defer hosts = !+relay_from_hosts
senders = : postmaster@* : Mailer-Daemon@*
acl = greylist_acl
message = GreyListed: please try again later
.endif
<the end clause accept is here>
Cordialmente, Silmar A. Marca
GrupoGSN - Desenvolvimento, Implantação e Verificação de Servidores
Profissionais baseados em Linux/Novell
http://www.grupogsn.com.br/~marca/
------------------------------------------------------------
Se algo não lhe faz mal (fisico, moral ou psicologicamente),
experimente! O máximo e você perder tempo! E tempo, e
o que você tem a vida toda pra perder.....
Mais vale um instante de prazer que uma eternidade fútil!
------------------------------------------------------------