This tutorial shows you how to install Postfix (2.9.6) with Dovecot (2.0.19), the manage tool Vimbadmin (2.2.2) and SpamAssassin (3.3.2) on Ubuntu Server 12.04 (I got feedback that this tutorial still works for Ubuntu Server 14.04).
If you are using Chef, “Install ViMbAdmin with Chef” can speed things up a bit.
Perform all actions as root!
You should check that your server has a valid fqdn hostname (complete with the domain part):
hostname --fqd
If you get something like “localhost” or “mail” it’s NOT OK and you have to do some work on /etc/hosts and /etc/hostname
Check your time with the command:
date
and eventually adjust the time zone as needed (this is important for logging and mail):
dpkg-reconfigure tzdata
apt-get install postfix postfix-mysql dovecot-pop3d dovecot-imapd dovecot-mysql dovecot-sieve dovecot-managesieved bcrypt
https://github.com/opensolutions/ViMbAdmin/wiki/Install-using-git
Make sure that you set the same uid and guid in application.ini as in Postfix with these lines:
defaults.mailbox.uid = 5000 defaults.mailbox.gid = 5000
Change the mailbox home directory:
defaults.mailbox.homedir = "/var/vmail/"
Further on in this tutorial will set the password encryption for Dovecot to use SHA512-CRYPT. Configure that also in this application.ini file with:
defaults.mailbox.password_scheme = "dovecot:SHA512-CRYPT"
Besides these changes, configure the salt(s) and other settings in this file to suit your needs.
Make sure there is a FQN hostname in /etc/mailname. So NO localhost, local.domain or something like that!
nano /etc/mailname
Configure Postfix:
nano /etc/postfix/main.cf
Comment the “myhostname” setting so that Postfix will read the host from /etc/mailname. Or you could if you want set a FQN hostname here.
Add to the bottom:
virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_alias_maps = mysql:/etc/postfix/mysql/virtual-aliases.cf virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual-domains.cf virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual-mailboxes.cf
Add the following below the smtpd lines. This allows the use of SASL (Simple Authentication And Security Layer), so email clients like thunderbird are allowed to send mail with this mail server if the credentials are correct.
smtpd_tls_auth_only = yes smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_sasl_authenticated_header = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth smtpd_sasl_security_options = noanonymous, noplaintext smtpd_sasl_tls_security_options = noanonymous smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_invalid_hostname, reject_unauth_pipelining, reject_non_fqdn_sender, reject_unknown_sender_domain, reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_rbl_client sbl.spamhaus.org, permit
Create the following files so that postfix uses the MySQL database and tables that Vimbadmin uses. For more information see https://github.com/opensolutions/ViMbAdmin/wiki/Postfix-and-MySQL-Integration.
Create a MySQL folder:
mkdir /etc/postfix/mysql
Create /etc/postfix/mysql/virtual-aliases.cf
nano /etc/postfix/mysql/virtual-aliases.cf
user = vimbadmin password = password hosts = 127.0.0.1 dbname = vimbadmin query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'
Create /etc/postfix/mysql/virtual-domains.cf
nano /etc/postfix/mysql/virtual-domains.cf
user = vimbadmin password = password hosts = 127.0.0.1 dbname = vimbadmin query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'
Create /etc/postfix/mysql/virtual-mailboxes.cf
nano /etc/postfix/mysql/virtual-mailboxes.cf
user = vimbadmin password = password hosts = 127.0.0.1 dbname = vimbadmin query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'
For further advanced configuration see https://github.com/opensolutions/ViMbAdmin/wiki/Config-Files-for-full-domain-aliasing.
When Postfix receive an e-mail it will send it to another software: “Dovecot”. Dovecot will then manage the IMAP and POP3 services for the users. Tell Postfix to do this by adding the following line at the end of the file /etc/postfix/master.cf.
nano /etc/postfix/master.cf
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}
And specify a few more options in the config file (/etc/postfix/main.cf) by executing:
postconf -e virtual_transport=dovecot postconf -e dovecot_destination_recipient_limit=1
Restart postfix
service postfix restart
Dovecot can do several things for use. Get emails from Postfix and save them to disk, watch quotas (how much space a user may use on the servers disk), execute user-based “sieve” filter rules (can be used to put away emails to different folders), allow users to fetch emails using POP3 or IMAP. Create a user and a group just for storing emails (choose a free uid/gid):
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /var/vmail -m
Set protocols that may be used in the dovecot configuration file:
nano /etc/dovecot/dovecot.conf
protocols = imap pop3
Set mail location:
nano /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:/var/vmail/%d/%n/Maildir
Configure authentication:
nano /etc/dovecot/conf.d/10-auth.conf
Set authentication mechanisms to:
auth_mechanisms = plain login
Comment the following line:
#!include auth-system.conf.ext
And add to the bottom:
passdb { driver = sql args = /etc/dovecot/dovecot-sql.conf } userdb { driver = static args = uid=5000 gid=5000 home=/var/vmail/%d/%n allow_all_users=yes }
The “allow_all_users=yes” setting means that it is not necessary for Dovecot to check if a certain user exists. We can do that because Postfix has already ensured (in the virtual_mailbox_maps query) that the users existed before their email was handed over to Dovecot’s “deliver” agent.
Set authentication service:
nano /etc/dovecot/conf.d/10-master.conf
service auth { # auth_socket_path points to this userdb socket by default. It's typically # used by dovecot-lda, doveadm, possibly imap process, etc. Its default # permissions make it readable only by root, but you may need to relax these # permissions. Users that have access to this socket are able to get a list # of all usernames and get results of everyone's userdb lookups. unix_listener auth-userdb { mode = 0600 user = vmail group = vmail } # Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix } # Auth process is run as this user. #user = $default_internal_user }
Set Dovecot LDA (Local Delivery Agent):
nano /etc/dovecot/conf.d/15-lda.conf
protocol lda { postmaster_address = postmaster@example.com mail_plugins = sieve auth_socket_path = /var/run/dovecot/auth-userdb log_path = /var/vmail/dovecot-deliver.log }
Set log path:
nano /etc/dovecot/conf.d/10-logging.conf
log_path = /var/vmail/dovecot-deliver.log
The log file can become quite large, so let the system rotate the log file.
nano /etc/logrotate.d/dovecot-deliver
/var/vmail/dovecot-deliver.log { weekly rotate 14 compress }
Set the correct SQL settings:
cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf
nano /etc/dovecot/dovecot-sql.conf
Paste:
Adjust the driver, connect and default_pass_scheme variable to your situation.
Set permissions:
chgrp vmail /etc/dovecot/dovecot.conf chmod g+r /etc/dovecot/dovecot.conf /etc/init.d/dovecot restart chown vmail.vmail /var/vmail/dovecot-deliver.log chown root:root /etc/dovecot/dovecot-sql.conf chmod go= /etc/dovecot/dovecot-sql.conf
Get a report on your domain from http://www.pingability.com/zoneinfo.jsp. This invaluable report will check a number of things. Whether your email server is an open relay; that it is listening on a public IP; that you have an MX DNS record; and more. DNSReport may warn about missing reverse DNS entries.
List made changes with:
doveconf -n
Postfix log:
tail -n100 /var/log/mail.log
It’s nice to install SpamAssassin as additional step to fight SPAM on your mail server! When Postfix receives an email it will go through the SpamAssassin filter that will add several X-SPAM headers before the email gets passed to Dovecot. An example of the headers in an email that is marked as spam by SpamAssassin:
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on example.com X-Spam-Flag: YES X-Spam-Level: **************** X-Spam-Status: Yes, score=16.5 required=3.0 tests=FROM_12LTRDOM,GAPPY_SUBJECT, HTML_FONT_LOW_CONTRAST,HTML_MESSAGE,HTML_MIME_NO_HTML_TAG,MANY_SPAN_IN_TEXT, MIME_HTML_ONLY,MISSING_MID,RCVD_IN_BRBL_LASTEXT,RCVD_IN_PBL,RDNS_NONE, URIBL_DBL_SPAM,URIBL_JP_SURBL,URIBL_SBL,URIBL_SC_SURBL,URIBL_WS_SURBL autolearn=spam version=3.3.2
Install SpamAssassin:
apt-get install spamassassin spamc
Add the group “spamd” and the user to run SpamAssassin under:
groupadd spamd useradd -g spamd -s /bin/false -d /var/log/spamassassin spamd
Create the spamassassin directory and set the owner and group:
mkdir /var/log/spamassassin chown spamd:spamd /var/log/spamassassin
Enable SpamAssassin:
nano /etc/default/spamassassin
Change the value of the ENABLED parameter to 1:
ENABLED=1
If you want to enable automatic rule updates for getting the latest spam filtering rules, set CRON to 1 (recommended):
CRON=1
Put the following line below the ENABLED parameter:
SAHOME="/var/log/spamassassin/"
Change the value of the OPTIONS parameter to:
OPTIONS="--create-prefs --max-children 2 --username spamd -H ${SAHOME} -s ${SAHOME}spamd.log"
We set a lower value for max children, because that is enough and SpamAssassin will otherwise get hungry for RAM. But if you have a busy server you may want to increase this value.
All is set, start SpamAssassin. It will automatically start on reboot.
service spamassassin start
At this moment, SpamAssassin runs but won’t get any email from Postfix. Open the Postfix config file:
nano /etc/postfix/master.cf
Find this line:
smtp inet n - - - - smtpd
And add after that on a new line:
-o content_filter=spamassassin
So that it will look like:
smtp inet n - - - - smtpd -o content_filter=spamassassin
Add at the bottom of the file:
spamassassin unix - n n - - pipe user=spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}
This will tell Postfix to filter the mail with SpamAssassin.
Restart Postfix so changes will take effect.
service postfix restart
nano /etc/spamassassin/local.cf
Add *****SPAM***** as prefix to the subject of mails that are marked as spam, by setting:
rewrite_header Subject *****SPAM*****
By default the score to mark an email as SPAM is 5.0, but I set it to 3.0 which is still safe and a bit more strict:
required_score 3.0
Restart SpamAssassin so changes will take effect.
service spamassassin restart
To see if SpamAssassin is working, execute:
cat /var/log/spamassassin/spamd.log
At this moment SpamAssassin is working correctly and will mark a large amount of emails as SPAM. But to get the most out of SpamAssassin it’s important that you train it.
Add the following to the crontab of the root user:
crontab -e
# Train SpamAssassin 0 0,6,12,18 * * * sa-learn --ham /var/vmail/*/*/Maildir/{cur,new,.INBOX*} >/dev/null 0 1,7,13,19 * * * sa-learn --spam /var/vmail/*/*/Maildir/.Junk/{cur,new} >/dev/null
This will train SpamAssassin every 6 hours. Notice the difference between the two by the —spam and —ham flag. It’s important to train not only spam, but also ham (mail that is valid and must NOT be considered spam). Otherwise the filter will become biased towards spam.
Configure your email client like Thunderbird to use the “Junk” folder as junk folder. This is the default for the Apple Mail client. So if you mark an email as junk or move it to the junk folder in your email client (if you use IMAP, so it will also be moved on the server), make sure it will stay there for at least 6 hours so the SpamAssassin can learn from it.
mkdir /etc/dovecot/sieve
And add a file named sieve.default with the following content:
nano /etc/dovecot/sieve/sieve.default
require "fileinto"; if header :contains "X-Spam-Flag" "YES" { fileinto "Junk"; stop; }
Set the correct owner and group:
chown -R vmail:vmail /etc/dovecot/sieve
And compile it:
sievec /etc/dovecot/sieve/default.sieve
Enable sieve as plugin in Dovecot by adding sieve to the protocols parameter:
nano /etc/dovecot/dovecot.conf
protocols = imap pop3 sieve
Set the sieve global path:
nano /etc/dovecot/conf.d/90-sieve.conf
sieve_global_path = /etc/dovecot/sieve/default.sieve
Restart Dovecot to activate the managesieve service that will use the sieve script.
service dovecot restart
Verify with the line below if managesieve is indeed running, by default that should be on port 4190.
netstat -tln
Test if the sieve script is used successfully by sending a spam email (Execute this on another host, otherwise it won’t get marked as spam):
sendmail youremail@example.com < /usr/share/doc/spamassassin/examples/sample-spam.txt
Or just send an email from your Gmail account for example. The subject must be "Test spam mail (GTUBE)" and the body:
This is the GTUBE, the Generic Test for Unsolicited Bulk Email If your spam filter supports it, the GTUBE provides a test by which you can verify that the filter is installed correctly and is detecting incoming spam. You can send yourself a test mail containing the following string of characters (in upper case and with no white spaces and line breaks): XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X You should send this test mail from an account outside of your network.
And view the Dovecot log:
tail -n100 /var/vmail/dovecot-deliver.log
It should say something like:
Jul 01 20:43:17 lda(youremail@example.com): Info: sieve: msgid=<CAESbuTWPsUAZt0qhM0Q44L3iEmMhw0g9ZW3Th==e4pUVQrGnjQ@mail.gmail.com>: stored mail into mailbox 'Junk'
Links that helped me a lot: