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

This howto describes one way to build a scalable, secure, full-featured mail platform. It offers virtual hosting of mailboxes in maildir format with support for quotas and server-side filtering, domain aliasing, address aliasing, address forwarding, catchall addresses. Relaying is secured with STARTTLS and SMTP-AUTH. Incoming mails are checked for viruses, spam, and checked against SPF policy and DNSBL.

In order to achieve scalabality the setup will be split accross 3 servers:

  • 1 MX server, where most of the security features sit (faramir.middle.earth)
  • 1 SMTP relay, to allow users to send mails to the outside world (ectelion.middle.earth)
  • 1 Mailstore server, where the mailbox sits (denetor.middle.earth)

Of course more MX can be added using DNS MX records to your domains, more relay servers can be added using DNS round-robin, and more mail stores can be added using mechanisms described in this howto. At the opposite you can merge easily the MX and relay part, or the relay and the mailstore part. Merging MX and mailstore involves some modifications.

 

Preliminary Note

In this howto we will assume you have a working Debian server. As well sudo is supposed to be installed on the systems and you must be a sudoer.

 

Configuring LDAP

The users' information will be stored in an LDAP directory. Here we will install it on the relay server.

First let's install the necessary packages:

 sudo apt-get install slapd ldap-utils

For the tutorial we will use the following LDAP parameters:

ldapBase: dc=middle,dc=earth

adminDn: cn=admin,dc=middle,dc=earth

adminPwd: thirdAge

In addition we will use a specific LDAP schema. Most of the attributes and objects are standards except one or two. Caution: as there are a lot of standard attributes you will have to take care none of them is defined twice.

So let's add the schema in openldap in /etc/ldap/schema/mailMEO.schema:

 attributetype ( 2.16.840.1.113730.3.1.13 
    NAME 'mailLocalAddress'
    DESC 'RFC822 email address of this recipient'
    EQUALITY caseIgnoreIA5Match
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

attributetype ( 2.16.840.1.113730.3.1.16
    NAME 'mailQuota'
    DESC 'Maiximal amount of disk space for a mailbox in kilobytes'
    EQUALITY integerMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )

attributetype ( 2.16.840.1.113730.3.1.18
    NAME 'mailHost'
    DESC 'FQDN of the SMTP/MTA of this recipient'
    EQUALITY caseIgnoreIA5Match
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
    SINGLE-VALUE )

attributetype ( 2.16.840.1.113730.3.1.22
    NAME 'mailCopyAddress'
    DESC 'RFC822 email shadow copy address'
    EQUALITY caseIgnoreIA5Match
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

attributetype ( 2.16.840.1.113730.3.1.47
    NAME 'mailRoutingAddress'
    DESC 'RFC822 routing address of this recipient'
    EQUALITY caseIgnoreIA5Match
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

attributetype ( 2.16.840.1.113730.3.1.49
    NAME 'spamassassinUserPrefs'
    DESC 'SpamAssassin user preferences'
    EQUALITY caseIgnoreIA5Match
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

objectclass ( 2.16.840.1.113730.3.2.147
    NAME 'inetLocalMailRecipient'
    DESC 'Internet local mail recipient'
    SUP top AUXILIARY
    MAY    ( mailLocalAddress $ mailHost $ mailRoutingAddress $ mailCopyAddress $ mailQuota $ spamassassinUserPrefs ) )
 
objectclass ( 2.16.840.1.113730.3.2.148
    NAME 'inetMailForwarder'
    DESC 'Internet mail Forward Address'
    SUP top AUXILIARY
    MAY    ( mailHost $ mailRoutingAddress ) )

Then make sure you add the needed schema in /etc/ldap/slapd.conf:

...
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/mailMEO.schema
...

... and check the suffix (debconf should have already configured it when you installed slapd):

suffix          "dc=middle,dc=earth"

Now we add few ACLs the daemons will need to bind to LDAP.

A readonly access to the userPassword attribute for dovecot:

access to attrs=userPassword,shadowLastChange 
        by dn="cn=admin,dc=middle,dc=earth" write
        by dn="uid=dovecot,dc=middle,dc=earth" read
        by anonymous auth
        by self write
        by * none

A readonly access to other attributes for exim and dovecot:

access to * 
        by dn="cn=admin,dc=middle,dc=earth" write
        by dn="uid=dovecot,dc=middle,dc=earth" read
        by dn="uid=exim,dc=middle,dc=earth" read
        by * read
        by anonymous none

The last ACL disables anonymous reads but enables reading (search) for every authenticated user, which you may not want.

We can now restart slapd for changes to take effect:

sudo /etc/init.d/slapd restart

We have to create the users of the previous ACL. To do it we will use the following user.ldif file:

dn: uid=exim,dc=middle,dc=earth
objectClass: account
objectClass: simpleSecurityObject
objectClass: top
uid: exim
userPassword:: e01ENX1hOElTeXAwV2hnVzFSVnhHd0hCNDF3PT0=

dn: uid=dovecot,dc=middle,dc=earth
objectClass: account
objectClass: simpleSecurityObject
objectClass: top
uid: dovecot
userPassword:: e01ENX1yZGp2Q1lPNmtDRm1scXAyVWQwa0xBPT0=

The user/pass are:

dovecot/dovecotpopper
exim4/eximmta 

To  feed the directory type:

ldapadd -x -D cn=admin,dc=middle,dc=earth -W < users.ldif

Here is another ldif file that contains sample data (caution, this sample contains IP addresses that won't suit your setup, change them manually):

dn: ou=domains,dc=middle,dc=earth
objectClass: organizationalUnit
objectClass: top
ou: domains

dn: dc=middle.earth,ou=domains,dc=middle,dc=earth
dc: middle.earth
objectClass: dNSDomain
objectClass: top
objectClass: inetLocalMailRecipient
objectClass: domainRelatedObject
objectClass: posixAccount
mailLocalAddress: [email protected]
cn: catchall
gidNumber: 8
homeDirectory: /var/mail/middle.earth/c/catchall
uid: catchall
uidNumber: 8
userPassword:: e01ENX1EV3RteGErOFROanJKNUFXZWt1Z0tBPT0=
mailQuota: 102400
mailHost: denetor.middle.earth
associatedDomain: middle.earth
associatedDomain: lotr.middle.earth

dn: uid=sam,dc=middle.earth,ou=domains,dc=middle,dc=earth
cn: sam
displayName: Sam Gamji
gidNumber: 8
homeDirectory: /var/mail/middle.earth/s/sam
mail: [email protected]
mailHost: 172.16.16.23
mailQuota: 102400
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: Gamji
uidNumber: 8
uid: sam
userPassword:: e01ENX1NeVV5M1BxaHkvWWVLaVpyMXlOaExBPT0=
mailLocalAddress: [email protected]
mailLocalAddress: [email protected]
mailLocalAddress: [email protected]

dn: uid=frodo,dc=middle.earth,ou=domains,dc=middle,dc=earth
cn: frodo
displayName: Frodo Baggins
gidNumber: 8
givenName: Frodo
homeDirectory: /var/mail/middle.earth/f/frodo
mail: [email protected]
mailHost: 172.16.16.23
mailQuota: 102400
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: Baggins
uidNumber: 8
uid: frodo
userPassword:: e01ENX04UGlDRHVnWEdCMmNhRktnbDljTmpRPT0=
mailLocalAddress: [email protected]
mailLocalAddress: [email protected]
mailLocalAddress: [email protected]

dn: uid=gmail,dc=middle.earth,ou=domains,dc=middle,dc=earth
cn: gmail
mail: [email protected]
mailHost: 172.16.16.23
mailRoutingAddress: [email protected]
objectClass: inetMailForwarder
objectClass: inetOrgPerson
objectClass: top
sn: alias to Gmail address
uid: gmail
Share this page:

4 Comment(s)