Kerberized Postfix, Dovecot, Policyd on Solaris

These are my notes from compiling and configuring these services.

Note that I put all the stuff I personally compile in /opt/psa to keep it separate from other sources. I also package everything. If you want the packages, just ask.

Postfix

Postfix compilation and configuration is fairly well documented.

Compile

The important parts for the including Dovecot SASL are:

-DUSE_SASL_AUTH
-DDEF_SERVER_SASL_TYPE="dovecot"

Here's the full script I used:

#!/bin/bash

export PATH="/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin"

make tidy

make makefiles CC=cc CCARGS='-DUSE_TLS -DHAS_PCRE -DUSE_SASL_AUTH -DDEF_SERVER_SASL_TYPE="dovecot" -DDEF_COMMAND_DIR="/opt/psa/sbin" -DDEF_CONFIG_DIR="/etc/opt/psa/postfix" -DDEF_DAEMON_DIR="/opt/psa/libexec/postfix" -DDEF_MAILQ_PATH="/opt/psa/bin/mailq" -DDEF_HTML_DIR="no" -DDEF_MANPAGE_DIR="/opt/psa/share/man" -DDEF_NEWALIAS_PATH="/opt/psa/bin/newaliases" -DDEF_QUEUE_DIR="/var/opt/psa/postfix" -DDEF_README_DIR="/opt/psa/share/readme/postfix" -DDEF_SENDMAIL_PATH="/opt/psa/sbin/sendmail" -I/usr/sfw/include -I/opt/sfw/include -I/opt/psa/include ' AUXLIBS="-R/usr/sfw/lib -R/opt/sfw/lib -R/opt/psa/lib -L/usr/sfw/lib -L/opt/sfw/lib -L/opt/psa/lib -lssl -lcrypto -lpcre" make if [ -r postfix-install ]; then /bin/bash postfix-install -non-interactive -package install_root=/tmp/postfix-install mail_owner=postfix setgid_group=postdrop fi

Configure

For the new built in TLS, they've changed the configuration to use X_tls_security_level so keep that in mind if you're upgrading from an older version.

Setting X_tls_security_level to may uses TLS where possible but allows for it not to be used and allows for certificates not to match (so self-signed certificates can still send you email).

My new TLS settings look like:

smtpd_tls_security_level = may
smtpd_tls_CAfile = /etc/sfw/openssl/cacert.pem
smtpd_tls_cert_file = /etc/opt/psa/dovecot/dovecot-cert.pem
smtpd_tls_key_file = /etc/opt/psa/dovecot/dovecot-req.pem
smtp_tls_security_level = may

Next comes SASL. The following configuration uses Dovecot SASL and turns off sending credentials over plain text (so usernames and passwords are forced over TLS or SSL connections).

smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous, noplaintext

To run Dovecot as the LDA, you need:

mailbox_command = /opt/psa/libexec/dovecot/deliver

If you're not running comsat (who does any more?), you probably want the following so it doesn't print lots of useless logs:

biff = no

The following client restrictions stop some spam by killing off anyone who doesn't wait for Postfix to answer the connection before sending commands (the sleep 1, followed by the reject_unauth_pipelining).

smtpd_client_restrictions = permit_sasl_authenticated,
  permit_mynetworks, 
  sleep 1, 
  reject_unauth_pipelining, 
  check_client_access pcre:/etc/opt/psa/postfix/maps/client_access,
  reject_unknown_client_hostname, 
  permit

# Required to make the sleep and reject_unauth_pipelining work properly smtpd_delay_reject = no

Now we allow any of our authenticated senders and do some more DNS based checks:

smtpd_sender_restrictions = permit_sasl_authenticated, 
  permit_mynetworks, 
  check_sender_access pcre:/etc/opt/psa/postfix/maps/sender_access, 
  reject_unknown_sender_domain, 
  reject_unauth_pipelining, 
  reject_non_fqdn_sender, 
  permit

And finally, our recipient restrictions. Note that policyd needs to go here so it gets all the information necessary to make a decision.

smtpd_recipient_restrictions = permit_sasl_authenticated, 
  permit_mynetworks, 
  reject_unknown_recipient_domain, 
  reject_unauth_pipelining, 
  reject_non_fqdn_recipient, 
  reject_unauth_destination, 
  check_policy_service inet:127.0.0.1:10031

Dovecot

Compile

Dovecot is also pretty straight forward to compile. The only issue I ran into was the version of krb5-config that ships with Solaris 10 identifies itself has using 1.2.1 which causes Dovecot's configure to barf (it is also old enough that it doesn't recognize krb5-config --libs gssapi). You need to update the configure script to as per the notes below to get it to work.

#!/bin/bash

# Notes: # Need to change krb5-config lines by: # - removing gssapi from --libs and --cflags calls # - add -lgss to the AUTH_LIBS lines # - don't check for version 1.2

export CC=cc export CPPFLAGS="-I/usr/sfw/include" export LDFLAGS="-R/usr/sfw/lib -L/usr/sfw/lib" ./configure --prefix=/opt/psa --sysconfdir=/etc/opt/psa/dovecot --localstatedir=/var/opt/psa/dovecot --with-gssapi --enable-header-install

make make DESTDIR=/tmp/dovecot-install install

Configure

Dovecot configuration is very straight forward.

Note that the keytab for dovecot needs to have the following to allow Postfix and Dovecot to do GSSAPI:

imap/fully.qualified.host.name
smtp/fully.qualified.host.name

The FQDN needs to be whatever the client will resolve it as. So, if you've got a CNAME of imap.otoh.org pointing to suricate.otoh.org then you need to have imap/suricate.otoh.org rather than imap/imap.otoh.org. If you go through a load balancer and use A record of imap.company.com then you'll need to set auth_gssapi_hostname appropriately.

# SSL 
ssl_cert_file = /etc/opt/psa/dovecot/dovecot-cert.pem
ssl_key_file = /etc/opt/psa/dovecot/dovecot-req.pem
ssl_ca_file =  /etc/sfw/openssl/cacert.pem

# Don't allow sending passwords in the clear disable_plaintext_auth = yes

# Use a real timestamp log_timestamp = "%Y-%m-%dT%H:%M:%S%z "

syslog_facility = mail

# Don't advertise what we are login_greeting = Ready.

# Maildirs mail_location = maildir:~/Maildir

# We shouldn't use dotlocks, but if we do, use O_EXCL to open it dotlock_use_excl = yes

# Fast and NFS safe lock_method = fcntl

# Again, we're not using mbox, but if for some reason we do, use fcntl mbox_read_locks = fcntl mbox_write_locks = fcntl

# System accounts don't use IMAP first_valid_uid = 1000

# Use hardlinks to save space maildir_copy_with_hardlinks = yes maildir_copy_preserve_filename = yes

# Advertise capabilities in the greeting protocol imap { login_greeting_capability = yes }

protocol pop3 { }

protocol lda { postmaster_address = postmaster@XXX # yes, this is set properly in the configuration

# set these to null and set syslog_facility so everything is sent to syslog log_path = info_log_path = syslog_facility = mail

# Use Seive mail_plugins = cmusieve }

# Keytab has to have imap/HOSTNAME and smtp/HOSTNAME in it auth_krb5_keytab = /etc/opt/psa/dovecot/dovecot.keytab

# Allow both GSSAPI and username/password auth default { mechanisms = plain gssapi passdb pam { } userdb passwd { }

# Have to run authd as root so we can open the shadow file user = root

# This is required for Postfix to talk to us socket listen { client { path = /var/opt/psa/postfix/private/auth mode = 0660 user = postfix group = postfix } } }

The other issue I found is that the Dovecot auth daemon segfaults if you have pam_kerb5 in it's auth stack. Add this to /etc/pam.conf to fix this.

dovecot auth requisite          pam_authtok_get.so.1
dovecot auth required           pam_dhkeys.so.1
dovecot auth required           pam_unix_cred.so.1
dovecot auth required           pam_unix_auth.so.1

Dovecot also uses the dovecot service by default, you can tell it to use specific services by setting:

auth default {
  passdb pam {
    args = *
  }
}

Then you'll need service specific (imap, pop for example) auth lines in your /etc/pam.conf.

Dovecot Sieve

This is very simple, just compile and install.

MySQL

Policyd requires MySQL :(

Compile

I took a look at the MySQL AB packages but they install in a nasty fashion (not zone aware and assume /usr/local) and the postinstall scripts are broken so I built my own :(

#!/bin/bash

export PATH="/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin"

make clean

arch="$(isainfo -k)" export CC=cc export CXX=CC export CPPFLAGS="-I/usr/sfw/include" export LDFLAGS="-R/usr/sfw/lib/${arch} -R/usr/sfw/lib -L/usr/sfw/lib/${arch} -L/usr/sfw/lib"

export ASFLAGS="-xarch=${arch}" export CFLAGS="-Xa -xstrconst -mt -D_FORTEC_ -m64" export CXXFLAGS="-noex -mt -D_FORTEC_ -m64"

./configure --prefix=/opt/psa --sysconfdir=/etc/opt/psa/mysql --localstatedir=/var/opt/psa/mysql --with-mysqld-user=mysql --without-debug --enable-thread-safe-client --enable-local-infile --enable-assembler --with-extra-charsets=complex --with-openssl --with-openssl-includes=/usr/sfw/include --with-openssl-libs=/usr/sfw/lib

make make DESTDIR=/tmp/mysql-install install

Configure

Use the standard MySQL process to create a base DB. I just used the small systems my.cnf as this DB is tiny.

Policyd

Compile

Use the 1.9x series (yes, it's beta but it's got a proper configure setup and should have the patches I wrote to make it compile cleanly on Solaris applied to it by the time you read this).

#!/bin/bash

export PATH="/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin"

export CC=cc export CPPFLAGS="-I/usr/sfw/include -I/opt/psa/include" export LDFLAGS="-R/usr/sfw/lib -L/usr/sfw/lib -R/opt/psa/lib -L/opt/psa/lib -R/opt/psa/lib/mysql -L/opt/psa/lib/mysql"

export CFLAGS="-m64" export CXXFLAGS="-m64"

make clean

./configure --prefix=/opt/psa --sysconfdir=/etc/opt/psa/policyd --localstatedir=/var/opt/psa/policyd --with-mysql-include=/opt/psa/include/mysql --with-mysql-lib=/opt/psa/lib/mysql

make make DESTDIR=/tmp/policyd-install install

Configure

First, follow the instructions; setup the policyd database and import the base SQL into the database.

The default mysql user is postfix but given this is policyd not postfix, I prefer to use the policyd user for MySQL.

Configuration of policyd is pretty straight forward, there's little tweaking to be done just follow the instructions.

The only gotcha's I fell for are that all configuration items need to be specified (i.e. don't comment out the stuff you're not using, set it to a default or blank value). This means you need something like:

# chroot:
#
#   directory to change to before binding
#
CHROOT=/

# # uid: # # userid for the policy daemon to run as # UID=125

# # gid: # # groupid for the policy daemon to run as # GID=125

even if you're starting it via SMF. In this case, 125 maps to the policyd user.

The other trap was that you need to set BLACKLISTING=1 to have it insert anything for any of the blacklist checks into the database. You can't just turn on BLACKLIST_HELO and have it populate the database so you can look at it before enabling blocking, it's either on or off.

References

Version 1.4 last modified by Paul Armstrong on 2008-01-13 at 21:22

Comments 0

No comments for this document
Add Comment...

Please answer this simple math question: 79 + 58 =

Attachments 0

No attachments for this document

Creator: Paul Armstrong on 2008-01-13 at 21:16
This wiki is licensed under a Creative Commons license
1.0.3342