exim-greylist.conf.inc 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # $Id: acl-greylist-sqlite,v 1.3 2007/11/25 19:17:28 dwmw2 Exp $
  2. GREYDB=/var/spool/exim4/db/greylist.db
  3. # ACL for greylisting. Place reason(s) for greylisting into a variable named
  4. # $acl_m_greylistreasons before invoking with 'require acl = greylist_mail'.
  5. # The reasons should be separate lines of text, and will be reported in
  6. # the SMTP rejection message as well as the log message.
  7. #
  8. # When a suspicious mail is seen, we temporarily reject it and wait to see
  9. # if the sender tries again. Most spam robots won't bother. Real mail hosts
  10. # _will_ retry, and we'll accept it the second time. For hosts which are
  11. # observed to retry, we don't bother greylisting again in the future --
  12. # it's obviously pointless. We remember such hosts, or 'known resenders',
  13. # by a tuple of their IP address and the name they used in HELO.
  14. #
  15. # We also include the time of listing for 'known resenders', just in case
  16. # someone wants to expire them after a certain amount of time. So the
  17. # database table for these 'known resenders' looks like this:
  18. #
  19. # CREATE TABLE resenders (
  20. # host TEXT,
  21. # helo TEXT,
  22. # time INTEGER,
  23. # PRIMARY KEY (host, helo) );
  24. #
  25. # To remember mail we've rejected, we create an 'identity' from its sender
  26. # and recipient addresses and its Message-ID: header. We don't include the
  27. # sending IP address in the identity, because sometimes the second and
  28. # subsequent attempts may come from a different IP address to the original.
  29. #
  30. # We do record the original IP address and HELO name though, because if
  31. # the message _is_ retried from another machine, it's the _first_ one we
  32. # want to record as a 'known resender'; not just its backup path.
  33. #
  34. # Obviously we record the time too, so the main table of greylisted mail
  35. # looks like this:
  36. #
  37. # CREATE TABLE greylist (
  38. # id TEXT,
  39. # expire INTEGER,
  40. # host TEXT,
  41. # helo TEXT);
  42. #
  43. greylist_mail:
  44. # First, accept if it there's absolutely nothing suspicious about it...
  45. accept condition = ${if eq{$acl_m_greylistreasons}{} {1}}
  46. # ... or if it was generated locally or by authenticated clients.
  47. accept hosts = :
  48. accept authenticated = *
  49. # Secondly, there's _absolutely_ no point in greylisting mail from
  50. # hosts which are known to resend their mail. Just accept it.
  51. accept condition = ${lookup sqlite {GREYDB SELECT host from resenders \
  52. WHERE helo='${quote_sqlite:$sender_helo_name}' \
  53. AND host='$sender_host_address';} {1}}
  54. # Generate a hashed 'identity' for the mail, as described above.
  55. warn set acl_m_greyident = ${hash{20}{62}{$sender_address$recipients$h_message-id:}}
  56. # Attempt to look up this mail in the greylist database. If it's there,
  57. # remember the expiry time for it; we need to make sure they've waited
  58. # long enough.
  59. warn set acl_m_greyexpiry = ${lookup sqlite {GREYDB SELECT expire FROM greylist \
  60. WHERE id='${quote_sqlite:$acl_m_greyident}';}{$value}}
  61. logwrite = greylist lookup returned "$acl_m_greyexpiry"
  62. # If the mail isn't already the database -- i.e. if the $acl_m_greyexpiry
  63. # variable we just looked up is empty -- then try to add it now. This is
  64. # where the 2 minute timeout is set ($tod_epoch + 120), should you wish
  65. # to change it.
  66. warn condition = ${if eq {$acl_m_greyexpiry}{} {1}}
  67. set acl_m_dontcare = ${lookup sqlite {GREYDB INSERT INTO greylist \
  68. VALUES ( '$acl_m_greyident', \
  69. '${eval10:$tod_epoch+120}', \
  70. '$sender_host_address', \
  71. '${quote_sqlite:$sender_helo_name}' );}}
  72. # Be paranoid, and check if the insertion succeeded (by doing another lookup).
  73. # Otherwise, if there's a database error we might end up deferring for ever.
  74. defer condition = ${if eq {$acl_m_greyexpiry}{} {1}}
  75. condition = ${lookup sqlite {GREYDB SELECT expire FROM greylist \
  76. WHERE id='${quote_sqlite:$acl_m_greyident}';} {1}}
  77. logwrite = Your mail was considered suspicious for the following reason(s):\n$acl_m_greylistreasons
  78. message = Your mail was considered suspicious for the following reason(s):\n$acl_m_greylistreasons \
  79. The mail has been greylisted for 5 minutes, after which it should be accepted. \
  80. We apologise for the inconvenience. Your mail system should keep the mail on \
  81. its queue and retry. When that happens, your system will be added to the list \
  82. genuine mail systems, and mail from it should not be greylisted any more. \
  83. In the event of problems, please contact postmaster@$qualify_domain
  84. log_message = Greylisted <$h_message-id:> from <$sender_address> for offences: ${sg {$acl_m_greylistreasons}{\n}{,}}
  85. # Handle the error case (which should never happen, but would be bad if it did).
  86. # First by whining about it in the logs, so the admin can deal with it...
  87. warn condition = ${if eq {$acl_m_greyexpiry}{} {1}}
  88. log_message = Greylist insertion failed. Bypassing greylist.
  89. # ... and then by just accepting the message.
  90. accept condition = ${if eq {$acl_m_greyexpiry}{} {1}}
  91. # OK, we've dealt with the "new" messages. Now we deal with messages which
  92. # _were_ already in the database...
  93. # If the message was already listed but its time hasn't yet expired, keep rejecting it
  94. defer condition = ${if > {$acl_m_greyexpiry}{$tod_epoch}}
  95. logwrite = Your mail was previously greylisted and the time has not yet expired.\n\
  96. You should wait another ${eval10:$acl_m_greyexpiry-$tod_epoch} seconds.\n\
  97. Reason(s) for greylisting: \n$acl_m_greylistreasons
  98. message = Your mail was previously greylisted and the time has not yet expired.\n\
  99. You should wait another ${eval10:$acl_m_greyexpiry-$tod_epoch} seconds.\n\
  100. Reason(s) for greylisting: \n$acl_m_greylistreasons
  101. # The message was listed but it's been more than five minutes. Accept it now and whitelist
  102. # the _original_ sending host by its { IP, HELO } so that we don't delay its mail again.
  103. warn set acl_m_orighost = ${lookup sqlite {GREYDB SELECT host FROM greylist \
  104. WHERE id='${quote_sqlite:$acl_m_greyident}';}{$value}}
  105. set acl_m_orighelo = ${lookup sqlite {GREYDB SELECT helo FROM greylist \
  106. WHERE id='${quote_sqlite:$acl_m_greyident}';}{$value}}
  107. set acl_m_dontcare = ${lookup sqlite {GREYDB INSERT INTO resenders \
  108. VALUES ( '$acl_m_orighost', \
  109. '${quote_sqlite:$acl_m_orighelo}', \
  110. '$tod_epoch' ); }}
  111. logwrite = Added host $acl_m_orighost with HELO '$acl_m_orighelo' to known resenders
  112. accept