My Mailserver Setup: Postfix + Dspam + Dovecot
In the following post I will describe how I set up the mailserver serving this domain. It is meant more or less as a reminder for myself if I ever have to set it up again. But since I think it might be a help for others searching for a (relatively) simple setup with virtual users but without the overhead of an SQL-Database that most howtos use I will put my configs and a little description here.
Overview
I use the following programms for the setup:
- Archlinux as the operating System
- Postfix for SMTP (version 2.7.2)
- DSPAM as a content filter for Postfix (version 3.9.0)
- Dovecot (version 2.0.8) for local mail delivery into the mailbox, sieve filtering (dovecot-pigeonhole) and IMAP with automatic spam training (dovecot-antispam)
The setup in an overview looks like this:
Outgoing Mail:
mail client --outgoing mail--> postfix(Port 587) --> recipient smtp server
|
|--> dovecot(sasl authentication) --> passwd-file
Incoming Mail:
sender smtp server --incoming mail--> postfix(Port 25) --lmtp--> dspam --lmtp--> dovecot(Sieve Filter) --> Users Mailbox
The mailboxes are accessible via IMAP. The users will be kept in flat passwd-like files and all authentication will be handled by dovecot. The setup will allow to host multiple domains, each with its own user/password database. As you can see in my “graphic” above I use two distinct ports for smtp ingoing and sending mail. Port 587 (submission port) is used for sending outgoing mail. Only Authenticated users are allowed here. If a user is authenticated he can send mails to anywhere. Port 25 is the port for ingoing mail. It Accepts mails from everywhere, but only accepts them if they are for known (local) users. It will not relay mails to any foreign domains.
I assume that you have installed postfix, dspam, dovecot and the plugins dovecot-pigeonhole and dovecot-antispam. If you don't know how to do this you should consult the fine manual of your distribution.
After this brief overview lets get to the individual components:
vmail user and directory-layout
All mail is owned by the system user vmail. So lets create this first:
useradd -d /home/vmail -m -s /bin/nologin -u 5000 -U vmail chmod 755 /home/vmail
The mail and domain-specific setups is stored under /home/vmail, feel free to adjust this to your liking (but remember to use the changed path later on)
Next we will create some directories for authentication files, global configs and the mailboxes. In this example I assume that I want to host the mailserver for the domain example.org.
Authentication information:
mkdir -p /home/vmail/auth.d/example.com/ touch /home/vmail/auth.d/example.com/passwd chown -R dovenull:dovenull /home/vmail/auth.d
This is the passwd file which will hold our virtual users. The ownership of the files is changed to dovenull, which is the user that will be used for running the dovecot login service
Per domain Configs (e.g. global sieve rules for spam filtering):
mkdir -p /home/vmail/conf.d/example.com/sieve_before.d mkdir -p /home/vmail/conf.d/example.com/sieve_after.d chown -R vmail:vmail /home/vmail/conf.d
Mailbox direcory:
mkdir -p /home/vmail/example.com/ chown vmail:vmail /home/vmail/example.com
Users
Next create a user. For the example we will use user1@example.com
Edit /home/vmail/auth.d/example.com/passwd and add the following line:
user1@example.com:{PLAIN}user1pass:5000:5000::/home/vmail/example.com/user1::
The line is composed as follows:
<user>@<domain>:<password>:vmail UID:vmail gid::<mailbox directory>::
If you want encrypted passwords you can use dovecots doveadm command:
# doveadm pw
Enter new password:
Retype new password:
{CRAM-MD5}e02d374fde0dc75a17a557039a3a5338c7743304777dccd376f332bee68d2cf6
Then use the encrypted password line that the command responds with for the password field.
Configuring the daemons
For the daemons I will mostly just list my configs with some comments on what to change or look out for. If you don't understand what the options do please consult the programs help/website.
dspam
/etc/dspam/dspam.conf:
Home /var/lib/dspam StorageDriver /usr/lib/dspam/libhash_drv.so OnFail error Trust root Trust dspam Trust vmail TrainingMode teft TestConditionalTraining on Feature whitelist Algorithm graham burton Tokenizer chain PValue bcr WebStats off # I deliver spam to the mailbox and filter them with sieve Preference "spamAction=deliver" Preference "signatureLocation=headers" Preference "showFactors=off" AllowOverride trainingMode AllowOverride spamAction spamSubject AllowOverride statisticalSedation AllowOverride enableBNR AllowOverride enableWhitelist AllowOverride signatureLocation AllowOverride showFactors AllowOverride optIn optOut AllowOverride whitelistThreshold # local reinject port for postfix, see postfix config DeliveryHost /var/run/dovecot/lmtp-client DeliveryIdent localhost DeliveryProto LMTP Notifications off HashRecMax 98317 HashAutoExtend on HashMaxExtents 0 HashExtentSize 49157 HashMaxSeek 100 HashConnectionCache 10 PurgeSignatures 14 PurgeNeutral 90 PurgeUnused 90 PurgeHapaxes 30 PurgeHits1S 15 PurgeHits1I 15 LocalMX 127.0.0.1 Opt out Broken case ProcessBias on # The next options ensure that each virtual user has its own spam/ham database ParseToHeaders on ChangeModeOnParse on ChangeUserOnParse full # Start dspam server on unix domain socket listening for lmtp connections ServerMode auto ServerParameters "--deliver=innocent,spam" ServerIdent "mail.example.com" # Change this to your servers hostname ServerPID "/var/run/dspam/dspam.pid" ServerDomainSocketPath "/var/run/dspam/dspam.sock"
Since I want to run dspam as user vmail and not as root, as it is the default on arch, I had to overwrite the systemd servicefile to use the right user. For this I copied the servicefile from /usr/lib/systemd/system/dspam.service to /etc/systemd/system/dspam.service and changed it like this:
[Unit] Description=A highly accurate statistical spam filter that uses minimal resources [Service] Type=forking User=vmail ExecStart=/usr/bin/dspam --daemon 2>/dev/null PrivateTmp=true [Install] WantedBy=multi-user.target
I also had to change the permissions for the runtime directory. for this I created the file /etc/tmpfiles.d/dspam.conf with the following content:
d /var/run/dspam 0777 vmail vmail -
After this changes and a restart of the service dspam will run as user vmail. You might have to change the ownership of /var/run/dspam manually since the tmpfiles are only created at boot.
dovecot
/etc/dovecot/dovecot.conf
# Activated Protocolls
protocols = imap lmtp sieve
# Store Mail in the <homedir>/Mail in maildir format
mail_location = maildir:~/Mail
# Login and Users
auth_mechanisms = plain login
auth_debug = no
# User Databases, %d expands to domain of login name.
# Users will have to log in with full email address for this to work
passdb {
driver = passwd-file
args = username_format=%u /home/vmail/auth.d/%d/passwd
}
userdb {
driver = passwd-file
args = username_format=%u /home/vmail/auth.d/%d/passwd
}
# Service Definitions
# IMAP Stuff
service imap-login {
inet_listener imap {
port=143
}
}
service imap {
}
# LMTP socket for local delivery from postfix
service lmtp {
unix_listener lmtp-client {
user = postfix
group = vmail
mode = 0660
}
}
# Authentication stuff, runs as dovenull user
service auth {
unix_listener auth-client {
user = postfix
group = postfix
mode = 0660
}
user = dovenull
}
service auth-worker {
user = dovenull
}
# Managesieve service for client-side filter-rule editing
service managesieve-login {
inet_listener sieve {
port = 4190
}
service_count = 1
process_min_avail = 0
vsz_limit = 64M
}
service managesieve {
}
verbose_proctitle = yes
# Protocol Definitions
protocol imap {
imap_client_workarounds = delay-newmail tb-extra-mailbox-sep
mail_plugins = $mail_plugins antispam # Activate antispam-plugin for training dspam
}
protocol lmtp {
mail_plugins = $mail_plugins sieve # Activatte sieve plugin for filtering on local delivery
postmaster_address = postmaster@example.com
}
protocol sieve {
managesieve_max_line_length = 65536
mail_max_userip_connections = 10
managesieve_implementation_string = Dovecot Pigeonhole
managesieve_max_compile_errors = 5
}
# Plugin config
plugin {
# Config for server-side sieve Filtering
sieve = ~/sieve/.dovecot.sieve # Per user script for active ruleset
sieve_dir = ~/sieve # Directory for storing users rulesets
sieve_global_dir = /home/vmail/conf.d/%d/sieve
# Global sieve-scripts that run before and after the per-user scripts
# All scripts have to use a .sieve extension or will be ignored
sieve_before = /home/vmail/conf.d/%d/sieve_before.d/
sieve_after = /home/vmail/conf.d/%d/sieve_after.d/
# Dovecot antispam will train dspam on moving mail into/out of the Spam folder (which is called Junk in my setup)
# This options only work if your dspam-daemon runs as the vmail-user!
antispam_backend = dspam
antispam_dspam_args = --source=error;--signature=%%s;--user;%u
antispam_spam = Junk
antispam_trash = Trash
antisapm_unsure = Trash
antispam_signature = X-DSPAM-Signature
}
# TLS
# Change the keys to your server's keys!
ssl = yes
ssl_cert = </etc/ssl/private/mail.crt
ssl_key = </etc/ssl/private/mail.pem
This config enables dovecot as imap server with sieve filtering and lmtp for local delivery and antispam-features for training the spam filter.
As a bonus we add a global sieve rule to stuff mails tagged as spam into the users “Junk” folder. Go to /home/vmail/conf.d/example.com/sieve_before.d/ and create a file like this:
spam.sieve:
require ["fileinto"];
# rule:[SPAM]
if anyof (header :contains "X-DSPAM-Result" "Spam")
{
fileinto "Junk";
stop;
}
After creating the file call “sievec” while in the directory to precompile the rule for dovecots use.
Postfix
/etc/postfix/main.cf:
smtpd_banner = $myhostname ESMTP biff = no append_dot_mydomain = no myhostname = mail.example.com # Change this to your mailservers hostname inet_protocols = ipv4 mydestination = $myhostname, localhost.$mydomain, localhost virtual_mailbox_domains = example.com # Here goes a list of all domains you want to host virtual_alias_maps = hash:/etc/postfix/virtual virtual_transport = lmtp:unix:/var/run/dovecot/lmtp-client # Hand mail to dovecot for local delivery strict_rfc821_envelopes = yes disable_vrfy_command = yes smtpd_helo_required = yes smtpd_recipient_restrictions = reject_unknown_recipient_domain, reject_non_fqdn_recipient, permit_mynetworks, reject_unauth_destination permit # SSL stuff for TLS smtpd_tls_cert_file=/etc/ssl/private/mail.crt smtpd_tls_key_file=/etc/ssl/private/mail.pem smtpd_use_tls=yes smtp_tls_note_starttls_offer=yes smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache smtpd_tls_security_level = may alias_maps = hash:/etc/postfix/aliases mailbox_size_limit = 0 message_size_limit = 20480000 queue_directory=/var/spool/postfix command_directory=/usr/sbin daemon_directory=/usr/lib/postfix
This config enables use of virtual/alias-maps, so you can map external mail addresses to internal (-dovecot) users. The smtp on port 25 will only accept mail for users in virtual/alias and the internal dovecot users
/etc/postfix/master.cf
# SMTP port 25 for recieving mail, dspam is configured for spam detection
smtp inet n - n - - smtpd
-o content_filter=lmtp:unix:/var/run/dspam/dspam.sock
# Submission port 587 for client connection / sending mails from authenticated users
submission inet n - n - - smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=/var/run/dovecot/auth-client
-o smtpd_recipient_restrictions=reject_unknown_recipient_domain,reject_non_fqdn_recipient,permit_sasl_authenticated,reject
# Default stuff
pickup fifo n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr fifo n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
-o smtp_fallback_relay=
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
Thats it
Now if you configured your services right you can start dovecot, dspam and postfix and should be able to send and recieve mail. Configure your client to use IMAP with TLS for mail recieving and SMTP on port 587 with TLS for mail sending. I hope my notes may be usefull for someone who wants to have a mailsetup with virtual users without having to run a full Database as most tutorials suggest.
This setup doesn't cover the topic of setting up the DNS of your Domain and the necessary MX-Records for recieving mails. The search-engine of your choice should have enough tutorials to cover this part.
References
I used this two howtos as my main resources:
Furthermore the websites of the used Programs:
Feel free to leave your comments/questions/suggestions in the Comments section below!
