date: 2006-11-15 13:46:50+00:00


categories: - Howto - Linux - Postfix - Red Hat/CentOS - Security - SQL

Thanks to Luca Gibelli for his document about Postfix SMTP AUTH. It helped me a lot, this article is largely based on his work, I adapted it to match RHEL/CentOS systems.

Scenario Your mail server hosts multiple domains. You use a MySQL database as backend for user authentication.

Users authenticate to the POP3/IMAP server as : username : password : test123

You want to allow them to authenticate with SMTP AUTH using the same credentials. The credentials are stored in a MySQL database in an encrypted form. You want them to authenticate on a secure channel (TLS)

What you need postfix with MySQL, TLS support (available in the centosplus repository) cyrus-sasl (available in the base repo) cyrus-sasl-plain (ditto) cyrus-sasl-md5 (ditto) openssl (ditto) pam_mysql (ditto)

pam_mysql is available at : el3 : el4 :

How to set it up * Edit /etc/pam.d/smtp :


auth required service=system-auth

account required service=system-auth

Comment : SMTP AUTH with MySQL

This is the first line

auth required user=database passwd=password host= db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1 md5=1

This is a second line

account sufficient user=database passwd=password host= db=postfix table=mailbox usercolumn=username passwdcolumn=password crypt=1 md5=1`

Change the info to match your configuration The auth and account lines could be cut in half in this article. If you are copy-pasting the text, make sure everything holds on one line on both auth and account statement.

  • Edit /usr/lib/sasl2/smtpd.conf :

`pwcheck_method: saslauthd

add the following two lines for smtp auth

mech_list: PLAIN LOGIN log_level: 5`

  • Make sure "MECH=pam" is present under /etc/sysconfig/saslauthd


I'm currently installing a mail server under CentOS 4.4 while this guide describes the CentOS 3 way I thought it did not matter but there's a small difference with saslauthd..

Under CentOS 4.x you need to add the following line in /etc/sysconfig/saslauthd : FLAGS="-r"

Without the -r flag, saslauthd would query the MySQL database this way : 25 Query SELECT password FROM mailbox WHERE username = 'admin'

Obviously, the whole email address is stored in the database, with the -r flag, it will query correctly : 26 Query SELECT password FROM mailbox WHERE username = ''

The man page for saslauthd mentions the -r flag under CentOS 4 only..

-r Combine the realm with the login (with an ’@’ sign in between). e.g. login: "foo" realm: "bar" will get passed as login: "foo@bar". Note that the realm will still be passed, which may lead to unexpected behavior. ===**

  • Add the following lines to /etc/postfix/ :

smtpd_sasl_local_domain = smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous broken_sasl_auth_clients = yes

This will enable SASL authentication to all the smtp ssl instances. You can disable sasl auth for certain instances under /etc/postfix/master.rc if you need inet n - n - 10 smtpd -o smtpd_sasl_auth_enable=no

  • Under /etc/postfix/ :

Add "permit_sasl_authenticated" to the "smtpd_recipient_restrictions" section :

smtpd_recipient_restrictions = ... permit_sasl_authenticated reject_unauth_destination

Enable TLS

  • Finally create the SSL certificate needed by TLS:

mkdir /etc/postfix/tls

cd /etc/postfix/tls

openssl genrsa -des3 -rand /etc/hosts -out smtpd.key 1024

openssl req -new -key smtpd.key -out smtpd.csr

Note: leave "challenge password" empty.

openssl x509 -req -days 3650 -in smtpd.csr -signkey smtpd.key -out smtpd.crt

openssl rsa -in smtpd.key -out smtpd.key.unencrypted

mv -f smtpd.key.unencrypted smtpd.key

openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650

  • Add the following lines to /etc/postfix/

`smtpd_tls_auth_only = no

smtp_use_tls : if set to "no" do not use TLS when connecting to server offering STARTTLS

smtp_use_tls = no

smtpd_use_tls : if set to "yes", offers STARTTLS to SMTP clients

smtpd_use_tls = yes

smtp_tls_note_starttls_offer : logs STARTTLS offers from remote SMTP server

smtp_tls_note_starttls_offer = yes smtpd_tls_key_file = /etc/postfix/tls/smtpd.key smtpd_tls_cert_file = /etc/postfix/tls/smtpd.crt smtpd_tls_CAfile = /etc/postfix/tls/cacert.pem smtpd_tls_loglevel = 1 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s tls_random_source = dev:/dev/urandom tls_daemon_random_source = dev:/dev/urandom`

Restart the services service saslauthd restart service postfix restart

Start services at boot chkconfig postfix on chkconfig saslauthd on

Debugging issues with verbose logs :

*** pam-mysql : ** add "verbose=true" to the end of the auth and account lines in /etc/pam.d/smtp

*** saslauthd :** stop the service start saslauthd manually : # saslauthd -a pam -d

Links :

**If you want to run Postfix chrooted with a MySQL backend : ** **If you want to run Postfix chrooted with saslauthd : ** **Script to enable/disable Postfix chroot (tested with Postfix 2.2.8) : **