Greylisting only for Suspicious Sender's IP address
Greylisting should not be applied to all incoming emails.
It should be use as one of the methods to prevent spam.
I only apply greylisting to suspicious sender's IP.
Suspicious IPs are:
1. Without reverse hostname
2. Reverse hostname does not point back to same IP
3. Reverse hostname is dynamic, e.g. 1-1-168-192.dialuppool.domain
The other cheap spam prevention method I use is checking for valid SMTP HELO.
These 2 methods fiters out more then 90% of spam before SMTP DATA.
The rest can be handled by more expensive process, i.e. ClamAV and SpamAssassin.
Implementation Notes:
I use Berg's exim-greylist, see url:
http://johannes.sipsolutions.net/Projects/exim-greylist/
I've installed exim-greylist on secondary MX server running CentOS 5.0 without DirectAdmin.
Using the default exim 4.63 installed by "yum install exim" which comes with mysql support.
/etc/exim/exim_dynamic_regex is file containing regex matches to dynamic IP's reverse hostname
# Example: (1-1-168-192.dialuppool.domain.)
# Example: (d-1.1.168.192.dialuppool.domai)
See url:
http://www.linuxmagic.com/opensource/anti_spam/dynamic_regex/
Example exim.conf
Code:
acl_check_rcpt:
accept hosts = : +relay_from_hosts
accept authenticated = *
accept condition = ${if or {\
{eq {$interface_port}{465}}\
{eq {$interface_port}{587}}\
}{yes}{no}}
endpass
message = relay not permitted, authentication required
authenticated = *
deny domains = +local_domains
local_parts = ^[.] : ^.*[@%!/|]
deny domains = !+local_domains
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
######################################################################
# HELO checks
######################################################################
# HELO is empty or not sent
deny message = You have sent no HELO! Please see RFC 2821 section 4.1.1.1
log_message = Bad HELO: Empty HELO
condition = ${if eq{$sender_helo_name}{}}
delay = 30s
# HELO is not a fully qualified domain name
deny message = Your mail server announcement ($sender_helo_name) \
is a single word rather than a FQDN. This is in breach of RFC2821
log_message = Bad HELO: Not FQDN
condition = ${if match {$sender_helo_name}{\\.}{no}{yes}}
delay = 30s
# IP Only is sent as the HELO
deny message = Your server announces itself ($sender_helo_name) with a plain IP address which is in breach of RFC2821.
log_message = Bad HELO: IP Only Announce
condition = ${if isip{$sender_helo_name}{yes}{no}}
delay = 30s
# Someone is trying to spoof your own IPs!
deny message = HELO/EHLO IP is local. You are not this server.
log_message = Bad HELO: Local IP Spoof Attempt
condition = ${if eq{$sender_helo_name}{localhost}{yes}{no}}
delay = 30s
# Someone is trying to spoof a domain on the server
deny message = Forged HELO: you are not $sender_helo_name
log_message = Forged HELO: $sender_helo_name Spoof Attempt
condition = ${if match_domain{$sender_helo_name}{+local_domains}{yes}{no}}
delay = 30s
######################################################################
# GREYLIST checks
######################################################################
.ifdef GREYLIST_ENABLED
# Reverse Host Lookup Failed
defer !senders = : postmaster@*
domains = +local_domains : +relay_to_domains
condition = ${if eq{$host_lookup_failed}{1}}
acl = greylist_acl
message = greylisted - try again later
log_message = greylisted_1 - host_lookup_failed [$host_lookup_failed]
# Reverse Host Lookup Deferred
defer !senders = : postmaster@*
domains = +local_domains : +relay_to_domains
condition = ${if eq{$host_lookup_deferred}{1}}
acl = greylist_acl
message = greylisted - try again later
log_message = greylisted_2 - host_lookup_deferred [$host_lookup_deferred]
# Reverse DNS Rejected - dynamic ip
defer !senders = : postmaster@*
domains = +local_domains : +relay_to_domains
condition = ${lookup{$sender_host_name} nwildlsearch {/etc/exim/exim_dynamic_regex} {yes}{no}}
acl = greylist_acl
message = greylisted - try again later
log_message = greylisted_3 - dynamic ip
.endif