I recently had to move to a new server and had some troube getting Postfix and Courier to work as I wanted. The tutorial I used to follow a bunch of years ago is gone and the tutorials I found were either outdated, wrong or didn’t do it my way. So with some inspiration from other tutorials including the old one I used to have, I have written my own modified version.
Step 1: Prepare your certificate now as you will be using it later
If you don’t already have one you can get one for free at StartSSL
This tutorial wont cover the steps at StartSSL as there are other documents for that.
Files that you will need:
– yourcert.crt
– yourprivatekey.key (in a decrypted state for server purpose)
– ca.pem
– sub.class1.server.ca.pem
Place them in a folder like /etc/ssl/StartCom/year-month-day
For example, I use /etc/ssl/StartCom/2015-08-10 since that is the expiration date for one of my certs.
When the files have been placed there you need to do the following:
cat yourcert.crt yourprivatekey.key ca.pem sub.class1.server.ca.pem > combined.pem
This is because Courier wants it in a pem file later, while Postfix wants them separated.
There might be a way to keep it consistent but I haven’t checked.
Also remember to set permissions to this folder!
chown -R root:root /etc/ssl/StartCom chmod -R 640 /etc/ssl/StartCom
Your private key is in there and you need to protect it.
Step 2: Install required software
apt-get install postfix postfix-mysql postfix-doc mysql-client mysql-server courier-authdaemon courier-authlib-mysql courier-pop courier-pop-ssl courier-imap courier-imap-ssl libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl apache2 libapache2-mod-php5 php5 php5-mysql libpam-smbpass
Step 3: Setup MySQL database
mysql -u root -p
CREATE mail; GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail'@'localhost' IDENTIFIED BY 'mail_password'; GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO 'mail'@'localhost.localdomain' IDENTIFIED BY 'mail_password'; FLUSH PRIVILEGES; USE mail; CREATE TABLE domains ( domain varchar(50) NOT NULL, PRIMARY KEY (domain) ) ENGINE=MyISAM; CREATE TABLE forwardings ( source varchar(80) NOT NULL, destination TEXT NOT NULL, PRIMARY KEY (source) ) ENGINE=MyISAM; CREATE TABLE users ( email varchar(80) NOT NULL, password varchar(20) NOT NULL, PRIMARY KEY (email) ) ENGINE=MyISAM; CREATE TABLE transport ( domain varchar(128) NOT NULL default '', transport varchar(128) NOT NULL default '', UNIQUE KEY domain (domain) ) ENGINE=MyISAM; exit
Step 4: Configure postfix
Create these files below and paste the content that follows.
Remember to replace the user and password with whatever you chose before.
vim /etc/postfix/mysql-virtual_domains.cf user = mail password = mail_password dbname = mail table = domains select_field = 'virtual' where_field = domain hosts = 127.0.0.1
vim /etc/postfix/mysql-virtual_forwardings.cf user = mail password = mail_password dbname = mail table = forwardings select_field = destination where_field = source hosts = 127.0.0.1
vim /etc/postfix/mysql-virtual_mailboxes.cf user = mail password = mail_password dbname = mail table = users select_field = CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/') where_field = email hosts = 127.0.0.1
vim /etc/postfix/mysql-virtual_email2email.cf user = mail password = mail_password dbname = mail table = users select_field = email where_field = email hosts = 127.0.0.1
vim /etc/postfix/mysql-virtual_transports.cf user = mail password = mail_password dbname = mail table = transport select_field = transport where_field = domain hosts = 127.0.0.1
Change permissions of the files
chmod o= /etc/postfix/mysql-virtual_*.cf chgrp postfix /etc/postfix/mysql-virtual_*.cf
Create user vmail
groupadd -g 5000 vmail useradd -g vmail -u 5000 vmail -d /home/vmail -m
Set options in the Postfix configuration file.
Replace server1.example.com with a FQDN of your server.
Also replace the cert and key file with the cert and key file in your StartCom folder.
For example instead of /etc/postfix/smtpd.cert you write /etc/ssl/StartCom/2015-08-10/yourcert.crt
postconf -e 'myhostname = server1.example.com' postconf -e 'mydestination = localhost, localhost.localdomain' postconf -e 'mynetworks = 127.0.0.0/8' postconf -e 'virtual_alias_domains =' postconf -e 'virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf' postconf -e 'virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf' postconf -e 'virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf' postconf -e 'virtual_mailbox_base = /home/vmail' postconf -e 'virtual_uid_maps = static:5000' postconf -e 'virtual_gid_maps = static:5000' postconf -e 'smtpd_sasl_auth_enable = yes' postconf -e 'broken_sasl_auth_clients = yes' postconf -e 'smtpd_sasl_authenticated_header = yes' postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination' postconf -e 'smtpd_use_tls = yes' postconf -e 'smtpd_tls_auth_only = yes' postconf -e 'smtpd_tls_received_header = yes' postconf -e 'smtpd_helo_required = yes' postconf -e 'smtp_tls_note_starttls_offer = yes' postconf -e 'smtpd_tls_cert_file = /etc/postfix/smtpd.cert' postconf -e 'smtpd_tls_key_file = /etc/postfix/smtpd.key' postconf -e 'smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3' postconf -e 'transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf' postconf -e 'proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps'
Now open /etc/postfix/master.cf and uncomment the following section.
The format of these lines are important so only remove the comment characters (#) and nothing else.
#smtps inet n - - - - smtpd # -o syslog_name=postfix/smtps # -o smtpd_tls_wrappermode=yes # -o smtpd_sasl_auth_enable=yes # -o smtpd_client_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING
Step 5: Configure Saslauthd
Create a folder for saslauthd
mkdir -p /var/spool/postfix/var/run/saslauthd
Open the following file.
Set START to yes and change the line OPTIONS=”-c -m /var/run/saslauthd” to OPTIONS=”-c -m /var/spool/postfix/var/run/saslauthd -r”.
vim /etc/default/saslauthd
Open the following file and configure pam to use MySQL to authenticate you.
vim /etc/pam.d/smtp
auth required pam_mysql.so user=mail passwd=mail_password host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1 account sufficient pam_mysql.so user=mail passwd=mail_password host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=1
Edit smtpd.conf and configure sasl to use the sql plugin to authenticate users.
vim /etc/postfix/sasl/smtpd.conf pwcheck_method: saslauthd mech_list: plain login allow_plaintext: true auxprop_plugin: sql sql_engine: mysql sql_hostnames: 127.0.0.1 sql_user: mail sql_passwd: mail_password sql_database: mail sql_select: select password from users where email = '%u@%r'
Add the postfix user to the sasl group
adduser postfix sasl
Restart postfix and saslauthd
/etc/init.d/postfix restart /etc/init.d/saslauthd restart
Step 6: Configure courier
Edit Courier to use MySQL to authenticate
vim /etc/courier/authdaemonrc [...] authmodulelist="authmysql" [...]
cp /etc/courier/authmysqlrc /etc/courier/authmysqlrc_orig cat /dev/null > /etc/courier/authmysqlrc
vim /etc/courier/authmysqlrc MYSQL_SERVER localhost MYSQL_USERNAME mail_admin MYSQL_PASSWORD mail_password MYSQL_PORT 0 MYSQL_DATABASE mail MYSQL_USER_TABLE users MYSQL_CRYPT_PWFIELD password MYSQL_UID_FIELD 5000 MYSQL_GID_FIELD 5000 MYSQL_LOGIN_FIELD email MYSQL_HOME_FIELD "/home/vmail" MYSQL_MAILDIR_FIELD CONCAT(SUBSTRING_INDEX(email,'@',-1),'/',SUBSTRING_INDEX(email,'@',1),'/')
Now configure Courier to use your StartSSL cert for imap.
Courier wants the combined pem file.
vim /etc/courier/imapd-ssl
Find the row TLS_CERTFILE and change the path.
For example: TLS_CERTFILE=/etc/ssl/StartCom/2015-08-10/combined.pem
Also find the the following rows and make sure they are set to the values below.
IMAPDSTARTTLS=YES IMAP_TLS_REQUIRED=1 TLS_PROTOCOL=TLS1 TLS_STARTTLS_PROTOCOL=TLS1
Since I don’t use pop3 I will make sure to disable it.
vim /etc/courier/pop3-ssl
Find the the following row and make sure it’s set to the value below.
POP3DSSLSTART=NO
vim /etc/courier/pop3
POP3DSTART=NO
Restart courier
/etc/init.d/courier-authdaemon restart /etc/init.d/courier-imap restart /etc/init.d/courier-imap-ssl restart /etc/init.d/courier-pop restart /etc/init.d/courier-pop-ssl restart
Step 7: Modify aliases
vim /etc/aliases [...] postmaster: root root: postmaster@yourdomain.tld [...]
Issue this command to update the aliases
newaliases
That should be all.
Don’t forget to populate the database with a user and a domain.
INSERT INTO domains VALUES('somedomain.com'); INSERT INTO users VALUES('user@somedomain.com', ENCRYPT('mypassword'));
If you have any comments or feedback then feel free to leave them in the comment section below.
This tutorial will be updated later with some more security related settings to protect against certain SSL/TLS attacks.