For this purpose, Exim 3 just won't do. You need Exim 4 to do the job.
Filtering solutions involving Exim 3 will often bounce when they really should
reject. And bouncing is evil!.
Some ISPs will even terminate your connection if you bounce when you really
should reject!
And just using Exim 4 won't do either. You have to apply the
exiscan patch, or install
an Exim 4 package, which has this patch already applied, such as Debian's
'exim4-daemon-heavy'.
And don't install SA-Exim either; It's perfectly pointless. The exiscan patch
does all you need.
The stuff below is based on Debian 3.0 / Woody. For Debian 3.1 / Sarge you can use the old Woody config tree, but you will have to make a few changes (a fully Sarge based page will be published later).
# Exim 4 deb http://www.nl.backports.org/debian woody exim4 deb http://www.backports.org/debian woody exim4If you want to be able to encrypt your mail using 'TLS' also install;
deb http://www.nl.backports.org/debian woody gnutls11 deb http://www.backports.org/debian woody gnutls11For SPF also add;
# SPF deb http://www.nl.backports.org/debian woody libmail-spf-query-perl deb http://www.backports.org/debian woody libmail-spf-query-perlThe SpamAssassin spam filter;
# SpamAssassin deb http://www.nl.backports.org/debian woody spamassassin deb http://www.backports.org/debian woody spamassassinAnd the SpamAssassin plugin Razor;
# Razor deb http://www.nl.backports.org/debian woody razor deb http://www.backports.org/debian woody razorThere is no SRS backport
Select the following packages and anything that they depend on;
After this configure the lot;
smtp stream tcp nowait.64 Debian-exim /usr/sbin/tcpd /usr/sbin/exim4 -bsAnd restart inetd.
You also need to run the queue from cron. Add / edit the following line in /etc/cron.d/exim;
08,23,38,53 * * * * Debian-exim if [ -x /usr/sbin/exim4 -a -f /var/lib/exim4/config.autogenerated ]; then /usr/sbin/exim4 -q ; fiAnd restart cron.
The Debian Exim 4 way of doing things however, is to use a large tree of config files in /etc/exim4/conf.d/ and generate one single file /var/lib/exim4/config.autogenerated using update-exim4.conf. This file will only be used if /etc/exim4/exim4.conf doesn't exist.
During install, debconf will edit /etc/exim4/update-exim4.conf.conf. update-exim4.conf uses this file, together with the tree under /etc/exim4/conf.d/ to generate /var/lib/exim4/config.autogenerated. It may be necessary to edit /etc/exim4/update-exim4.conf.conf.
Below are various additions and enhancements to the default Exim 4 config.
primary_hostname = Your_Helo_NameSome spam filters will complain if your helo doesn't match the reverse, even if the forward matches (forged helo). Fortunately newer versions of Exim support 'smtp_active_hostname'. The statement below will use the host name of the interface used for the SMTP connection. If the lookup fails or the mail isn't received via TCP but via stdin, the primary_hostname will be used instead;
smtp_active_hostname = ${lookup dnsdb{ptr=$interface_address}{$value}fail}The statement below allows you to use a special name 'Helo_For_1.2.3.4' when connected via interface '1.2.3.4'. In other cases 'Other_Helo' will be used;
smtp_active_hostname = ${if eq{$interface_address}{1.2.3.4}\ {Helo_For_1.2.3.4}{Other_Helo}}This works for incoming mail and callouts. For outgoing mail see transport/30_exim4-config_remote_smtp
And the qualify_domain isn't necessarily what you want either;
# Qualify_domain #qualify_domain = DEBCONFvisiblenameDEBCONF qualify_domain = Your_DomainSet the maximum message size.
MESSAGE_SIZE_LIMIT = 128KA whitelist for RBL checking;
hostlist rbl_white_hosts = : \ 127.0.0.0/8 : \ 192.168.1.0/24 : \ Your_Own_Ip_AddressThe qualify_domain isn't necessarily what you want either;
# Qualify_domain #qualify_domain = DEBCONFvisiblenameDEBCONF qualify_domain = example.com
acl_smtp_vrfy = check_vrfyA message size limit. This one is quite large. That way one gets an error after RCPT, not immediately after MAIL.
message_size_limit = 2MAvoid defers on failing DNS lookups
dns_again_means_nonexist = *Add additional info with your bounces;
bounce_message_text = "See Url_To_Your_Spam_Policy"Check for underscores but complain after RCPT
helo_allow_chars = _Do a DNS lookup, but complain after RCPT
helo_try_verify_hosts = *Disable pipelining
# No pipelining pipelining_advertise_hosts = :Limit return size
return_size_limit = 16KOptional virus scanner
deb http://www.nl.backports.org/debian woody clamav deb http://www.backports.org/debian woody clamavReplace 'nl' with your favourite mirror. Don't edit routers and transports to use a virus scanner All you need is an entry in main/02_exim4-config_options and the data or mime ACL;
av_scanner = Virus_Scanner_CommandExim temporarily stores the mail and attachments in /var/spool/exim4/scan/$message_id. This path is represented by '%s'. You can tell the scanner to scan the files in this directory;
av_scanner = cmdline:/path/to/scanner %sA F-Prot Example;
av_scanner = cmdline:/usr/local/bin/f-prot -archive -packed %s ; \ echo -e "\nfprot_retval $?":fprot_retval 3:Infection:: (.*)Some scanners use an unix socket
av_scanner = clamd:/path/to/socketOr an IP port
av_scanner = clamd:127.0.0.1 3310See Adding Anti-Virus Software for more information.
Enable SpamAssassin
spamd_address = 127.0.0.1 783Allow 8 bits
accept_8bitmime print_topbitcharsRoot should never send or receive mail!
never_users = root
The original config files whitelist mail to postmaster. Experience shows that this is not a good idea.
# Accept mail to postmaster in any local domain, regardless of the source, # and without verifying the sender. # #accept local_parts = postmaster # domains = +local_domainsHowever, if you administer a lot of boxes which all forward their postmaster mail to you, it's probably a good idea to accept mail that was accepted by those systems;
accept hosts = Host_List_Of_My_Boxes local_parts = postmasterI insist on a matching reverse lookup;
deny message = Broken Reverse DNS no host name found for IP address $sender_host_address See http://www.sput.nl/spam/ !verify = reverse_host_lookupThis doesn't work on on boxes newer then Woody. Instead of '!verify' use 'condition';
deny message = Broken Reverse DNS no host name found for IP address $sender_host_address See http://www.sput.nl/spam/ condition = ${if and\ {{def:sender_host_address}\ {!def:sender_host_name}}\ {yes}{no}}You may need to create a whitelist for badly configured nameservers. One way of doing this, is adding entries to /etc/hosts. You need order hosts,bind in your /etc/resolv.conf or /etc/host.conf to make this work;
Ip_Address Host_NameA lot of zombie ISPs don't have a MX. And therefore no abuse address either. Below an experimental test to see if they have one and if it is a hostname. If the host is 'a.b.c.d.e' it will first try 'd.e', then 'c.d.e' and finally 'b.c.d.e'. If none if these result in a hostname, the mail is rejected. This stuff only works with newer versions of Exim.
# Check host's MX domain # Looks for mx for host a.b.c.d.e # First check d.e, then c.d.e and then b.c.d.e deny message = No MX for host $sender_host_name domain hosts = ! : !+relay_from_hosts # Put lookup result in variable set acl_m8 = ${lookup dnsdb {mxh=\ ${extract{-2}{.}{$sender_host_name}}.${extract{-1}{.}{$sender_host_name}} : \ ${extract{-3}{.}{$sender_host_name}}.${extract{-2}{.}{$sender_host_name}}.\ ${extract{-1}{.}{$sender_host_name}} : \ ${extract{-4}{.}{$sender_host_name}}.${extract{-3}{.}{$sender_host_name}}.\ ${extract{-2}{.}{$sender_host_name}}.${extract{-1}{.}{$sender_host_name}}\ }{$value}fail} # Test content of variable; The MX has to be a hostname. condition = ${if !match {$acl_m8}{\N.*[A-Za-z].*\..*[A-Za-z].*\N}{yes}{no}}If all went well '$acl_m8' will now contain a number of hosts separated by newlines. The next thing to do is to check if these resolve to IP addresses. To this end 'tr' replaces the newlines with colons (':'). None of the addresses should be in use on your lan. Edit to suit your needs (don't forget to replace '192.168.1.' and '213.84.159.78' with your own IP address(es)).
deny message = Bogus MX for host $sender_host_name domain hosts = ! : !+relay_from_hosts set acl_m8 = ${lookup dnsdb {a=${tr{$acl_m8}{\n}{:}}}{$value}fail} condition = ${if \ or{\ {!match {$acl_m8}{\N[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}\N}}\ {match {$acl_m8}{\N127\.0\.0\.1\N}}\ {match {$acl_m8}{\N192\.168\.1\.[0-9]{1,3}\N}}\ {match {$acl_m8}{\N213\.84\.159\.78\N}}\ }\ {yes}{no}}In some cases however, the remote host DOES accept SMTP connections. You may add these to a whitelist.
Lots of HELO checks. Just choose and pick
# Don't allow underscores deny message = Underscores are not allowed in hostnames condition = ${if match\ {$sender_helo_name}\ {\N.*_.*\N}\ {yes}{no}} # A remote host using my helo is wrong deny hosts = !+relay_from_hosts message = Using my HELO is identity theft condition = ${if match\ {$sender_helo_name}\ {\N^(213\.84\.159\.78|(.*\.)?sput\.nl)$\N}\ {yes}{no}} # A remote host can't be localhost or localdomain deny hosts = !+relay_from_hosts message = $sender_helo_name is a silly HELO condition = ${if match\ {$sender_helo_name}\ {\N^(127\.0\.0\.1|localhost(\.localdomain)?)$\N}\ {yes}{no}} # Helo should not be RFC 1918 address deny hosts = !+relay_from_hosts message = RFC 1918 IP address in HELO condition = ${if match\ {$sender_helo_name}\ {\N^(\[)?(10\.[0-9]{1,3}|172\.(1[6-9]|2[0-9]|31)|192\.168)\.[0-9]{1,3}\.[0-9]{1,3}(\])?$\N}\ {yes}{no}} # Helo should be hostname deny hosts = !+relay_from_hosts message = HELO should be hostname. See http://www.sput.nl/spam/ condition = ${if !match\ {$sender_helo_name}\ {\N.*[A-Za-z].*\N}\ {yes}{no}} # Helo should be FQDN deny hosts = !+relay_from_hosts message = HELO should be Fully Qualified Domain Name Host.Domain.Tld See RFC821 condition = ${if !match\ {$sender_helo_name}\ {\N.*[A-Za-z].*\..*[A-Za-z].*\N}\ {yes}{no}}Don't accept mail from Some_User@localhost.localdomain
# A domain can't be localhost or localdomain deny message = $sender_address_domain is a silly domain. condition = ${if match\ {$sender_address_domain}\ {\N^(localhost|localhost\.localdomain|localdomain)$\N}\ {yes}{no}}I also added an SPF record to my NS. Addresses like 'root@localhost' really shouldn't be used;
IN NS localhost. IN TXT "v=spf1 a -all" IN A 127.0.0.1An other identity theft check.
# A remote host using my Domain is wrong deny hosts = !+relay_from_hosts message = Using my domain is identity theft condition = ${if match\ {$sender_address_domain}\ {\N^(.*\.)?sput\.nl$\N}\ {yes}{no}}Check if the HELO has got anything to do with the hostname. If not, reject the mail.
# Check the helo after recipient. # If that doesn't work try to match Host's Domain with Helo's Domain # Next see if they are in the same /24 # After that try the MX deny hosts = !+relay_from_hosts message = Lookup of $sender_helo_name failed or did not match. See http://www.sput.nl/spam/ !verify = helo condition = \ ${if \ and {\ {!eq \ {${extract{-2}{.}{${lc:$sender_host_name}}}}\ {${extract{-2}{.}{${lc:$sender_helo_name}}}}\ }\ {!match \ {${lookup dnsdb{a=$sender_helo_name}{$value}fail}}\ {\ ${extract{1}{.}{$sender_host_address}}\.\ ${extract{2}{.}{$sender_host_address}}\.\ ${extract{3}{.}{$sender_host_address}}\.\ }\ }\ {!match \ {${lc:${lookup dnsdb{mx=$sender_helo_name}{$value}fail}}}\ {${lc:$sender_host_name}}\ }\ }\ {yes}{no}}You may need to create a whitelist for badly configured hosts. One way of doing this, is adding entries to /etc/hosts. You need order hosts,bind in your /etc/resolv.conf or /etc/host.conf to make this work;
Ip_Address Host_Name Helo_NameForged Yahoo email addresses are a major spam source. Unfortunately, Yahoo doesn't publish SPF records.
deny message = This is a fake Yahoo mail. See http://www.sput.nl/spam/ condition = \ ${if \ and {\ {eq \ {$sender_address_domain}\ {yahoo.com}\ }\ {!match \ {$sender_host_name}\ {\N^.+\.yahoo\.com$\N}\ }\ }\ {yes}{no}}A local (rather then DNS based) blacklist;
deny message = sender envelope address $sender_address is locally blacklisted here. See http://www.sput.nl/spam/ !acl = acl_whitelist_local_deny senders = ${if exists{CONFDIR/local_sender_blacklist}\ {CONFDIR/local_sender_blacklist}\ {}}Various DNS based blacklists
# Check IP address in DNS based blacklists deny hosts = !+rbl_white_hosts message = Host is listed in $dnslist_domain. dnslists = \ virbl.dnsbl.bit.nl : \ list.dsbl.org : \ relays.ordb.org : \ dnsbl.sorbs.net : \ bl.spamcop.net : \ sbl.spamhaus.org : \ xbl.spamhaus.org #relays.visi.com # Check hostname in domain DNS based blacklists deny message = Host name is listed in $dnslist_domain. hosts = !+rbl_white_hosts dnslists = \ bogusmx.rfc-ignorant.org/$sender_host_name : \ dsn.rfc-ignorant.org/$sender_host_name : \ postmaster.rfc-ignorant.org/$sender_host_name : \ abuse.rfc-ignorant.org/$sender_host_nameHelo
# Check helo in domain DNS based blacklists deny message = Helo is listed in $dnslist_domain. hosts = !+rbl_white_hosts dnslists = \ abuse.rfc-ignorant.org/$sender_helo_name : \ bogusmx.rfc-ignorant.org/$sender_helo_name : \ dsn.rfc-ignorant.org/$sender_helo_name : \ postmaster.rfc-ignorant.org/$sender_helo_name: \ abuse.rfc-ignorant.org/$sender_helo_nameAnd address
# Check email address domain in DNS based blacklists deny hosts = !+rbl_white_hosts senders = ! : message = Domain is listed in $dnslist_domain. dnslists = \ bogusmx.rfc-ignorant.org/$sender_address_domain : \ dsn.rfc-ignorant.org/$sender_address_domain : \ postmaster.rfc-ignorant.org/$sender_address_domain : \ abuse.rfc-ignorant.org/$sender_address_domainIf you want mail from really cheap ISPs, don't use abuse- and postmaster.rfc-ignorant.org
The 'mx_domains' option is a bit too strict for my taste. The stuff below does something similar, but only for incoming mail and not for DSN's.
# There has to be an MX, except in case of DSN deny message = No MX for envelope sender domain $sender_address_domain. See http://www.sput.nl/spam/ hosts = ! : !+relay_from_hosts senders = ! : condition = ${if eq\ {${lookup dnsdb{mx=$sender_address_domain}{$value}fail}}\ {fail}\ {yes}{no}}And the MX should be a hostname, not an IP address.
# The MX has to be a hostname. deny message = MX for transport sender domain $sender_address_domain should be FQDN. See http://www.sput.nl/spam/ hosts = ! : !+relay_from_hosts senders = ! : condition = ${if !match\ {${lookup dnsdb{mx=$sender_address_domain}{$value}fail}}\ {\N.*[A-Za-z].*\..*[A-Za-z].*\N}\ {yes}{no}}Keep in mind that the above MX tests may result in a lot of false positives. They are also in violation of RFCs.
A callout verification. This also checks the existence of postmaster.
# This test is done after blacklists deny !verify = sender/callout=postmaster,100s,random message = No verifiable envelope sender address. See http://www.sput.nl/spam/A combination of a callout and a postmaster check doesn't work with Hotmail. This is caused by a reset between the two on which Hotmail terminates the connection. If you want to do callouts on Hotmail, use a separate callout.
The stuff below checks if the remote MX accepts mail for random addresses. Non whitelisted hosts get rejected.
# A warn if random test succeeds warn hosts = ! : !+relay_from_hosts senders = ! : message = Envelope MX accepts mail for random addresses. See http://www.sput.nl/spam/ #set acl_m7 = $sender_address_domain #set acl_m7 = ${run{/usr/local/sbin/chckcal.pl $acl_m7}} set acl_m7 = ${run{/usr/local/sbin/chckcal.pl $sender_address_domain}} condition = ${if eq {$runrc}{1}{true}{false}} # A deny for non whitelisted hosts deny hosts = ! : !+relay_from_hosts : !+rand_white_hosts senders = ! : !*@*.nl message = Envelope MX accepts mail for random addresses. See http://www.sput.nl/spam/ set acl_m7 = ${run{/usr/local/sbin/chckcal.pl $sender_address_domain}} condition = ${if eq {$runrc}{1}{true}{false}}I tried to have Exim read its own own callout cache, but didn't succeed. So I wrote a little Perl script instead;
#!/usr/bin/perl # Looks for 'random' domain in callout cache # The default return value $ret = 0; open (FILE, "/usr/sbin/exim_dumpdb /var/spool/exim4 callout |") or die "can't open $!"; while (<FILE>) { if ($_ =~ / ${ARGV[0]} .* random=accept /) { #print $_; $ret = 1; break; } } close(FILE); #print "$ret\n"; exit $retSPF Check.
# Just after callout, do a SPF check # Use 'spfquery' to obtain SPF status for this particular sender/host. # If the return code of that command is 1, this is an unauthorised sender. # deny message = [SPF] $sender_host_address is not allowed to send mail \ from $sender_address_domain. senders = ! : hosts = ! : !+relay_from_hosts #log_message = SPF check failed. set acl_m9 = -ipv4=$sender_host_address \ -sender=$sender_address \ -helo=$sender_helo_name set acl_m9 = ${run{/usr/bin/spfquery $acl_m9}} condition = ${if eq {$runrc}{1}{true}{false}}
deny message = Message headers fail syntax check # !acl = acl_whitelist_local_deny !verify = header_syntaxAnd a home made syntax check.
From: "=?UTF-8?Q?Andr=C3=A9?=" <andre@example.com>After all, without the 'UTF-8' bit, your MUA wouldn' know how to interpret the non ASCII chars.
# More syntax: Non ASCII deny message = Message headers contain non ASCII chars. condition = \ ${if \ or {\ {match{$rh_bcc:}{\N[\x80-\xff]\N}}\ {match{$rh_cc:}{\N[\x80-\xff]\N}}\ {match{$rh_from:}{\N[\x80-\xff]\N}}\ {match{$rh_reply-to:}{\N[\x80-\xff]\N}}\ {match{$rh_sender:}{\N[\x80-\xff]\N}}\ {match{$rh_subject:}{\N[\x80-\xff]\N}}\ {match{$rh_to:}{\N[\x80-\xff]\N}}\ }\ {yes}{no}}If you administer a lot of boxes which all forward their postmaster mail to you, it's probably a good idea to accept mail that was accepted by those systems;
accept hosts = Host_List_Of_My_Boxes condition = \ ${if !match{$h_to:}\ {\N<?postmaster@.+>?\N}\ {yes}{no}}Don't accept mail from Some_User@localhost.localdomain
# A domain can't be localhost or localdomain deny message = ${domain:$h_from:} is a silly domain. condition = ${if match\ {${domain:$h_from:}}\ {\N^(localhost|localhost\.localdomain|localdomain)$\N}\ {yes}{no}}Below a way to use the envelope blacklist for content. The blacklist needs to exist;
# Blacklist unreachable sender before h_from: verification deny message = Sender content address $h_from: is locally blacklisted here. See http://www.sput.nl/spam/ condition = \ ${lookup{${address:$h_from:}}\ nwildlsearch {/etc/exim4/local_sender_blacklist}\ {yes}{no}}Apply DNS based blacklists to the content from address.
# Blacklist based on domain deny hosts = !+rbl_white_hosts message = Sender content domain is listed in $dnslist_domain dnslists = \ bogusmx.rfc-ignorant.org/${domain:$h_from:} : \ dsn.rfc-ignorant.org/${domain:$h_from:} : \ postmaster.rfc-ignorant.org/${domain:$h_from:} : \ abuse.rfc-ignorant.org/${domain:$h_from:}Spammers will often use a content domain for which there is no MX. Usually there is a host with the domain name, but it doesn't accept SMTP connections. This will lead to a defer for each delivery attempt. By checking the MX, this type of mail will be rejected immediately.
# There has to be an MX, except in case of DSN deny message = No MX for content sender domain ${domain:$h_from:}. See http://www.sput.nl/spam/ hosts = ! : !+relay_from_hosts senders = ! : condition = ${if eq\ {${lookup dnsdb{mx=${domain:$h_from:}}{$value}fail}}\ {fail}\ {yes}{no}}And the MX should be a hostname, not an IP address.
# And the MX has to be a hostname. deny message = MX for content sender domain ${domain:$h_from:} should be FQDN. See http://www.sput.nl/spam/ hosts = ! : !+relay_from_hosts senders = ! : condition = ${if !match\ {${lookup dnsdb{mx=${domain:$h_from:}}{$value}fail}}\ {\N.*[A-Za-z].*\..*[A-Za-z].*\N}\ {yes}{no}}Keep in mind that the above MX tests may result in a lot of false positives. They are also in violation of RFCs.
And a callout verification
# require that there is a verifiable sender address in at least # one of the 'Sender:', 'Reply-To:', or 'From:' header lines. deny message = No verifiable sender address in message headers. See http://www.sput.nl/spam/ # !acl = acl_whitelist_local_deny !verify = header_sender/callout=postmaster,100s,randomIf you want Hotmail use this instead;
# This one doesn't test postmaster deny message = No verifiable sender address in message headers. See http://www.sput.nl/spam/ !acl = acl_whitelist_local_deny !verify = header_sender/calloutThe stuff below checks if the remote MX accepts mail for random addresses. Non whitelisted hosts get rejected.
# A warn if random test succeeds warn hosts = ! : !+relay_from_hosts senders = ! : message = Content MX accepts mail for random addresses. See http://www.sput.nl/spam/ #set acl_m7 = $sender_address_domain #set acl_m7 = ${run{/usr/local/sbin/chckcal.pl $acl_m7}} set acl_m7 = ${run{/usr/local/sbin/chckcal.pl ${domain:$h_from:}}} condition = ${if eq {$runrc}{1}{true}{false}} # A deny for non whitelisted hosts deny hosts = ! : !+relay_from_hosts : !+rand_white_hosts senders = ! : !*@*.nl message = Content MX accepts mail for random addresses. See http://www.sput.nl/spam/ set acl_m7 = ${run{/usr/local/sbin/chckcal.pl ${domain:$h_from:}}} condition = ${if eq {$runrc}{1}{true}{false}}Require a message id.
# deny no Message-Id deny message = RFC compliant Message-Id required. See http://www.sput.nl/spam/ condition = \ ${if !match{$h_message-id:}\ {\N<.+@.+>\N}\ {yes}{no}}An other identity theft test
# Deny fake Message-Id deny hosts = ! : !+relay_from_hosts message = RFC compliant Message-Id required. See http://www.sput.nl/spam/ condition = \ ${if match{$h_message-id:}\ {\N^<.+@(.+\.)?sput\.nl>$\N}\ {yes}{no}}Some spammers base64 their entire message to avoid scanning.
# Deny 'attachment' only deny message = Plain text required. See http://www.sput.nl/spam/ condition = ${if eq\ {$h_content-transfer-encoding:}\ {base64}\ {yes}{no}}In my experience, only spammers use CP-1252. But maybe your experience is different.
# Block proprietary charsets deny message = Unsupported character set. See http://www.sput.nl/spam/ condition = \ ${if \ and {\ {match\ {${lc:$h_content-type:}}\ {\Ncharset\N}\ }\ {!match\ {${lc:$h_content-type:}}\ {\N(us-ascii|iso-?8859-15?|utf-8)\N}\ }\ }\ {yes}{no}}More identity theft checks
# Block fake bounces on ip address deny hosts = !+relay_from_hosts senders = : message = This is a fake (joe job) or sub standard (lacking original headers) DSN. See http://www.sput.nl/spam/ condition = \ ${if !match{${lc:$message_body}}\ {\N( |^)received: from .+\.sput\.nl.+213\.84\.159\.78\N}\ {yes}{no}} # Block fake bounces on mesg-id deny hosts = !+relay_from_hosts senders = : message = This is a fake (joe job) or sub standard (lacking original headers) DSN. See http://www.sput.nl/spam/ condition = \ ${if !match{${lc:$message_body}}\ {\N( |^)message-id: <.+@(.+\.)?sput\.nl>( |$)\N}\ {yes}{no}}Is the biz TLD used for anything other then spam? I don't think so.
# Block .biz links deny message = Use of the biz TLD is very bad taste. See http://www.sput.nl/spam/ condition = \ ${if match{${lc:$message_body}}\ {\N<a\ href=(\&|\0x27)?http://.*\.biz\N}\ {yes}{no}}HTML mail sux.
# Block HTML, except DSN's # Content-type based deny hosts = ! : senders = ! : message = HTML mail not wanted here. See http://www.sput.nl/spam/ condition = \ ${if \ and {\ {match{${lc:$h_content-type:}}\ {\Nmultipart\N}}\ {match{${lc:$message_body}}\ {\N --.* content-type: text/html\N}}\ {!match{${lc:$message_body}}\ {\N name=\N}}\ {!match{${lc:$message_body}}\ {\N filename=\N}}\ }\ {yes}{no}}
# Block HTML, except DSN's # Content based deny hosts = ! : senders = ! : message = HTML mail not wanted here. See http://www.sput.nl/spam/ condition = \ ${if \ or {\ {match{${lc:$message_body}}\ {\N<html\N}}\ {match{${lc:$message_body}}\ {\N<head\N}}\ {match{${lc:$message_body}}\ {\N<meta\N}}\ {match{${lc:$message_body}}\ {\N<title\N}}\ {match{${lc:$message_body}}\ {\N<body\N}}\ }\ {yes}{no}} condition = \ ${if \ or {\ {match{${lc:$message_body}}\ {\N<font\N}}\ {match{${lc:$message_body}}\ {\N<a\ href=\N}}\ {match{${lc:$message_body}}\ {\N<img\ src=\N}}\ {match{${lc:$message_body}}\ {\N<br>\N}}\ }\ {yes}{no}}Check the max message size.
# enforce a message-size limit deny message = Message size $message_size is larger than limit of MESSAGE_SIZE_LIMIT See http://www.sput.nl/spam/ condition = ${if >{$message_size}{MESSAGE_SIZE_LIMIT}{yes}{no}}Refuse broken attachments
# Scan stuff deny message = This message contains malformed MIME $demime_reason demime = * condition = ${if >{$demime_errorlevel}{2}{1}{0}}More attachments I don't want. Edit this to suit your needs.
deny message = Attachment has unsupported file format .$found_extension try text or PDF instead. See http://www.sput.nl/spam/ demime = bat:btm:cmd:com:cpl:dll:doc:exe:lnk:msi:pif:ppt:prf:rar:reg:scr:vb:vbs:url:xls deny message = Try gzip, bzip or tar instead of zip demime = zipVirus scanner
deny message = Message contains a virus or other harmful content ($malware_name) # demime = * malware = *SpamAssassin stuff
# Don't spam check local generated mail # (Comment out for spam check test purposes) accept hosts = : +relay_from_hosts # Don't spam filter abuse accept condition = \ ${if \ and {\ {match{$recipients}{\N<?(abuse|postmaster)@(.+\.)?sput\.nl>?\N}}\ {match{$h_to:}{\N>?(abuse|postmaster)@(.+\.)?sput\.nl<?\N}}\ }\ {yes}{no}} warn message = X-Spam-Score: $spam_score ($spam_bar) condition = ${if <{$message_size}{80k}{1}{0}} spam = spamd:true condition = ${if >{$spam_score_int}{40}{1}{0}} warn message = X-Spam-Report: $spam_report condition = ${if <{$message_size}{80k}{1}{0}} spam = spamd:true condition = ${if >{$spam_score_int}{40}{1}{0}} deny message = This message scored $spam_score spam points. See http://www.sput.nl/spam/ condition = ${if <{$message_size}{80k}{1}{0}} spam = spamd:true condition = ${if >{$spam_score_int}{50}{1}{0}}
# ACL that is used after the VRFY command check_vrfy: accept
# ignore private rfc1918 and APIPA addresses #ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 192.168.0.0/16 :\ # 172.16.0.0/12 : 10.0.0.0/8 : 169.254.0.0/16 ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 255.255.255.255 : \ 172.16.0.0/12 : 10.0.0.0/8 : 169.254.0.0/16I added '255.255.255.255' because it seemed like a good idea.
Alternatively use;
# ignore private rfc1918 and APIPA addresses #ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 : 192.168.0.0/16 :\ # 172.16.0.0/12 : 10.0.0.0/8 : 169.254.0.0/16 ignore_target_hosts = !192.168.1.0/24 : 0.0.0.0 : 127.0.0.0/8 : 255.255.255.255 : \ 192.168.0.0/16 : 172.16.0.0/12 : 10.0.0.0/8 : 169.254.0.0/16Adapt '!192.168.1.0/24' to suit your needs.
headers_add = \ X-message-flag: In case of problems see Url_To_Your_spam_policyThe following will change the outgoing helo;
helo_data = ns.sput.nlAdapt 'ns.sput.nl' to suit your needs.
#! /bin/sh # Spf init script test -f /usr/sbin/spfd || exit 0 set -e case "$1" in start) echo -n "Starting SPF Mail Filter Daemon: " ( /usr/sbin/spfd -port=5970 -setuser=spfd -setgroup=spfd ) & echo "spfd." ;; stop) echo -n "Stopping SPF Mail Filter Daemon: " killall spfd sleep 1 killall -9 spfd echo "spfd." ;; *) echo "Usage: spf {start|stop}" >&2 exit 1 ;; esac exit 0To run as a non privileged user, create system user and group spfd
You also need to create various /etc/rc* symlinks;
rc0.d: K19spf -> ../init.d/spf rc1.d: K19spf -> ../init.d/spf Rc2.d: S19spf -> ../init.d/spf rc3.d: S19spf -> ../init.d/spf rc4.d: S19spf -> ../init.d/spf rc5.d: S19spf -> ../init.d/spf rc6.d: K19spf -> ../init.d/spfAdding spfd to /etc/services looks nice in netstat;
# Local services spamd 783/tcp # SpamAssassin clamd 3310/tcp # Clam Anti Virus spfd 5970/tcp # SPF
ENABLED=1 OPTIONS="--create-prefs --max-children 5 --helper-home-dir --username spamd" PIDFILE="/var/run/spamd/spamd.pid"Adding spamd to /etc/services looks nice in netstat;
# Local services spamd 783/tcp # SpamAssassin clamd 3310/tcp # Clam Anti Virus spfd 5970/tcp # SPFCreate system user and group spamd. /var/run/spamd/ should be owned spamd:spamd. You also need a spamd homedir, such as /home/spamd/ or /var/lib/spamd/. Any local configuration stuff you put in /etc/spamassassin/local.cf;
Block HTML only mail, switch on auto whitelist, tell razor where its config is and supply sensible contact info;
# HTML only sux score MIME_HTML_ONLY 10.0 use_auto_whitelist 1 # Location of razor.conf razor_config /home/spamd/.razor/razor-agent.conf # Sensible contact report_contact postmaster@example.com
# Use ~spamd/ razorhome = /home/spamd/.razor
In the RCPT ACL just put an accept statement;
accept: senders = jdoe@example.comFor the DATA ACL, do the following; Create an '/etc/exim4/conf.d/acl/25_exim4-config_whitelist_rcpt'. In this file put something like;
acl_whitelist_rcpt: accept condition = \ ${if match\ {$recipients}\ {\N<?jdoe@example\.com>?\N}\ {yes}{no}}Replace 'jdoe@example.com' with the desired RCPT email address.
/etc/cron.daily/spamassassin: Last-Modified: Fri, 06 May 2005 23:10:22 GMT ETag: "2fe3375e44faf197a8a9c2cf8c380735" Content-Length: 109543 Restarting SpamAssassin Mail Filter Daemon: spamd.Squid log entries should look somewhat like;
1115440296.709 625 localhost TCP_REFRESH_MISS/200 109914 GET http://www.timj.co.uk/linux/bogus-virus-warnings.cf - DIRECT/212.69.37.57 text/plainWhen the file was changed.
1115353868.292 202 localhost TCP_REFRESH_HIT/304 239 GET http://www.timj.co.uk/linux/bogus-virus-warnings.cf - DIRECT/212.69.37.57 -When it didn't change.