[exim] Mini tutorial of Fast GrayList

Top Page
Delete this message
Reply to this message
Author: Silmar A. Marca
Date:  
To: exim-users
Subject: [exim] Mini tutorial of Fast GrayList
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!
------------------------------------------------------------