User Tools

Site Tools


raspiserver2014:smtp

SMTP server

The SMTP (simple mail transfer protocol) server handles sending/receiving emails. In our case, it will also handle mailboxes, i.e. the temporary storage where emails reside until they are retrieved and/or deleted by the user.

We will set up a Postfix server for this task.

As MINIBIAN comes per default with exim, that needs to be removed:

aptitude remove exim4 exim4-base exim4-config exim4-daemon-light

Now we may install postfix and what goes with it:

aptitude install postfix

During installation, a few questions are asked:

  • type of install: internet with relay host
  • mail name: mail.hellsnet.lu (put in your own domain here)
  • relayhost: smtp.pt.lu (put in the SMTP server of your ISP here)

A basic, default configuration is now written to /etc/postfix.

mailbox format

To change the default use of mbox format for mailboxes to maildir, edit the main.cf file and add the line:

home_mailbox = Maildir/

With mbox, all emails are placed into one large file. Subfolders get their own mbox files. This may work nice enough when a single software accesses it (Thunderbird uses mbox for local storage), but in the context of a mailserver several software use it (smtp server, pop/imap server, …) which may cause less agreeable surprises (file corruption, …).

With Maildir, every email ends up in its own file. The filename can include flags which can then be directly interpreted. You may need more space than with mbox (typical issue when having many small files), but you generally have better performance all around.

procmail

Make sure procmail is installed:

which procmail

This should give you ”/usr/bin/procmail” as output.

If missing, install it:

aptitude install procmail

To enable procmail for the email delivery (e.g. for sorting emails into specific directories, based on some criteria), add the following in /etc/postfix/main.cf:

mailbox_command = procmail -a "$EXTENSION"

To keep Maildir format allright, you will need to define this in /etc/procmailrc:

DEFAULT=$HOME/Maildir/

local networks

The mynetworks variable is at this stage set to local interfaces only. You'll want to add your local network(s) here, i.e. at least your private IPv4 address range (typically something like 192.168.1.0/24 with an Alcatel Router or 192.168.178.0/24 with a Fritz!Box) and your IPv6 address [or subnet, if you have one] (e.g. [2001:7e8:2200:xx::]/64 - the v6 addresses need to be put in brackets).

mynetworks = 127.0.0.0/8 192.168.1.0/24 [::ffff:127.0.0.0]/104 [::1]/128

To enable IPv6 besides IPv4, you'll need to add a parameter in /etc/postfix/main.cf:

inet_protocols = all

mydestination

You need to define for which domain(s) this server should handle mailboxes by itself. This is done via the mydestination parameter.

mydestination = mail.hellsnet.lu, raspberrypi.hellsnet.lu, hellsnet.lu, raspberrypi, localhost.localdomain, localhost

SMTP authentication

For SMTP authentication, you'll want to add the following lines to /etc/postfix/main.cf:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth-client
smtpd_sasl_local_domain =
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination

TLS

TLS (transport layer security) will SSL-encrypt the SMTP traffic, in and out, if so chosen. Some configuration is already in place in the default configuration, using a “snake oil” certificate (auto-generated, self-signed). You can look at this default certificate using the command:

openssl x509 -in /etc/ssl/certs/ssl-cert-snakeoil.pem -text

The name used here is for the server name you previously provided, which hardly fits our own domain - not so good. Since few mail clients will properly complain about self-signed certificates, there is little preventing you from using a no-cost self-generated self-signed certificate with the proper name, at least for hobbyist use. For production, a certificate signed by a well-known CA (certification authority) should be used.

You may read up on the older version of the server tutorial about x509 certificates.

Here to save time, we'll just use that snakeoil certificate.

Go on with inserting the following code in /etc/postfix/main.cf - careful, some parameters are already present, search for “TLS parameters”:

smtpd_tls_auth_only = no
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtp_tls_note_starttls_offer = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
#skip following, already there
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
myhostname = serverlinux.<mydomain>

This will enable TLS specifically for incoming connections.

enable SMTP auth for your relayhost

We already configured our relayhost (smtp.pt.lu). To enable SMTP auth for this, we need some additional configuration:

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/saslpw
smtp_sasl_security_options =

The last line enables plaintext passwords, which is not default for SASL.

We now need to create that saslpw file and hash it. Its format is:

host id:pw

The host part here needs to be identical to the relayhost. So, you'll end up with:

smtp.pt.lu <yourptlogin>:<yourptmailpassword>

To generate the hash, use

postmap saslpw

Now, after a restart of postfix, your emails should be forwarded with SMTP auth.

configuring SASL

A component still missing is the SASL authentication. For this, we will need to install dovecot-common.

aptitude install dovecot-common

Unlike for older versions, where the dovecot configuration resided entirely in /etc/dovecot/dovecot.conf, it has been split up in a number of files under /etc/dovecot/conf.d.

To enable postfix to authenticate users, we need to touch the configuration in 10-master.conf. Navigate to “Postfix smtp-auth”. There, uncomment the few lines and change as follows:

service auth {
   ...
   # Postfix smtp-auth
   unix_listener /var/spool/postfix/private/auth-client {
     mode = 0660
     user = postfix
     group = postfix
   }
   ...
}

Be careful here - the path is changed from default!

To enable Outlook users, in 10-auth.conf you'll have to add the login mechanism:

auth_mechanisms = plain login

Once restarted, dovecot should provide proper SASL authentication to postfix.

/etc/init.d/dovecot restart

filtering

We will integrate spamassassin (antispam) and clamav (antivirus) with postfix. We will use amavisd-new as a wrapper between postfix and other filters. Additionally, postfix can pass messages to lightweight external filters, so as to be able to filter out unwanted messages before handing them to the more resource intensive filters. Two such external filters are dkim-filter and python-policyd-spf.

  • Amavisd-new is a wrapper program that can call any number of content filtering programs for spam detection, antivirus, etc.
  • Spamassassin uses a number of ways to determine whether a message is SPAM or HAM, based on message contents.
  • ClamAV is an open source antivirus application.
  • dkim-filter implements a sendmail milter for DKIM
  • python-policyd-spf does SPF (Sender Policy Framework) checking with postfix

The way things work:

  • a message comes in to postfix
  • postfix passes it through external filters (here: dkim-filter and python-policyd-spf)
  • amavisd-new then processes the message
  • ClamAV will scan for viruses
  • spamassassin will check for spam-status and inform thereof via X header, allowing amavisd-new to act accordingly.

legalities / practicalities on filtering

A note on legalities/practicalities: due to the risk of false positives (legitimate mail being tagged as virus, spam), you shouldn't accept and thereafter just delete such messages unless your users explicity approve of such a policy. If you're in an organisation, have the collaborators sign an IT policy document specifying such things. Better to refuse the message outright, so the sender gets informed.

In case of doubt, especially if the message is already accepted into the mailsystem and the SMTP connection closed, flag the messages and sort them into subfolders - this allows the end-users to verify the messages, and in case of a false positive, to retrieve it. It also keeps the inbox clean.

installation

To install the packages, use:

aptitude install amavisd-new spamassassin clamav-daemon
aptitude install dkim-filter postfix-policyd-spf-python

You will notice that these packages have a number of dependencies.

You may also install a couple of optional packages that integrate with spamassassin for better filter results:

aptitude install pyzor razor

You will also need some utilities to unpack some archives, so as to be able to filter attachments:

aptitude install arj cabextract cpio nomarch pax unzip zip

configuration

ClamAV

We won't need much configuration for ClamAV, as the defaults are all right. It will be necessary though to give clamav access to amavis-owned files, so it can access the messages to be scanned. This is done by adding the clamav user to the amavis group:

adduser clamav amavis

You may want to retrieve latest signatures via

freshclam

Don't forget to start your clamav-daemon:

/etc/init.d/clamav-daemon start

You may get a number of warnings about an outdated clamav engine - don't panic, it will get updated allright via your routine aptitude update/safe-upgrade. You haven't lost antivirus scanning even when this message appears.

SpamAssassin

Activate spamassassin by editing /etc/default/spamassassin and setting

ENABLED=1

You can now start spamassassin:

/etc/init.d/spamassassin start

amavisd-new

The files in /etc/amavis/conf.d/ are read in alphabetical order. Later configurations may replace previous definitions.

Start with enabling scanning by editing /etc/amavis/conf.d/15-content_filter_mode. Uncomment the 2x 2 lines with the bypass_*_checks_maps.

Bouncing spam is often a bad idea as the return addresses are often fake (google for “backscatter”). Therefore, Ubuntu overwrites the $final_spam_destiny, which is set to D_BOUNCE by Debian, to D_DISCARD. If you wish to deliver spams to the user's Inbox (so the user can put it into his spam folder), you'll want to edit /etc/amavis/conf.d/50-user to set $final_spam_destiny to D_PASS.

Other variables which are candidates for fiddling are $sa_tag_level_deflt, $sa_tag2_level_deflt, $sa_kill_level_deflt, $sa_dsn_cutoff_level. Be careful though to keep in a range where you don't get false positives.

Use this to always get spam info headers:

$sa_tag_level_deflt = -999;

You'll want to set the variable $myhostname in /etc/amavis/conf.d/50-user to your MX. Also, if you want to receive emails for multiple domains, you'll need to adapt the list @local_domains_acl.

$myhostname = '<yourserver>.<yourdomain>';
@local_domains_acl = ( "<yourdomain>", "<yourserver>.<yourdomain>" );

If you wish to keep all spams (in case of false positives), you'll have to change the default, which is to discard the spams. Change the file /etc/amavis/conf.d/50-user to add

$final_spam_destiny = D_PASS;

After configuration, amavisd-new needs to be restarted:

/etc/init.d/amavis restart
DKIM whitelist

If you wish, you can whitelist addresses from domains with valid Domain Keys. Some are pre-configured in /etc/amavis/conf.d/40-policy_banks. Note that this means that no filtering at all will take place for such addresses, which may not be what you want.

There are several ways to do this:

  • 'example.com' ⇒ 'WHITELIST',: will whitelist any address from the “example.com” domain.
  • '.example.com' ⇒ 'WHITELIST',: will whitelist any address from any subdomains of “example.com” that have a valid signature.
  • '.example.com/@example.com' ⇒ 'WHITELIST',: will whitelist subdomains of “example.com” that use the signature of example.com the parent domain.
  • './@example.com' ⇒ 'WHITELIST',: adds addresses that have a valid signature from “example.com”. This is usually used for discussion groups that sign thier messages.

A domain can also have multiple such configurations.

Don't forget to restart amavisd-new after such a reconfiguration.

postfix

To integrate these filters with postfix, /etc/postfix/main.cf needs an addition:

content_filter = smtp-amavis:[127.0.0.1]:10024

/etc/postfix/master.cf will take some modifications. Add the following to the end:

smtp-amavis     unix    -       -       -       -       2       smtp
        -o smtp_data_done_timeout=1200
        -o smtp_send_xforward_command=yes
        -o disable_dns_lookups=yes
        -o max_use=20

127.0.0.1:10025 inet    n       -       -       -       -       smtpd
        -o content_filter=
        -o local_recipient_maps=
        -o relay_recipient_maps=
        -o smtpd_restriction_classes=
        -o smtpd_delay_reject=no
        -o smtpd_client_restrictions=permit_mynetworks,reject
        -o smtpd_helo_restrictions=
        -o smtpd_sender_restrictions=
        -o smtpd_recipient_restrictions=permit_mynetworks,reject
        -o smtpd_data_restrictions=reject_unauth_pipelining
        -o smtpd_end_of_data_restrictions=
        -o mynetworks=127.0.0.0/8
        -o smtpd_error_sleep_time=0
        -o smtpd_soft_error_limit=1001
        -o smtpd_hard_error_limit=1000
        -o smtpd_client_connection_count_limit=0
        -o smtpd_client_connection_rate_limit=0
        -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

Be careful when copy/pasting: the lines starting with smtp-amavis resp. 127.0.0.1 must be left-aligned (no indentation)!

And add the following immediately below the “pickup” transport service:

         -o content_filter=
         -o receive_override_options=no_header_body_checks

This will prevent messages that are generated to report on spam from being classified as spam.

policyd-spf

To get proper SPF-based filtering, we need to integrate policyd-spf into postfix.

Add the following to /etc/postfix/master.cf:

policyd-spf  unix  -       n       n       -       0       spawn
  user=nobody argv=/usr/bin/python /usr/bin/policyd-spf /etc/postfix-policyd-spf-python/policyd-spf.conf

Configure the postfix policy service in /etc/postfix/main.cf:

smtpd_recipient_restrictions =
  ...
  reject_unauth_destination,check_policy_service unix:private/policyd-spf
  ...

policyd-spf_time_limit = 3600

Note: check_policy_service must come after reject_unauth_destination, else your system may become an open relay.

A restart of postfix is required at this point:

/etc/init.d/postfix restart

procmail

So as to sort spams into their own subfolder, and keeping the inbox clean, adapt the global /etc/procmailrc or insert into every user's ~/.procmailrc

DEFAULT=$HOME/Maildir/
DROPPRIVS="yes"
:0
* ^X-Spam-Status: Yes
$HOME/Maildir/.Spam/

The “dropprivs” make sure the files end up with the user's permissions, not root. The stuff after it filters based on the X-Spam-Status header - if it's a “yes”, the mail goes not into the inbox but the Spam subdirectory.

Please note the ”.Spam” - with a dot in front: if you omit it, the IMAP server won't see it correctly, and it won't be displayed in your IMAP clients (including webmail).

If now you want to cleanup the Spam subfolder automatically, you may run a cronjob regularly that will look for older files and remove them. An example command would be:

cd /home
find */Maildir/.Spam/new/ -ctime +7 -type f -exec /bin/rm {} \;

which would remove all files older than 7 days. If you want to allow for holidays, it may be a good idea to keep files up to maybe 3 weeks.

testing

First, test that amavisd-new SMTP is listening:

telnet localhost 10024
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 [127.0.0.1] ESMTP amavisd-new service ready
^]

When now sending an email to your server, it should contain headers such as:

X-Virus-Scanned:
X-Spam-Flag:
X-Spam-Score:
X-Spam-Level:
X-Spam-Status:

To deliver an email:

telnet localhost 25
helo pt.lu
mail from: <youremailaddress>@pt.lu
rcpt to: <youruser>@<yourdomain>
data
Subject: test

test
.
quit

If you wish to test how viruses or spams are handled, use the EICAR or GTUBE test strings:

EICAR: http://www.eicar.org/anti_virus_test_file.htm

GTUBE: http://spamassassin.apache.org/gtube/

NOTE

ClamAV is having trouble on my RasPi, which is why I simply took out the virus-filtering part in amavis - in the file /etc/amavis/conf.d/15-content_filter_mode, I commented out the two lines with bypass_virus_checks_maps.

The reasoning here is that viruses via email have largely come out of fashion, and are pretty much a non-issue on the Linux clients my family and I use.

further steps

aliases etc

You may want to configure an alias table or virtusertable.

To use the classic aliases file as known from sendmail, add in /etc/postfix/main.cf:

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

For a virtual user table:

virtual_alias_maps = hash:/etc/postfix/virtusertable, hash:/etc/postfix/virtual

Note: if you define this, make sure the files exist and the hashes were generated using postmap.

submission port

To enable the use of the submission port (TCP 587), uncomment the corresponding lines in /etc/postfix/master.cf and restart postfix. Verify that it works using

netstat -nlp | grep 587
raspiserver2014/smtp.txt · Last modified: 2014/02/23 16:45 (external edit)