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:
A basic, default configuration is now written to /etc/postfix.
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.
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/
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
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
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 (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.
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.
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
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.
The way things work:
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.
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
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.
Activate spamassassin by editing /etc/default/spamassassin and setting
ENABLED=1
You can now start spamassassin:
/etc/init.d/spamassassin start
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
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:
A domain can also have multiple such configurations.
Don't forget to restart amavisd-new after such a reconfiguration.
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.
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
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.
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:
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.
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.
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