Cheap UK Web Hosting Company, Cheap Web Hosting UK, Low Cost Webhosting Space, Low Cost Web Site Hosting UK, Domain Hosting UK and Domain Name Registration

Cheap web hosting uk and domain name registration services from Webconexion Internet Solutions LTD
Tel: 0208 144 2211      Fax: 0871 661 9456      Email: sales@webconexion.net

  Installing Postfix, Cyrus SASL, and Courier IMAP to use MySQL for Virtual Domains


 
 

Introduction

This tutorial has been compiled after many months of searching the Internet for a viable virtual mail server installation. Many websites had information on this subject but the tutorials that were found either were incomplete or just did not work for us.

The tutorial presented below provides a working installation of Postfix, Cyrus SASL and Courier IMAP, connecting to a MySQL database to provide virtual email services on RedHat 9/Fedora Core 2. Cyrus SASL is used to provide authenticated SMTP, also via a MySQL database.

We will guide you through the installation of all the software that we used together with details of problems we encountered and then provide the required configuration to provide a virtual mail server solution for your Red Hat 9 or Fedora Core 2 server.

Overview of the virtual mail solution

  • Provides authenticated SMTP via Cyrus SASL. Cyrus SASL authenticates users by connecting to a MySQL database
  • The Postfix MTA will allow SMTP Authenticated SASL connections instead of using relay domains.
  • Postfix maildrop will deliver email to both real and virtual users home directories using Maildir style mail boxes.
  • Courier IMAP and POP3 will be available to allow users to retrieve their email. Authentication will again be provided by a MySQL database.
  • Virtual users will not require an actual real Linux user account.

Software Required for this Tutorial

Installation and Configuration


MySQL Installation and Configuration


Installing the software

Generally, it is easier to install MySQL via the RPM distibution than to compile from source. This tutorial will provide information on installing the RPM version only although there is no reason why a version built from source would not work so long as shared libraries are included.

$ cd /software-install/
$ wget http://dev.mysql.com/get/Downloads/MySQL-4.0/MySQL-client-4.0.18-0.i386.rpm \
	/from/http://www.mirror.ac.uk/sites/ftp.mysql.com/
$ wget http://dev.mysql.com/get/Downloads/MySQL-4.0/MySQL-server-4.0.18-0.i386.rpm \
	/from/http://www.mirror.ac.uk/sites/ftp.mysql.com/
$ wget http://dev.mysql.com/get/Downloads/MySQL-4.0/MySQL-devel-4.0.18-0.i386.rpm \
	/from/http://www.mirror.ac.uk/sites/ftp.mysql.com/
$ wget http://dev.mysql.com/get/Downloads/MySQL-4.0/MySQL-shared-4.0.18-0.i386.rpm \
	/from/http://www.mirror.ac.uk/sites/ftp.mysql.com/
$ rpm -i MySQL-client-4.0.18-0.i386.rpm \
	MySQL-server-4.0.18-0.i386.rpm \
	MySQL-devel-4.0.18-0.i386.rpm \
	MySQL-shared-4.0.18-0.i386.rpm

This will install the four MySQL RPM packages and provide all the required startup scripts. MySQL is now fully installed and ready for use.

MySQL can be started and stopped using the /etc/init.d/ scripts as installed as part of the RPM.

$ /etc/init.d/mysql start
$ /etc/init.d/mysql stop

Ensure that MySQL has been started in preparation for the next section.

Configuring the software

You will first need to change the root password for MySQL for security reasons.

$ mysql
mysql> use mysql;
mysql> UPDATE user SET password ='your-password' WHERE User='root';

You now need to create a new user and a database for the tables that will be used by Postfix, Cyrus SASL and Courier IMAP. This user must have full grant permissions on this database. Note that the grant tables will also need to be reloaded.

mysql> CREATE DATABASE postfix;
mysql> GRANT ALL on postfix.* to postfix@localhost identified by 'choose-a-password';
mysql> quit;
$ mysqladmin -uroot -pyour-password reload

We now need to create the required tables in our new database. Begin by logging back into MySQL as the postfix user.

$ mysql -upostfix -pyour-password postfix;
mysql> DROP TABLE IF EXISTS postfix_access;
mysql> CREATE TABLE postfix_access ( \
  id int(10) unsigned NOT NULL auto_increment, \
  source varchar(128) NOT NULL default '', \
  access varchar(128) NOT NULL default '', \
  type enum('recipient','sender','client') NOT NULL default 'recipient', \
  PRIMARY KEY  (id) \
) TYPE=MyISAM;

mysql> DROP TABLE IF EXISTS postfix_alias;
mysql> CREATE TABLE postfix_alias ( \
  id int(11) unsigned NOT NULL auto_increment, \
  alias varchar(128) NOT NULL default '', \
  destination varchar(128) NOT NULL default '', \
  PRIMARY KEY  (id) \
) TYPE=MyISAM;

mysql> DROP TABLE IF EXISTS postfix_relocated;
mysql> CREATE TABLE postfix_relocated ( \
  id int(11) unsigned NOT NULL auto_increment, \
  email varchar(128) NOT NULL default '', \
  destination varchar(128) NOT NULL default '', \
  PRIMARY KEY  (id) \
) TYPE=MyISAM;

mysql> DROP TABLE IF EXISTS postfix_smtp;
mysql> CREATE TABLE postfix_smtp ( \
  id int(11) NOT NULL auto_increment, \
  email varchar(100) NOT NULL default '', \
  clear varchar(20) NOT NULL default '', \
  PRIMARY KEY  (id) \
) TYPE=MyISAM;

mysql> DROP TABLE IF EXISTS postfix_transport;
mysql> CREATE TABLE postfix_transport ( \
  id int(11) unsigned NOT NULL auto_increment, \
  domain varchar(128) NOT NULL default '', \
  destination varchar(128) NOT NULL default '', \
  PRIMARY KEY  (id), \
  UNIQUE KEY domain (domain) \
) TYPE=MyISAM;

mysql> DROP TABLE IF EXISTS postfix_users;
mysql> CREATE TABLE postfix_users ( \
  id int(11) unsigned NOT NULL auto_increment, \
  email varchar(128) NOT NULL default '', \
  clear varchar(128) NOT NULL default '', \
  uid int(11) unsigned NOT NULL default '0', \
  gid int(11) unsigned NOT NULL default '0', \
  homedir tinytext NOT NULL, \
  maildir tinytext NOT NULL, \
  quota tinytext NOT NULL, \
  access enum('Y','N') NOT NULL default 'Y', \
  postfix enum('Y','N') NOT NULL default 'Y', \
  PRIMARY KEY  (id), \
  UNIQUE KEY email (email) \
) TYPE=MyISAM;

mysql> DROP TABLE IF EXISTS postfix_virtual;
mysql> CREATE TABLE postfix_virtual ( \
  id int(11) unsigned NOT NULL auto_increment, \
  email varchar(128) NOT NULL default '', \
  destination varchar(128) NOT NULL default '', \
  PRIMARY KEY  (id) \
) TYPE=MyISAM;

We recommend that you create a my.cnf file in your /etc/ directory and enable MySQL logging. This will aid you in testing the installation once all the software is installed. I have provided an example my.cnf file below. This will create a file in /var/log/mysql.log and will show all activity on the MySQL database: Example my.cnf file with logging enabled

Cyrus SASL Installation and Configuration


Installing the software

The following assumes that you have MySQL setup in /usr/local/mysql. We will be installing Cyrus SASL from source with built in MySQL support to allow authentication via a MySQL database. Prior to installing these modules, you should remove any pre-installed ones that may exist in /usr/lib, /usr/local/lib, and /usr/local/lib/sasl2.

$ wget ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/cyrus-sasl-2.1.18.tar.gz
$ export CPPFLAGS="-I/usr/include/mysql"
$ export LDFLAGS="-L/usr/lib/mysql -lmysqlclient -lz -lm"
$ ./configure \
	--enable-anon \ 
	--enable-plain \
	--enable-login \
	--enable-sql \
	--disable-krb4 \
	--disable-otp \
	--disable-cram \
	--disable-digest \
	--with-mysql=/usr/lib/mysql \
	--without-pam \
	--without-saslauthd \
	--without-pwcheck \
	--with-plugindir=/usr/local/lib/sasl2
$ make
$ make install

Check to make sure that the path /usr/local/lib is in /etc/ld.so.conf. If it is not, append that path to the file and run ldconfig (as root).

If this step is not carried out then the postfix mail log will report the following error when attempting to send email via SMTP:
fatal: no SASL authentication mechanisms

$ echo "/usr/local/lib" >> /etc/ld.so.conf
$ ldconfig

You may need to add the following symbolic link. I think you can just do away with /usr/lib/sasl and /usr/lib/sasl2 if they are present as part of the Red Hat/Fedora installation.

$ ln -s /usr/local/lib/sasl2/ /usr/lib/sasl2
NOTE: If an error is seen during make you will need to edit lib/checkpw.c file and add an include for errno.h. This appears to be a bug in the distribution that we used for this tutorial.

$ vi /root/tar.gz/cyrus-sasl-2.1.18/lib/checkpw.c

#include <errno.h>

Configuring the software

We now need to tell Cyrus SASL to use a MySQL database for authentication and which table contains the authentication details.

$ vi /usr/local/lib/sasl2/smtpd.conf

pwcheck_method: auxprop
auxprop_plugin: sql
sql_engine: mysql
mech_list: sql plain login
sql_hostnames: localhost
sql_user: postfix
sql_passwd: your-password
sql_database: postfix
sql_statement: SELECT clear FROM postfix_smtp WHERE email = '%u@%r'
sql_verbose: yes

Postfix Installation and Configuration


Installing the software

Compiling Postfix is pretty straight forward. Be sure to add the postfix user and group. During the install it will ask for the user and group, use postfix and postdrop. For the configuration directory, specify /etc/postfix.

Add the postfix user and postdrop group. You may need to change the UID and GID accordinly.

$ vi /etc/passwd

postfix:x:101:103::/var/spool/postfix:/bin/true

$ vi /etc/group

postdrop:x:102:

We will be compiling Postfix from source with MySQL support.

$ wget ftp://postfix.ulimit.org/postfix/official/postfix-2.1.1.tar.gz
$ tar zxvf postfix-2.0.16.tar.gz
$ make makefiles \
	'CCARGS=-DHAS_MYSQL -I/usr/include/mysql -DUSE_SASL_AUTH -I/usr/local/include/sasl' \
	'AUXLIBS=-L/usr/lib/mysql -lmysqlclient -lz -lm -L/usr/local/lib -lsasl2'
$ make install

Configuring the software

We now need to configure Postfix to use MySQL. We will be editing the /etc/postfix/main.cf file and also creating a series of MySQL specific .cf files that are used to connect to the MySQL tables we created earlier.

$ vi /etc/postfix/main.cf

home_mailbox = Maildir/
recipient_delimiter = +
mydestination = $myhostname, $transport_maps
alias_maps = mysql:/etc/postfix/mysql-aliases.cf
relocated_maps = mysql:/etc/postfix/mysql-relocated.cf
transport_maps = mysql:/etc/postfix/mysql-transport.cf
virtual_maps = mysql:/etc/postfix/mysql-virtual.cf
local_recipient_maps = $alias_maps $virtual_mailbox_maps unix:passwd.byname

virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-maps.cf
virtual_uid_maps = mysql:/etc/postfix/mysql-virtual-uid.cf
virtual_gid_maps = mysql:/etc/postfix/mysql-virtual-gid.cf

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
mail_owner = postfix

myhostname = domain.com
mydomain = sub.domain.com
myorigin = $mydomain

unknown_local_recipient_reject_code = 550
debug_peer_level = 2
debugger_command = \
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin \
         xxgdb $daemon_directory/$process_name $process_id & sleep 5 \
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/local/man
sample_directory = /etc/postfix
readme_directory = no

broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_recipient_restrictions = permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_local_domain = $myhostname
$ vi /etc/postfix/mysql-aliases.cf

user         		= postfix
password     		= your-password
dbname       		= postfix
table        		= postfix_alias
select_field 		= destination
where_field  		= alias
hosts        		= localhost

$ vi /etc/postfix/mysql-client.cf

user         		= postfix
password     		= your-password
dbname       		= postfix
table        		= postfix_access
select_field 		= access
where_field  		= source
additional_conditions	= and type = 'client'
hosts        		= localhost

$ vi /etc/postfix/mysql-recipient.cf

user         		= postfix
password     		= your-password
dbname       		= postfix
table        		= postfix_access
select_field 		= access
where_field  		= source
additional_conditions	= and type = 'recipient'
hosts        		= localhost

$ vi /etc/postfix/mysql-relocated.cf

user         		= postfix
password     		= your-password
dbname       		= postfix
table			= postfix_relocated
select_field		= destination
where_field		= email
hosts        		= localhost

$ vi /etc/postfix/mysql-sender.cf

user         		= postfix
password     		= your-password
dbname       		= postfix
table        		= postfix_access
select_field 		= access
where_field  		= source
additional_conditions	= and type = 'sender'
hosts        		= localhost

$ vi /etc/postfix/mysql-transport.cf

user         		= postfix
password     		= your-password
dbname       		= postfix
table        		= postfix_transport
select_field 		= destination
where_field  		= domain
hosts        		= localhost

$ vi /etc/postfix/mysql-virtual.cf

user        		= postfix
password     		= your-password
dbname       		= postfix
table        		= postfix_virtual
select_field 		= destination
where_field  		= email
hosts        		= localhost

$ vi /etc/postfix/mysql-virtual-gid.cf

user                  	= postfix
password              	= your-password
dbname			= postfix
table                 	= postfix_users
select_field          	= gid
where_field           	= email
additional_conditions 	= and postfix = 'y'
hosts                 	= localhost

$ vi /etc/postfix/mysql-virtual-maps.cf

user                  	= postfix
password              	= your-password
dbname                	= postfix
table                 	= postfix_users
select_field          	= maildir
where_field           	= email
additional_conditions 	= and postfix = 'y'
hosts                 	= localhost

$ vi /etc/postfix/mysql-virtual-uid.cf

user                  	= postfix
password              	= your-password
dbname                	= postfix
table                 	= postfix_users
select_field          	= uid
where_field           	= email
additional_conditions 	= and postfix = 'y'
hosts                 	= localhost

You will now need to create the vmail user and group. You may need to change the UID and GID accordinly.

$ vi /etc/passwd

vmail:x:1008:1008::/home/vmail:/bin/true

$ vi /etc/group

vmail:x:1008:

We must now create the directory where email for virtual users will be stored.

$ mkdir /home/vmail/
$ chown vmail.vmail /home/vmail/

Courier IMAP Installation and Configuration


Installing the software

As with Postfix, Courier IMAP should be simple to install. We will be installing Courier IMAP from source with MySQL support. We will use /usr/local/courier as the base directory for the installation.

<as non root user>
$ wget http://www.courier-mta.org/beta/imap/courier-imap-3.0.4.20040524.tar.bz2
$ bzip2 -dc courier-imap-3.0.4.20040524.tar.bz2 | tar xvf -
$ cd courier-imap-3.0.4.20040524
$ ./configure \
	--prefix=/usr/local/courier \
	--with-authmysql \
	--with-mysql-libs=/usr/lib/mysql/ \
	--with-mysql-includes=/usr/include/mysql \
	--with-redhat
$ make

<as root>
$ make install
$ make install-configure

The /usr/local/courier/bin/ contains the IMAP and POP init.d scripts. Follow the following steps to copy them into the correct location.

$ cp /usr/local/courier/bin/imapd /etc/init.d/imapd
$ cp /usr/local/courier/bin/ipop3d /etc/init.d/ipop3d
$ chmod 700 /etc/init.d/imapd
$ chmod 700 /etc/init.d/ipop3d

The IMAP and POP3 daemons can be started and stopped using the following commands.

$ /etc/init.d/imapd start
$ /etc/init.d/imapd stop

$ /etc/init.d/ipop3d start
$ /etc/init.d/ipop3d stop

Configuring the software

We now need to tell Courier IMAP to use a MySQL database for authentication and which table contains the authentication details.

$ vi /usr/local/courier/etc/authdaemonrc

authmodulelist="authmysql authpam"
$ vi /usr/local/courier/etc/authmysqlrc

MYSQL_SERVER localhost
MYSQL_USERNAME postfix
MYSQL_PASSWORD your-password
MYSQL_PORT 0
MYSQL_DATABASE postfix
MYSQL_USER_TABLE postfix_users
MYSQL_CLEAR_PWFIELD clear
MYSQL_UID_FIELD uid
MYSQL_GID_FIELD gid
MYSQL_LOGIN_FIELD email
MYSQL_HOME_FIELD homedir
MYSQL_MAILDIR_FIELD maildir
MYSQL_QUOTA_FIELD quota

Testing The Installation

You should now have a fully functioning virtual mail server. We will now test the installation with some test accounts. The first step will be to add some test domain names into the /etc/hosts file to allow us to test the sending of email to virtual domains.

$ vi /etc/hosts

domain1.com			100.0.0.1	(enter your ip address here)
domain2.com			100.0.0.1	(enter your ip address here)

Next we need to add some real unix users so that we can test the sending of email to local accounts (i.e. non virtual accounts).

$ vi /etc/passwd
user1:x:1013:1013::/home/user1:/bin/bash
user2:x:1014:1014::/home/user2:/bin/bash

$ vi /etc/group
user1:x:1013:
user2:x:1014:

We now need to populate our MySQL database with some test data

INSERT INTO postfix_alias VALUES (1,'root','user1');

INSERT INTO postfix_smtp VALUES (1,'user1@domain1.com','user1');
INSERT INTO postfix_smtp VALUES (2,'user2@domain2.com','user2');

INSERT INTO postfix_transport VALUES (1,'localdomain.co.uk','local:');
INSERT INTO postfix_transport VALUES (2,'domain1.com','virtual:');
INSERT INTO postfix_transport VALUES (3,'domain2.com','virtual:');

INSERT INTO postfix_users VALUES (1,'vuser@domain1.com','vuser', \
	1008 (vmail_uid),1013 (main_user_gid),'/home/vmail','domain1.com/vuser/','','Y','Y');
INSERT INTO postfix_users VALUES (2,'vuser@domain2.com','vuser', \
	1008 (vmail_uid),1014 (main_user_gid),'/home/vmail','domain2.com/vuser/\r\n','','Y','Y');

INSERT INTO postfix_virtual VALUES (1,'@domain1.com','user1');
INSERT INTO postfix_virtual VALUES (2,'user1@domain1.com','user1');
INSERT INTO postfix_virtual VALUES (3,'vuser@domain1.com','vuser@domain1.com');
INSERT INTO postfix_virtual VALUES (4,'forwarding@domain1.com','you@hotmail.com');
INSERT INTO postfix_virtual VALUES (1,'@domain2.com','user2');
INSERT INTO postfix_virtual VALUES (2,'user1@domain2.com','user2');
INSERT INTO postfix_virtual VALUES (3,'vuser@domain2.com','vuser@domain2.com');
INSERT INTO postfix_virtual VALUES (4,'forwarding@domain2.com','you@hotmail.com');

You will now need to start all the programs that have just been installed.

$ /etc/init.d/mysql start
$ /etc/init.d/postfix start
$ /etc/init.d/impad start
$ /etc/init.d/pop3d start

Send an email to vuser@domain1.com by performing the following.

$ smtp localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 localdomain.co.uk ESMTP Postfix
mail from: user1@domain1.com
250 Ok
rcpt to: user1@domain2.com
250 Ok
data
354 End data with .
Hello user1 at domain2 this is user1 at domain1
.
250 Ok: queued as 9F0861531F

This should have sent an email to virtual user user1@domain2.com. This can be confirmed by looking in the /home/vmail/domain2/user1/new/ directory. If an email is present then it would appear that everything is working. WELL DONE!

Knowledgebase

 
Get online now with your choice of UK or International domain name.

 UK domains £3.25 p/a
 International domains £10 p/a
 Web forwarding services
 E-mail forwarding services
 POP/IMAP E-Mail accounts NEW
 Spam E-Mail Protection NEW
 DNS Configuration NEW
 Change nameservers
 Upgrade to web hosting
 No release fees

The domain control panel (DCP) is provided as standard with all parked domain accounts.

 Map multiple domains to your web hosting account for the one time fee of £29.99 per domain!

 Additional bandwidth usage on your web hosting account now only 2p per MB per month!

 HTML only web hosting accounts now start from just £29.99 p/a!

 Add Frontpage Extensions to your HTML only web hosting account for the one time fee of £14.99.

 Transfer your .co.uk domain name to Webconexion for FREE with the option to upgrade to one of our web hosting accounts!

Latest News | Related News | Contact Us | Terms & Conditions | Knowledgebase | Related Resources | System Status | Add Resource
Copyright © 2010 - Webconexion Internet Solutions LTD