I needed to install some incoming mail servers (MX servers) to filter emails before delivering them to customers servers. So the need is to accept mails for a fixed list of domains, check for viruses and spams, then route them to customers servers for delivery.

The distribution is Debian 6, the mailserver is Exim. The antivirus check is done by ClamAV and the antispam with Spamassassin + Pyzor + Razor + DCC + DNSBL. I get the list of domains from the f*cking OSS/BSS/whatever software.

It all begins with a standard Debian installation, just make sure you have lots of space for /var partition.

Next we install the needed packages:

 apt-get install exim4-daemon-heavy clamav-daemon clamav-unofficial-sigs spamassassin spamc sa-exim pyzor razor make gcc

Now it’s just a matter of some configuration.

ClamAV

Add to /etc/clamav/freshclam.conf :

 NotifyClamd /etc/clamav/clamd.conf

ClamAV user needs to be in Debian-exim group so it can reads files in spool :

 gpasswd -a clamav Debian-exim

Exim

Edit /etc/default/exim4:

 QUEUERUNNER='separate'

We’ll use a file for local domains, it will be empty but you never know:

 touch /etc/exim4/locals

Edit `/etc/exim4/exim4.conf :

 domainlist local_domains = @ : lsearch;/etc/exim4/locals

We’ll use a file for hosts allowed to relay through us no matter the domain, just put all the IP addresses or networks (one per line):

 echo "127.0.0.1/8" > /etc/exim4/relayfromhosts

Edit /etc/exim4/exim4.conf:

 hostlist   relay_from_hosts = localhost : /etc/exim4/relayfromhosts

We also have files for blacklisted “mail from” and “rcpt to” addresses:

 touch /etc/exim4/badmailfrom /etc/exim4/badrcptto

Now in /etc/exim4/exim4.conf, add this to the check_rcpt ACL:

 deny message = You are not welcome here.
 senders = lsearch;/etc/exim4/badmailfrom
 deny message = This recipient is blacklisted.
 recipients = lsearch;/etc/exim4/badrcptto

We get the domains from a URL, and we put all the domains in one file : /etc/exim4/rcpthosts . Edit /etc/exim4/exim4.conf:

 domainlist relay_to_domains = lsearch;/etc/exim4/rcpthosts

Now as this server will be one of the MX records for the domains, we need to tell the server where to send the mails. Our standard is to send mails for domain.tld to mail.domain.tld . So we simply add “domain.tld:mail.domain.tld” to /etc/exim4/smtproutes , for each domains.

Then we need to route those mails at the right palce before anything else, so add this first to the routers section in /etc/exim4/exim4.conf:

 smarthost:
  driver = manualroute
  transport = remote_smtp
  route_data = ${lookup{$domain}lsearch{/etc/exim4/smtproutes}}

Tell Exim where to find antivirus and antispam. Edit /etc/exim4/exim4.conf:

av_scanner = clamd:/var/run/clamav/clamd.ctl
 local_scan_path = /usr/lib/exim4/local_scan/sa-exim.so

And check the email for viruses. Add this to check_data ACL in /etc/exim4/exim4.conf:

 deny malware = *
 message = This message contains a virus ($malware_name).

SSL certificates if needed (for TLS and SSL connections):

 cd /etc/ssl
 openssl genrsa -aes256 -out exim.key 2048
 openssl rsa -in exim.key-with-pass -out exim.key
 openssl req -new -key exim.key -out exim.csr
 openssl x509 -req -days 9999 -in exim.csr -signkey exim.key -out exim.crt

Edit /etc/exim4/exim4.conf:

 tls_advertise_hosts = *
 tls_certificate = /etc/ssl/exim.crt
 tls_privatekey = /etc/ssl/exim.key
 tls_remember_esmtp = true

Antispam check will be done by Spamassassin with SA-Exim, so we need to edit /etc/exim4/sa-exim.conf . For now, we just remove extra chat and limit the process time to 4 minutes.

 SAEximDebug: 0
 SAtimeout: 240

We also make Exim do the checks of DNSBL because the earlier it’s done, the less time will be wasted on the mails. Add the following to check_rcpt ACL in /etc/exim4/exim4.conf:

 deny message = Host is listed in $dnslist_domain. Please contact your ISP.\n$dnslist_text
 log_message = rejected found in dnsbl $dnslist_domain
 dnslists = sbl-xbl.spamhaus.org : dnsbl.sorbs.net : bl.spamcop.net

Spamassassin

Enable spamassassin, enable the cron job which updates the rules and lower its priority. Edit /etc/default/spamassassin :

 ENABLED=1
 NICE="--nicelevel 15"
 CRON=1

Now just make some basic configuration to /etc/spamassassin/local.cf . Enable Bayes, set maximum size for the database (customize it if needed, it’s in bytes), enable dcc, enable pyzor.

 use_bayes 1
 bayes_auto_expire 0
 bayes_learn_to_journal 1
 bayes_journal_max_size 17179869184
 bayes_path /var/lib/spamassassin/bayes
 add_header all Status _YESNO_, hits=_HITS_ required=_REQD_ tests=_TESTS_
 bayes_auto_learn_threshold_spam 7.1
 use_dcc 1
 dcc_timeout 9
 dcc_path /usr/local/bin/dccproc
 use_pyzor 1
 pyzor_options --homedir /var/lib/spamassassin/.pyzor

Enable the DCC plugin in /etc/spamassassin/v310.pre :

 loadplugin Mail::SpamAssassin::Plugin::DCC

Initialize pyzor and apply changes to Spamassassin:

 pyzor --homedir /var/lib/spamassassin/.pyzor discover
 /etc/init.d/spamd restart

Install DCC:

cd /usr/src
wget http://www.rhyolite.com/dcc/source/dcc.tar.Z
tar -xzvf dcc.tar.Z
cd dcc-1.3.143
./configure && make && make install

Final config file for Exim

I realize it might be difficult to get a grasp of the whole exim4.conf file with the text above, so the final file should look like this file.

Statistics

If you want to have an overview of how many mails you receive, reject, why, etc, you can use eximstats to parse the logfile. The easy way to not miss something is to do it when the log is rotated (/etc/logrotate.d/exim4-base).

Graphs & Cacti

It would be nice to have some graphs to get a quicker overview of the statistics. Make the numbers available through SNMP would be great so it’s graphed easily by Cacti, but I’m to lazy to do this atm :)