Setting up a spamsafe Postfix server

I am currently in the process of upgrading my webserver to Debian Etch. In the past I have been using Debian Sarge with Plesk as an administration desktop. Plesk is very convenient, but it is also a memory hog and a performance killer, so I decided to go on without a web based administration tool and configure every service manually. This has the advantage that the system will be more secure and easier to update. The downside is a little bit more work in the beginning. During the next couple of postings I will document the configuration of the various services I have running on that server.

In this first post I will start with the mail service for which I choose the Postfix daemon together with policyd-weight for spam filtering and Dovecot as an IMAP and POP3 server. Authentication will be done with the SASL daemon against the standard user database. This is not really suited for large mail installations with a lot of users, but if you have to deal with only a couple of mail users, it is really easy to administrate.

This descriptions is based on the Postfix tutorial of Gerald Holt and Kain Anderer. Thanks for the great work!

Installing all required components is a breeze on a Debian system. During the installation your current mail daemon will be removed in favor of Postfix:

apt-get install postfix policyd-weight dovecot-imapd dovecot-pop3d sasl2-bin libsasl2-modules

First let’s create a configuration file for policyd:

policyd-weight defaults > /etc/policyd-weight.conf

The default configuration is fine for us and we don’t need to change it. If you experience poor spam filtering results, you could modify the above configuration file to better suite your needs.

Next on the list is Dovecot. The configuration file /etc/dovecot/dovecot.conf needs to look like this:

protocols =  imap imaps pop3 pop3s
disable_plaintext_auth = no
log_timestamp = "%Y-%m-%d %H:%M:%S "
ssl_cert_file = /etc/ssl/certs/dovecot.pem
ssl_key_file = /etc/ssl/private/dovecot.pem
mail_location = maildir:%h/Maildir
mail_extra_groups = mail
protocol imap {
}
protocol pop3 {
  pop3_uidl_format = %08Xu%08Xv
}
auth default {
  mechanisms = plain
  passdb shadow {
  }
  userdb passwd {
  }
  user = root
}
dict {
}
plugin {
}

This will enable secure and plaintext logins with IMAP, IMAPS, POP3 and POP3S. If you want to restrict access to only encrypted and secure logins you need to change the following two settings:

protocols =  imaps pop3s
disable_plaintext_auth = yes

The login credentials will be checked against the shadow user database.

Now we need to setup SASL to enable authentication checks in Postfix. First, we will configure the SASL daemon using the configuration file /etc/default/saslauthd:

START=yes
MECHANISMS="shadow"
MECH_OPTIONS=""
THREADS=2
OPTIONS="-m /var/spool/postfix/var/run/saslauthd"
PWDIR="/var/spool/postfix/var/run/saslauthd"
PIDFILE="/var/spool/postfix/var/run/${NAME}/saslauthd.pid"

Now create some directories inside the Postfix chroot environment and add postfix to the sasl usergroup:

mkdir -p /var/spool/postfix/var/run/saslauthd
dpkg-statoverride --add root sasl 710 /var/spool/postfix/var/run/saslauthd
adduser postfix sasl

The last step to enable SASL authentication is to create the file /etc/postfix/sasl/smtpd.conf:

saslauthd_path: /var/run/saslauthd/mux
pwcheck_method: saslauthd
mech_list: plain login

Before we edit the configuration file for Postfix, we need to create SSL certificates for secure SMTP connections:

openssl genrsa -out mail.key 2048
openssl req -new -key mail.key -out mail.csr
openssl x509 -req -days 4312 -in mail.csr -out mail.cert -signkey mail.key

When filling out the certificate data you need to make sure, that you enter your fully qualified domain name in the field CN. Else you will get a warning about a wrong certificate every time you try to send email.

Now edit the main Postfix configuration file /etc/postfix/main.cf. It should look like this:

# See /usr/share/postfix/main.cf.dist for a commented, more complete version# Debian specific:  Specifying a file name will cause the first# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP Mailserver
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

# TLS parameters
smtpd_tls_cert_file=/etc/postfix/mail.cert
smtpd_tls_key_file=/etc/postfix/mail.key
smtpd_use_tls=yes
smtpd_enforce_tls = no
smtpd_tls_auth_only = no
smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${queue_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
myhostname = FULL.DOMAIN.NAME
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, localhost.$mydomain, $mydomain
relayhost =
mynetworks = 127.0.0.0/8
#mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
message_size_limit = 20480000
recipient_delimiter = +
inet_interfaces = all

smtpd_helo_required = yes
smtpd_helo_restrictions = reject_invalid_hostname
smtpd_recipient_restrictions = permit_mynetworks, reject_unknown_recipient_domain, permit_sasl_authenticated, reject_unauth_destination, check_policy_service inet:127.0.0.1:12525
smtpd_sender_restrictions = reject_unknown_address
smtpd_client_restrictions = reject_invalid_hostname
strict_rfc821_envelopes = yes

home_mailbox = Maildir/

smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
smtp_sasl_auth_enable = no
broken_sasl_auth_clients = yes
virtual_alias_domains = COLON SEPARATED LIST OF YOUR DOMAINS
virtual_alias_maps = hash:/etc/postfix/virtual_domains
virtual_mailbox_limit = 0

In the above file you need to replace FULL.DOMAIN.NAME with your fully qualified domain name and COLON SEPARATED LIST OF YOUR DOMAINS with a list of all the domains you want to receive mails for.

Once this is done you can restart all services:

/etc/init.d/policyd-weight restart
/etc/init.d/dovecot restart
/etc/init.d/saslauthd restart
/etc/init.d/postfix restart

Adding new mail users

Create the user (in this example with the login “joe”):

adduser --shell /bin/false joe

Map email addresses to the user by editing the file /etc/postfix/virtual_domains:

joe.sample@mydomain.com    joe
joe@seconddomain.net         joe

Rebuild the mappings database:

postmap /etc/postfix/virtual_domains

That’s it! You now have secure base mail configuration which does not allow mail relaying without logging in with a valid user account. The mails will be stored in the Maildir inside each users home folder and best of all thanks to policyd-weight most of the spam mails will be rejected by the mailserver. If you need even better spam filtering you could also integrate Spamassassin.

Leave a Reply