RE: [exim] building mail gateway

Top Page
Delete this message
Reply to this message
Author: Hochstrasser Benedikt
Date:  
To: Genady Perchenko
CC: exim-users
Subject: RE: [exim] building mail gateway
<snip lots of posts>

Well, here's my config. "My" exim is acting as a mail gateway with some
added value such as antispam etc. Below is a slightly abridged exim.conf
(I spare you the obvious stuff):

# global settings
# I am a mail gateway, therefore no local domains
domainlist local_domains =
# but these are the domains I serve:
domainlist relay_to_domains = my.domain.com : myother.domain.com
# allow relaying from internal addresses
hostlist relay_from_hosts = 127.0.0.1 : 172.16.0.0/13 :
192.168.16.0/21
# as well as from authenticated senders (road warriors)
hostlist auth_relay_hosts = *

# these are the acl aliases below
acl_smtp_rcpt = check_recipient
acl_smtp_data = check_message
acl_smtp_helo = check_helo

<snip some stuff>

# look up all hosts
host_lookup = *
# allow even brainless senders such as Exchange et al
helo_accept_junk_hosts = *
# and allow underscores and @ in helo messages (broken clients)
helo_allow_chars = _@

# do not run ident calls
rfc1413_hosts =
rfc1413_query_timeout = 0s

<snip>

# omit the timestamp in syslog (it's doing that anyway)
syslog_timestamp = false
# and don't log everything, but log incoming connections
log_selector = -retry_defer -skip_delivery -queue_run +smtp_connection

# ACL settings

check_recipient:
accept hosts = :

accept hosts = +relay_from_hosts

  accept  hosts = +auth_relay_hosts
          message = authentication required
          authenticated = *


  deny    message = HELO/EHLO with my own ip address. You are not me.
          log_message  = HELO/EHLO my.ip
          condition    = ${if match {$sender_helo_name}{1.2.3.4}
{yes}{no}}


  deny    message = HELO/EHLO with my own domain name. You are not me.
          log_message  = HELO/EHLO my.domain.com
          condition    = ${if match {$sender_helo_name}{my.domain.com}
{yes}{no}}


  deny    message = HELO/EHLO with my own domain name. You are not me.
          log_message  = HELO/EHLO myother.domain.com
          condition    = ${if match
{$sender_helo_name}{myother.domain.com} {yes}{no}}


  # allow whitelisted, log 'em.
  warn   senders = /etc/exim/goodsenders
         log_message = whitelisted (goodsenders)


  accept senders = /etc/exim/goodsenders
         domains = +relay_to_domains


  # but deny blacklisted
  deny   hosts = +ignore_unknown : /etc/exim/badhosts
         message = host is blacklisted
         log_message = blacklisted (badhosts)


  # realtime black lists     
  deny   message = host is listed in $dnslist_domain
         log_message = blacklisted ($dnslist_domain)
         dnslists = sbl.spamhaus.org : dun.dnsrbl.net : relays.ordb.org


  # hand-crafted blacklist     
  deny   senders = @@partial-lsearch;/etc/exim/badsenders
         message = sender is blacklisted
         log_message = blacklisted (badsenders)

    
require verify = sender

accept recipients = postmaster@??? :
postmaster@???

  deny   message = unrouteable address
         !verify = recipient


  deny   message       = Faked Yahoo, so you must be spam.
         log_message   = Fake Yahoo
         senders       = *@yahoo.com
         condition     = ${if match
{$sender_host_name}{\Nyahoo.com$\N}{no}{yes}}

        
  deny   message       = Faked hotmail, so you must be spam.
         log_message   = Fake hotmail
         senders       = *@hotmail.com
         condition     = ${if match
{$sender_host_name}{\Nhotmail.com$\N}{no}{yes}}

                    
  deny   message       = Faked MSN, so you must be spam.
         log_message   = Fake MSN
         senders       = *@msn.com
         condition     = ${if match
{$sender_host_name}{\N(hotmail|msn).com$\N}{no}{yes}}

                            
  deny   message       = Faked AOL, so you must be spam.
         log_message   = Fake AOL
         senders       = *@aol.com
         condition     = ${if match
{$sender_host_name}{\Nmx.aol.com$\N}{no}{yes}}


  deny    message       = Restricted characters in address
          domains       = +local_domains : +relay_to_domains
          local_parts   = ^[.] : ^.*[@%!/|]


  deny    message       = Restricted characters in address
          domains       = !+local_domains : !+relay_to_domains
          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./


  accept  domains       = +relay_to_domains
          endpass
          verify        = recipient


# Reaching the end of the ACL causes a "deny", but we might as well
give
# an explicit message.

  deny    message       = relay not permitted


# not implemented yet
check_message:
accept

# same here
check_helo:
accept

# Routers
begin routers

# this is for outgoing mail
dnslookup:
driver = dnslookup
domains = ! +local_domains : ! +relay_to_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more

# this is for incoming mail
localdomains:
driver = manualroute
transport = local_smtp
domains = +relay_to_domains
route_list = * exchangeserver.my.domain.com :
exchangeserver.myother.domain.com byname
# allusers.txt contains an ldap-queried list (crontabbed every day) of
Active Directory
# recipients
condition =
${lookup{$local_part@$domain}lsearch{/etc/exim/allusers.txt} {yes} {no}
}

# check for redirection, else reject
reject:
driver = redirect
cannot_route_message = "$local_part@$domain: Recipient unknown."
data = ${lookup{$local_part}wildlsearch{/etc/exim/redirect.txt}}
no_more
    
<snip>

# Transports
begin transports

remote_smtp:
driver = smtp

# mailfilter contains a shell script "renattach -g | spamc" - renames
attachments,
# filters through SpamAssassin. Is there a way to pipe them directly in
the config
# file?

local_smtp:
driver = smtp
transport_filter = /usr/sbin/mailfilter

<snip>

# authentication
# the .passwd file is created with mini_httpd's htpasswd program;
probably Apache's
# will do as well. We only have one generic authentication password; I
didn't bother
# to do (expensive) ldap queries
begin authenticators

plain:
  driver = plaintext
  public_name = PLAIN
  server_condition = "\
    # $2 = Username | $3 = password
    ${if and {{!eq{$2}{}}{!eq{$3}{}} \
    {crypteq{$3}{${extract{1}{:} \ 
    {${lookup{$2}lsearch{/etc/exim/.passwd}{$value}{*:*}}}}}}}{1}{0}}"
  server_set_id = $2


login:
  driver = plaintext 
  public_name = LOGIN
  server_prompts = "Username:: : Password::"
  server_condition = "\   
    # $1 = Username | $2 = password
    ${if and {{!eq{$1}{}}{!eq{$2}{}} \
    {crypteq{$2}{${extract{1}{:} \ 
    {${lookup{$1}lsearch{/etc/exim/.passwd}{$value}{*:*}}}}}}}{1}{0}}" 
  server_set_id = $1

                    
# End of Exim configuration file

Yeah. More or less that's about it.
The last four week's statistics reveal this:

14491 connections
7646 rejected, of which
  160 rejected temporarily
  903 rejected (HELO my.ip)
  1112 rejected (HELO pentagroup.ch)
  39 rejected (HELO silion.ch)
  927 blacklisted (sbl.spamhaus.org)
  8 blacklisted (relays.ordb.org)
  0 blacklisted (dun.dnsrbl.net)
  1441 blacklisted (badhosts)
  827 blacklisted (badsenders)
  244 Fake Yahoo/MSN etc
  224 relaying prohibited
  1508 unknown recipient
  249 Sender verify failed
  2 Unrouteable address
8054 messages delivered, of which
  7475 individual messages of which
    996 were identified as spam


This means that roughly 50% of all mail was rejected at RCPT time
(thanks to the ACLs) and no "collateral spam" was generated with bounce
messages.

--
Good luck,
Ben