SQL Authentication¶
Pre-requisites¶
All examples use MySQL but it should be possible to use PostgresQL or similar database.
MySQL Server¶
This document assumes that MySQL is running on localhost
and that you can connect as a user who has the required privileges to add users and databases.
We will create a database db_mail
with the mail_users
table and grant SELECT privileges to the user db_mail_user
with password db_mail_password
The database connection details are completely changeable and you can even use a remote MySQL server, but remember to change them throughout the instructions below.
Note
The database table doesn't need to be writable by the Cyrus server. If your master database is held on a different server, you could use MySQL replication to replicate just the mail_users table to the Cyrus server and make the table read-only on the replica.
saslauthd¶
saslauthd needs to be configured to use PAM. In the output of ps ax | grep saslauthd it'll probably look like saslauthd -a pam
Optionally -r
(realm) parameter with saslauthd if you plan to use username@domain style logins instead of just username
pam_mysql¶
pam_mysql (0.7) from http://pam-mysql.sourceforge.net/ - it's quite likely that other MySQL PAM modules would work, but this one definitely works and using a different version will require different configuration to that described below.
Database structure¶
At the very minimum, the mail_users table requires username and password columns. It is also recommended to include a column to indicate if the account is permitted to login or not since this will make disabling an account much easier than altering the password field.
CREATE DATABASE db_mail;
GRANT SELECT ON db_mail.* TO 'db_mail_user'@'localhost'
IDENTIFIED BY 'db_mail_password';
USE db_mail;
CREATE TABLE mail_users (
username VARCHAR(200) NOT NULL,
password VARCHAR(40) NOT NULL,
active TINYINT(1) NOT NULL DEFAULT 1,
INDEX username_idx(username)
);
Next insert an example record for testing purposes. The username must match the mailbox created in Cyrus and the login is the full email address. If you don't need/want domain based virtual users, you can also just insert a username without the @example.org
INSERT INTO mail_users SET username='jane@example.org',
password=ENCRYPT('janepass','$1$1234abcd'), active=1;
Warning
You should use better passwords and salts in production!
On modern versions of Linux, the salts used for the password encryption should be $1$ followed by 8 random alphanumeric characters. Other operating systems may have different requirements for the salt as used by the system crypt(3) function and described in the relevant man page.
PAM configuration for use with saslauthd¶
Assuming both POP3 and IMAP services are being offered, you will need to update /etc/pam.d/pop and /etc/pam.d/imap to allow MySQL to be used.
Assuming the files already contain the following
#%PAM-1.0
auth required pam_nologin.so
auth include system-auth
account include system-auth
session include system-auth
amend them to read
#%PAM-1.0
auth required pam_nologin.so
auth sufficient pam_mysql.so config_file=/etc/mail-pam-mysql.conf
auth include system-auth
account sufficient pam_mysql.so config_file=/etc/mail-pam-mysql.conf
account include system-auth
password required pam_deny.so
session include system-auth
The configuration file specified also needs to be created. Using the database connection details established earlier, the configuration file should contain:
verbose = 0;
users.host = localhost;
users.database = db_mail;
users.db_user = db_mail_user;
users.db_passwd = db_mail_password;
users.password_crypt = 1;
users.md5 = true;
users.table = mail_users;
users.where_clause = active = 1;
users.user_column = username;
users.password_column = password;
Warning
Because this file contains the database password, you should ensure it is properly protected. Change the ownership to root:root (if it's not already), and chmod 600 /etc/mail-pam-mysql.conf
Changing verbose to 1 results in a large amount of debugging output in the logs, including the SQL being run. This can be useful if it's not working as expected. If you are using the MySQL PASSWORD() function, change password_crypt to 1
Testing the SASL configuration¶
If everything is correct, you should be able to run the following commands:
$ testsaslauthd -u jane -r example.org -p janepass -s imap 0: OK "Success." $ testsaslauthd -u jane -r example.org -p janepas3 -s imap 0: NO "authentication failed" $ testsaslauthd -u jane -r example.org -p janepass -s pop 0: NO "authentication failed"
This fails because we haven't setup the PAM config file for the POP service, update /etc/pam.d/pop by adding the following two 'sufficient' lines above the appropriate 'required' lines.
auth sufficient pam_mysql.so config_file=/etc/mail-pam-mysql.conf
account sufficient pam_mysql.so config_file=/etc/mail-pam-mysql.conf
If everything is correct, you should be able to run the following and get an OK response.
$ testsaslauthd -u jane -r example.org -p janepass -s pop 0: OK "Success."
Create the test mailboxes within Cyrus¶
cyradm> cm user/jane@example.org
If you get an error when creating the mailbox, check that you have virtdomains: userid
and unixhierarchysep: on
in /etc/imapd.conf as the syntax for the mailbox name will be different.
Testing everything together¶
This step assumes Cyrus is already configured and listening on localhost port 143 (IMAP). Change the openssl command as required if it's not.
$ openssl s_client -connect localhost:143 -starttls imap ... . OK Completed 0 LOGIN jane@example.org janepass 0 OK [CAPABILITY ...] User logged in ... 0 LOGOUT * BYE LOGOUT received 0 OK Completed
If you don't get an OK response to the LOGIN command, something isn't working properly and there may be useful log messages in either maillog, messages or secure log files.
Back to Features