Using DES/AES Encryption in Postfix Courier Configurations


You can use AES or DES to encrypt your database passwords, used by Postfix and Courier. Of course, as AES and DES use a key to encrypt the password, the one who knows the key may decrypt it.

You could also use Encrypt option to change this (to use MySQL's encrypt), but that's not available on all versions of Courier and Postfix for current operating systems without patching it.

In the following example, I'm simply encrypting the password using the user's e-mail address. You might want to vary this a bit, generating a stronger hash using the mysql functions md5, sha1 or password to create an encryption key. You might want to use a fix hash instead (in this case think of securing your server configuration as who can read your configuration files will be able to decrypt your passwords) or use a combination of fields hashed by md5 for example to create your key.

/etc/postfix/sasl/smtp*.conf:

pwcheck_method: auxprop
auxprop_plugin: sql
mech_list: plain login
sql_engine: mysql
sql_hostnames: localhost
sql_user: postfix
sql_passwd: post
sql_database: postfix
sql_verbose: yes
select DES_DECRYPT(password,email) from users where email='%u@%r' and status='1'

Adapt the mysql credentials to fit to your system environment.

Then create the mysql auth file /etc/postfix/mysql_auth.cf:

user = postfix
password = post
dbname = postfix
table = users
select_field = email
where_field = DES_DECRYPT(password,email)
additional_conditions = and status='1'
hosts = localhost

/etc/courier/authmysqlrc:

....
MYSQL_SERVER localhost
MYSQL_USERNAME your_username
MYSQL_PASSWORD your_password
MYSQL_PORT 3306
MYSQL_DATABASE postfix
MYSQL_USER_TABLE users
#MYSQL_CRYPT_PWFIELD crypt #better, but not working in both, Postfix and Courier on all systems
MYSQL_CLEAR_PWFIELD DES_DECRYPT(password,email)
#DEFAULT_DOMAIN example.com #if no domain passed
MYSQL_UID_FIELD '5000'
MYSQL_GID_FIELD '5000'
MYSQL_LOGIN_FIELD email
MYSQL_HOME_FIELD CONCAT('/home/vmail/',SUBSTRING_INDEX(email,'@',-1),'/')
MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',1),'/')
MYSQL_WHERE_CLAUSE status='1'
....

When you create a new user, you need to encrypt the password like this:

INSERT INTO users (user_login, user_password, user_email, user_status) VALUES ('testuser', DES_ENCRYPT('testpassword', 'testuser@example.net'), 'testuser@example.net', '1');

Instead of DES_ENCRYPT, you may also use AES_ENCRYPT.

The advantage here is that you have encrypted passwords in your database, but you'll be able to decrypt them.

To make your changes take effect, you should restart some services:

/etc/init.d/courier-authdaemon restart
/etc/init.d/courier-imap restart
/etc/init.d/postfix restart