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: catchall@middle.earth
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: sam@middle.earth
mailHost: 172.16.16.23
mailQuota: 102400
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: Gamji
uidNumber: 8
uid: sam
userPassword:: e01ENX1NeVV5M1BxaHkvWWVLaVpyMXlOaExBPT0=
mailLocalAddress: sam@middle.earth
mailLocalAddress: gamji@middle.earth
mailLocalAddress: shire@middle.earth
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: frodo@middle.earth
mailHost: 172.16.16.23
mailQuota: 102400
objectClass: inetLocalMailRecipient
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
sn: Baggins
uidNumber: 8
uid: frodo
userPassword:: e01ENX04UGlDRHVnWEdCMmNhRktnbDljTmpRPT0=
mailLocalAddress: frodo@middle.earth
mailLocalAddress: baggins@middle.earth
mailLocalAddress: shire@middle.earth
dn: uid=gmail,dc=middle.earth,ou=domains,dc=middle,dc=earth
cn: gmail
mail: alxgomz@gmail.com
mailHost: 172.16.16.23
mailRoutingAddress: alxgomz@gmail.com
objectClass: inetMailForwarder
objectClass: inetOrgPerson
objectClass: top
sn: alias to Gmail address
uid: gmail