Setting Up A Mail Server Using Exim4, Clamav, Dovecot, SpamAssassin And Many More On Debian Lenny - Page 3
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, [email protected] is an alias for [email protected] and [email protected] is an alias for both, [email protected] and [email protected].
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