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.

UPDATE 11/2013 I removed the extra reinjection to postfix after spam filtering since it is not really necessary. I also updated the dspam part with instructions to change the dspam user with systemd instead of the deprecated initscripts

All instructions and configuration on this page is provided as is. It works like this for me but there is no warranty that it will work for everyone else. This is not meant to be a step by step howto for someone who has never worked with linux or has no knowledge about mailservers and networking. Make sure you understand what these instructions mean before trying them yourself.


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

Authentication information:

mkdir -p /home/vmail/auth.d/
touch /home/vmail/auth.d/
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/
mkdir -p /home/vmail/conf.d/
chown -R vmail:vmail /home/vmail/conf.d

Mailbox direcory:

mkdir -p /home/vmail/
chown vmail:vmail /home/vmail/


Next create a user. For the example we will use

Edit /home/vmail/auth.d/ and add the following line:{PLAIN}user1pass:5000:5000::/home/vmail/

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: 

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.



Home /var/lib/dspam
StorageDriver /usr/lib/dspam/

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


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             "" # Change this to your servers hostname
ServerPID               "/var/run/dspam/"
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:

Description=A highly accurate statistical spam filter that uses minimal resources

ExecStart=/usr/bin/dspam --daemon 2>/dev/null


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.



# 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 {

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 =

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

# 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/ and create a file like this:


require ["fileinto"];
# rule:[SPAM]
if anyof (header :contains "X-DSPAM-Result" "Spam")
        fileinto "Junk";

After creating the file call “sievec” while in the directory to precompile the rule for dovecots use.



smtpd_banner = $myhostname ESMTP
biff = no
append_dot_mydomain = no

myhostname =  # Change this to your mailservers hostname
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain, localhost
virtual_mailbox_domains =  # 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 =

# SSL stuff for TLS
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


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


# 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.


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!


09.04.2013 00:30

Thanks for you article.

However, I have a question.


sender smtp server –incoming mail–> postfix(Port 25) –lmtp–> dspam –smtp–> postfix(Port 10026) –lmtp–> dovecot(Sieve Filter) –> Users Mailbox

and not just

sender smtp server –incoming mail–> postfix(Port 25) –lmtp–> dspam –lmtp–> dovecot(Sieve Filter) –> Users Mailbox

25.11.2013 07:37

Actually you are right, this step is not really necessary. I took this from another howto. I changed the setup (and the instructions here) accordingly. Thanks for the hint.

3 03.04.2015 08:43

Still the best howto around! I used exim instead of postfix, but the rest of configuration fits perfectly! Thank you!!!

blog/2011/01/my_mailserver_setup_postfix_dspam_dovecot.txt · Last modified: 25.11.2013 07:36 by Seiichiro
CC Attribution-Share Alike 3.0 Unported
Driven by DokuWiki Hosted by Linode Recent changes RSS feed Valid XHTML 1.0