Setting Up A Mail Server Using Exim4, Clamav, Dovecot, SpamAssassin And Many More On Debian Lenny - Page 3

Want to support HowtoForge? Become a subscriber!
 
Submitted by alxgomz (Contact Author) (Forums) on Wed, 2010-09-22 15:56. ::

The Aliases:

 These are secondary addresses for a mailbox. They must belong to the same domain as destination address. One Alias can be added to several mailboxes, in which case all the mailboxes receive mails sent to the alias address. In the sample data, baggins@middle.earth is an alias for frodo@middle.earth and shire@middle.earth is an alias for both, frodo@middle.earth and sam@middle.earth.

To add an alias to an existing mailbox just add a mailLocalAddress attribute with the mail address of the alias.

The file /etc/exim4/conf.d/router/070_mailMEO_alias  is the router for such address: mailMEO_alias:

mailMEO_alias:
 driver = redirect
  debug_print = "R: locally aliased from $local_part@$domain"
  domains = +mailMEO_domains
  qualify_domain = MAILMEO_MAINDOMAIN
  check_ancestor = true
 
  local_parts = <\n ${sg{\
        ${sg{\
            ${lookup ldapm \
                {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
                ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?mailLocalAddress?one?\
                (&(objectClass=inetLocalMailRecipient)(objectClass=inetOrgPerson)(mailLocalAddress=$local_part@$domain))}\
            }}{([\\w\\-\\.]+)@([\\w\\-]+\\.)([\\w\\-]+)}{\$1}}\
        }{,}{\\n}}

  data = ${sg{\
        ${lookup ldapm \
            {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
            ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?uid?one?\
            (&(objectClass=inetLocalMailRecipient)(objectClass=inetOrgPerson)(mailLocalAddress=$local_part@$domain))}}\
        }{([\\w\-\.]+)}{\$1@$domain}\
    }

 

The Forwarders:

Forwarders are addresses that forward mails to one or several addresses. They are quite similar to aliases except that they can forward mails to addresses not belonging to their domains or even remote addresses. To create mail forwarders, create an LDAP entry under the domain entry following the template:

dn: uid=gmail,dc=middle.earth,ou=domains,dc=middle,dc=earth
cn: %FWD_LOCALPART%
mail: %DEST_MAILADDR%
mailHost: %IPADDR_OF_MAILSTORE%
mailRoutingAddress: %DEST_MAILADDR%
objectClass: inetMailForwarder
objectClass: inetOrgPerson
objectClass: top
sn: Alias address
uid: %FWD_LOCALPART%

The file /etc/exim4/conf.d/router/071_mailMEO_fwd this kind of address:

mailMEO_fwd_routes:
driver = redirect
  debug_print = "R: Forwarded from $local_part@$domain"
  domains = +mailMEO_domains
  qualify_domain = MAILMEO_MAINDOMAIN
  check_ancestor = true
  forbid_pipe = true
  forbid_file = true
  forbid_exim_filter = true
  local_parts = ${lookup ldap \
            {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
            ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?uid?one?\
            (&(uid=$local_part)(objectClass=inetOrgPerson)(objectClass=inetMailForwarder))}\
        }
  data = ${lookup ldap \
            {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
            ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?mailRoutingAddress?one?\
            (&(uid=$local_part)(objectClass=inetOrgPerson)(objectClass=inetMailForwarder))}\
        }

 

The Catchall:

Catchalls are kind of garbage mailboxes that will receive every mails sent to a domain whatever the localpart is. You can mix regular mailbox and catchall mailbox in a domain (of course only one catchall per domain is allowed). To add a catchaal address to a domain, add the posixAccount to the domain entry (and all the needed attributes), a mailLocalAddress and mailQuota attributes:

objectClass: posixAccount
mailLocalAddress: %CATCHALL_ADDR%
gidNumber: %gID%
homeDirectory: %MAILDIR_PATH%
uid: %CATCHALL_LOCALPART%
uidNumber: %UID%
userPassword:: %HASH_PASS_STR%
mailQuota: %KB%

The file /etc/exim4/conf.d/router/079_mailMEO_catchall defines catchall routing:

mailMEO_catchall: 
  driver = redirect
  debug_print = "R: domain catchall for $domain <- $local_part"
  domains = <\n ${sg{${lookup ldapm {\
    USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
    ldap:///ou=domains,dc=middle,dc=earth?associatedDomain?one?\
    (&(objectClass=inetLocalMailRecipient)(objectClass=posixAccount)(objectClass=dNSDomain)(mailHost=$primary_hostname))}}}{,}{\\n}}
  qualify_domain = MAILMEO_MAINDOMAIN
  data = ${lookup ldap \
        {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
        ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?uid?base?}\
    }

 

The Virtual Users:

Well... It's the mailbox that users will check for mails! To create a user add an LDAP entry under the domain following this template:

dn: uid=%LOCALPART%,dc=%DOMAIN%,ou=domains,dc=middle,dc=earth
cn: %SOMETHING_DESCRIPTIVE%
displayName: %SOMETHING_DESCRIPTIVE%
gidNumber: %GID%
givenName: %SOMETHING_DESCRIPTIVE%
homeDirectory: %MAILDIR_PATH%
mail: %EMAIL_ADDR%
mailHost: %IPADDR_OF_MAILSTORE%
mailQuota: %KB%
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: %SOMETHING_DESCRIPTIVE%
uidNumber: %UID
uid: %LOCALPART%
userPassword:: %HASH_PASS_STR%
mailLocalAddress: %EMAIL_ADDR%

Please note that the main email address *MUST* be set as a mailLocalAddress just like aliases.

Routing is done using the file /etc/exim4/conf.d/router/077_mailMEO_users:

mailMEO_virtual: 
  driver = accept
  debug_print = "R: mailMEO virtual for $local_part@$domain"
  domains = +mailMEO_domains
  local_parts = ${lookup ldap\
            {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
            ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?uid?sub?\
            (&(objectClass=inetLocalMailRecipient)(uid=$local_part))}\
        }
  transport = mailMEO_virtual_delivery

Once done with the routers we have to add several transports.

The first one obvious, it delivers mails in the mailboxes of virtual users. To do so we will use the dovecot LDA because it's reliable and natively implements cool stuffs like quota or sieve filtering (Dovecot rules!).

This is a typical example as described on dovecot wiki and is in the file /etc/exim4/conf.d/transport/50_mailMEO_dovecot:

mailMEO_virtual_delivery: 
  driver = pipe
  command = /usr/lib/dovecot/deliver -d $local_part@$domain  -f $sender_address
  message_prefix =
  message_suffix =
  delivery_date_add
  envelope_to_add
  return_path_add
  log_output
  user = mail
  temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78 

 

Spamassassin:

This router is used to check mails for spam using the spamassassin daemon.

spamcheck_router:
no_verify condition = ${if and { {<{$message_size}{90K}} {!def:header_X-Spam-Flag:} {!eq {$received_protocol}{spam-scanned}}} {1}{0}} driver = accept transport = spamcheck

The spamcheck transport is used to process mails in spamassassin daemon.

SA transport is configured in /etc/exim4/conf.d/transport/50_mailMEO_spamcheck:

spamcheck: 
    driver = pipe
    command = /usr/sbin/exim4 -oMr spam-scanned -bS
    use_bsmtp = true
    transport_filter = /usr/bin/spamc -u $local_part@$domain
    home_directory = "/dev/shm"
    current_directory = "/dev/shm"
    # must use a privileged user to set $received_protocol on the way back in!
    user = mail
    group = mail
    log_output = true
    return_fail_output = true
    return_path_add = false
    message_prefix =
    message_suffix =

Let's configure SpamAssassin while we are dealing with it.

Most of the config is stored in /etc/spamassassin/local.cf:

user_scores_dsn                 ldap://ldap.middle.earth/ou=domains,dc=middle,dc=earth?spamassassinUserPrefs?sub?(&(mailLocalAddress=__USERNAME__)(objectClass=inetLocalMailRecipient))
user_scores_ldap_username       uid=exim,dc=middle,dc=earth 
user_scores_ldap_password       eximmta
clear_headers
add_header all Flag _YESNO_
add_header spam Result _SCORE_/_REQD_ (_TESTS_)

With this config you can have specific settings for each user, just use the spamassassinUserPrefs attribute using the form 'item value'.

We have to enable spamd in /etc/default/spamassassin:

ENABLED=1 
OPTIONS="-x --ldap-config -u nobody --max-children 5"

... and start it.

sudo /etc/init.d/spamassassin restart

We can now restart exim as well:

sudo /etc/init.d/exim4 restart

At this point, mails can't be sent to the mailstore yet (dovecot must be configured... we'll do it later), and most of the security features are not implemented.

 

The MX server (faramir):

It's here where we will add security features.

As the MX server will do virus scanning too it needs to have volatile repository in the file /etc/apt/sources.list.d/volatile.list:

deb http://volatile.debian.org/debian-volatile lenny/volatile main

... and the backports for a newer dovecot version, in the /etc/apt/sources.list.d/backports.list:

deb http://backports.debian.org/debian-backports lenny-backports main

Update the apt database:

sudo apt-get update

We can now install the needed packages:

sudo apt-get install  clamav-daemon clamav-freshclam exim4-daemon-heavy libmail-spf-query-perl

sudo apt-get -t lenny-backports install dovecot-imapd dovecot-pop3d

Proceed with exim4 installation just like for the relay server.

The file /etc/exim4/conf.d/main/04_mailMEOmacrodefs defines the macros we will use in other config files:

ldap_default_servers = ldap.middle.earth
 # mailMEO macros definitions
.ifndef MAILMEO_DOMAINROOT
MAILMEO_DOMAINROOT = ou=domains,dc=middle,dc=earth
.endif

.ifndef MAILMEO_MAINDOMAIN
MAILMEO_MAINDOMAIN = ${lookup ldap {USER=userid=exim,dc=middle,dc=earth PASS=eximmta ldap:///MAILMEO_DOMAINROOT?dc?one?(associatedDomain=$domain)}}
.endif
domainlist mailMEO_domains = <\n ${sg{${lookup ldapm {\
    USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
    ldap:///MAILMEO_DOMAINROOT?associatedDomain?one?\
    (&(objectClass=inetLocalMailRecipient)(objectClass=dNSDomain))}}}{,}{\\n}}

.ifndef CHECK_RCPT_IP_DNSBLS
CHECK_RCPT_IP_DNSBLS = cbl.abuseat.org:dnsbl.njabl.org:sbl.spamhaus.org
.endif

.ifndef CHECK_RCPT_SPF
CHECK_RCPT_SPF = true
.endif

CHECK_RCPT_SPF enabled SPF checking at SMTP time, and reject mail for which spf check failed.

CHECK_RCPT_IP_DNSBL enables DNSBL lookups. The blacklists used here are trustworthy and should not list smarthosts of big MSP. As a consequence, we will choose to reject mails based on thoose DNSBL instead of just warn (which is the default in exin4). Go to the file /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt and change:

 .ifdef CHECK_RCPT_IP_DNSBLS
  warn
    message = X-Warning: $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
    log_message = $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
    dnslists = CHECK_RCPT_IP_DNSBLS
  .endif

to

.ifdef CHECK_RCPT_IP_DNSBLS
  deny
    message = Access denied: $sender_host_address is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
    dnslists = CHECK_RCPT_IP_DNSBLS
  .endif

We have to specify exim to accept the domains defined by mailMEO_domains in /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt: change

require
  message = relay not permitted
  domains = +local_domains : +relay_to_domains

to

require
  message = relay not permitted
  domains = +local_domains : +relay_to_domains : +mailMEO_domains

Now we enable virus scanning just like we did on the relay server in /etc/exim4/conf.d/main/02_exim4-config_options:

av_scanner = clamd:/var/run/clamav/clamd.ctl

Uncomment 3 lines in /etc/exim4/conf.d/acl/40_exim4-config_check_data:

deny
  malware = *
   message = This message was detected as possible malware ($malware_name).

Add user clamav to the Debian-exim group:

sudo adduser clamav Debian-exim

sudo /etc/init.d/clamav-daemon restart

The main purpose of  the MX server is to route mails to the mailstore server where the mailbox is hosted.

In Exim, routing can be done using the manualroute driver, which will send mails to remote hosts using SMTP.

We will needed 2 drivers of this kind to handle users accounts, aliases and forwarders on one side and catchall accounts on the other side.

All is in /etc/exim4/conf.d/router/075_mailMEOroutes:

mailMEO_routes: 
  debug_print = "R: $local_part@$domain routed with mailMEO_routes to $0"
  driver = manualroute
  domains = +mailMEO_domains
  transport = remote_smtp
  local_parts = <\n ${sg{\
    ${sg{\
        ${lookup ldapm \
            {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
            ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?mailLocalAddress?one?\
            (&(objectClass=inetLocalMailRecipient)(mailLocalAddress=$local_part@$domain))}\
        }}{([\\w\\-\\.]+)@([\\w\\-]+\\.)([\\w\\-]+)}{\$1}}\
        , ${lookup ldap \
            {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
            ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?uid?one?\
            (uid=$local_part)}}\
    }{,}{\\n}}
  route_data = ${lookup ldap \
    {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
    ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?mailHost?base?}}
  host_find_failed = defer
  same_domain_copy_routing = yes

mailMEO_catchall_routes:
  debug_print = "R: $local_part@$domain routed with mailMEO_catchall_route to $0"
  driver = manualroute
  domains = <\n ${sg{\
        ${lookup ldapm {\
            USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
            ldap:///MAILMEO_DOMAINROOT?associatedDomain?one?\
            (&(objectClass=inetLocalMailRecipient)(objectClass=posixAccount)(objectClass=dNSDomain))}}\
    }{,}{\\n}}
  transport = remote_smtp
  route_data = ${lookup ldap \
    {USER=userid=exim,dc=middle,dc=earth PASS=eximmta \
    ldap:///dc=MAILMEO_MAINDOMAIN,MAILMEO_DOMAINROOT?mailHost?base?}}
  host_find_failed = defer
  same_domain_copy_routing = yes

 A quick explanation: this router first validate the domain is stored in ldap, then it checks that the address exists and at last requests the hostname of the mail server where the mailbox sits.

We don't need to do anything else for the MX concerning the MTA part. So we restart exim and will come back later for the dovecot part.

sudo /etc/init.d/exim4 restart


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.