Mailserver with Postfix and Dovecot

This page describes a special mail server configuration.

Server name: server.example.com
Virtual domains: example.com, example.org, example.net
Catch-all user: foo@example.org
Operating System: Debian Squeeze

Postfix

Basic Installation

# apt-get install postfix

In /etc/mailname:

server.example.com

Basic configuration in /etc/postfix/mail.cf:

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no

readme_directory = no

mailbox_size_limit = 0
recipient_delimiter = +

inet_interfaces = all
myorigin = /etc/mailname
myhostname = server.example.com
mydestination = server.example.com, localhost.example.com, localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
relayhost =

smtpd_client_restrictions = reject_unknown_client_hostname
smtpd_helo_required = yes
smtpd_helo_restrictions = reject_invalid_helo_hostname
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_recipient_restrictions =
  permit_mynetworks,
  reject_unknown_recipient_domain,
  reject_unauth_pipelining,
  permit_sasl_authenticated,
  reject_unauth_destination

Deliver to Dovecot

In /etc/postfix/main.cf:

alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
virtual_alias_maps = hash:/etc/postfix/virtual
virtual_mailbox_domains = hash:/etc/postfix/virtual-mailbox-domains
virtual_mailbox_maps = hash:/etc/postfix/virtual-mailbox-users
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

In /etc/postfix/virtual, catch-all:

@example.com        foo@example.org
@example.org        foo@example.org
@example.net        foo@example.org

In /etc/postfix/virtual-mailbox-domains:

example.com         OK
example.org         OK
example.net         OK

In /etc/postfix/virtual-mailbox-users:

foo@example.org     OK

Generate databases:

# postmap /etc/postfix/virtual
# postmap /etc/postfix/virtual-mailbox-domains
# postmap /etc/postfix/virtual-mailbox-users

In /etc/postfix/master.cf:

dovecot   unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver
  -f ${sender} -d ${recipient}

TLS and Authentification

Requires creation of SSL certificates first. Delegates authentification to Dovecot.

In /etc/postfix/main.cf:

smtpd_tls_cert_file=/etc/ssl/certs/server-example-com.pem
smtpd_tls_key_file=/etc/ssl/private/server-example-com.pem
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_auth_only = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

Spamassassin

# apt-get install spamass-milter

User for Spamassassin:

# groupadd spamd
# useradd -g spamd -s /bin/false -d /var/lib/spamassassin spamd
# mkdir /var/lib/spamassassin
# chown spamd.spamd /var/lib/spamassassin -R
# mkdir /var/run/spamassassin

In /etc/default/spamassassin:

ENABLED=1
CRON=1
SAHOME="/var/lib/spamassassin"
OPTIONS="--username spamd --nouser-config --max-children 2 --helper-home-dir ${SAHOME} --socketpath=/var/run/spamassassin/spamd.sock --socketowner=spamd --socketgroup=spamd --socketmode=0660"
PIDFILE="/var/run/spamassassin/spamd.pid"

In /etc/default/spamass-milter:

OPTIONS="-u spamass-milter -m -I -i 127.0.0.1 -- --socket=/var/run/spamassassin/spamd.sock"

Allow spamass-milter user to access spamd socket:

# usermod -a -G spamd spamass-milter

In /etc/postfix/main.cf:

smtpd_milters = unix:/spamass/spamass.sock
milter_connect_macros = j {daemon_name} v {if_name} _
milter_default_action = tempfail

ClamAV

# apt-get install clamav-milter
# apt-get install arj bzip2 cabextract cpio file gzip lha lzop nomarch p7zip pax rar rpm unrar unzip zip zoo

Configuration with

Results in /etc/clamav/clamav-milter.conf:

MilterSocket /var/spool/postfix/clamav/clamav-milter.ctl
FixStaleSocket true
User clamav
AllowSupplementaryGroups true
ReadTimeout 120
Foreground false
PidFile /var/run/clamav/clamav-milter.pid
ClamdSocket unix:/var/run/clamav/clamd.ctl
OnClean Accept
OnInfected Quarantine
OnFail Defer
AddHeader Replace
LogSyslog true
LogFacility LOG_MAIL
LogVerbose false
LogInfected Full
LogClean Off
MaxFileSize 25M
TemporaryDirectory /tmp
LogFile /var/log/clamav/clamav-milter.log
LogTime true
LogFileUnlock false
LogFileMaxSize 0M
MilterSocketGroup clamav
MilterSocketMode 660

In /etc/default/clamav-milter:

SOCKET_RWGROUP=postfix

In /etc/postfix/main.cf:

smtpd_milters = unix:/clamav/clamav-milter.ctl

Dovecot

Basic Installation

# apt-get install dovecot-imapd

Group, user, and directory for mail delivery

# groupadd -g 5000 vmail
# useradd -g vmail -u 5000 vmail -d /srv/vmail -m
# chown -R vmail:vmail /srv/vmail
# chmod u+w /srv/vmail

Basic Configuration: dovecot -n

log_timestamp: %Y-%m-%d %H:%M:%S 
protocols: imap
login_dir: /var/run/dovecot/login
login_executable: /usr/lib/dovecot/imap-login
mail_privileged_group: mail
mail_location: maildir:/srv/vmail/%d/%n:LAYOUT=fs
mbox_write_locks: fcntl dotlock
mail_process_size: 512
imap_client_workarounds: tb-extra-mailbox-sep
auth default:
  verbose: yes
  userdb:
    driver: static
    args: uid=5000 gid=5000 home=/srv/vmail/%d/%n allow_all_users=yes

SSL

disable_plaintext_auth: yes
ssl: required
ssl_cert_file: /etc/ssl/certs/server-example-com.pem
ssl_key_file: /etc/ssl/private/server-example-com.pem

Authentification for Postfix

lda:
  postmaster_address: postmaster@example.com
  auth_socket_path: /var/run/dovecot/auth-master
  log_path: 
auth default:
  socket:
    type: listen
    client:
      path: /var/spool/postfix/private/auth
      mode: 432
      user: postfix
      group: postfix
    master:
      path: /var/run/dovecot/auth-master
      mode: 384
      user: vmail

LDAP Authentification

In /etc/dovecot/dovecot.conf:

auth default:
  passdb:
    driver: ldap
    args: /etc/dovecot/dovecot-ldap.conf

In /etc/dovecot/dovecot-ldap.conf:

uris = ldapi:///
auth_bind = yes
base = dc=example,dc=com
pass_attrs = mail=user
pass_filter = (&(objectClass=inetOrgPerson)(uid=%u))

Virtual Folders

mail_plugins: virtual
lda:
  mail_plugins: sieve virtual
namespace:
  type: private
  separator: /
  location: maildir:/srv/vmail/%d/%n:LAYOUT=fs
  inbox: yes
  list: yes
  subscriptions: yes
namespace:
  type: private
  separator: /
  prefix: virtual/
  location: virtual:/srv/vmail/%d/%n/virtual:INDEX=MEMORY
  list: yes
  subscriptions: yes

Examples for virtual folders:

All mailbox /srv/vmail/%d/%n/virtual/all/dovecot-virtual:

*
-Spam
-Trash
-Trash/*
  all

Unseen mailbox /srv/vmail/%d/%n/virtual/unseen-threaded/dovecot-virtual:

virtual/all
  inthread refs unseen

Mailing list mailbox /srv/vmail/%d/%n/virtual/somelist/dovecot-virtual:

virtual/all
  HEADER List-Id <...>
  OR HEADER List-Id <...> HEADER List-Id <...>

Sieve

lda:
  mail_plugins: sieve virtual
plugin:
  sieve: /srv/vmail/%d/%n/dovecot.sieve

In /srv/vmail/%d/%n/dovecot.sieve:

require ["date", "variables", "fileinto"];
if currentdate :matches "month" "*" { set "month" "${1}"; }
if currentdate :matches "year"  "*" { set "year"  "${1}"; }
if anyof ( header :contains "List-Id" "" ) {
  # Move all mails from mailing lists into archive
  fileinto "Archives/${year}";
}
elsif header :contains "X-Spam-Level" "**" {
  # Move spam mails to Spam folder
  fileinto "Spam";
}
else {
  keep;
}

Shorewall and Fail2ban

In /etc/shorewall/rules:

ACCEPT      net     $FW     tcp  25 -       -       2/min:8
ACCEPT      net     $FW     tcp 143 -       -       2/min:8

Restart shorewall:

# /etc/init.d/shorewall restart

See Fail2ban.

Upgrade to Debian Wheezy

Postfix

To listen to IPv4 only, in /etc/postfix/main.cf:

inet_protocols = ipv4

Deliver binary was renamed, in /etc/postfix/master.cf replace deliver with dovecot-lda.

Spamassassin

User spamd is no longer required as a new user debian-spamd is created.

In /etc/default/spamassassin replace spamd with debian-spamd.

Also make sure the run directory is created, add to /etc/default/spamassassin:

if [ ! -d "/var/run/spamassassin" ]; then
    mkdir /var/run/spamassassin
    chmod 755 /var/run/spamassassin
fi

Add spamass-milter user to debian-spamd group:

# usermod -a -G debian-spamd spamass-milter

Dovecot

Dovecot version was updated from 1.2 to 2.0 and the configuration format changed.

# cd /etc/dovecot
# mv dovecot.conf dovecot.conf.original
# doveconf -n -c dovecot.conf.ucf-old > dovecot.conf
# chmod 644 dovecot.conf

To listen to IPv4 only, in /etc/dovecot/dovecot.conf:

listen = *

TODOs


Sources: