Home arrow Configure arrow Mail Server with Postfix
Setup a mail server using Postfix, Mysql, SSL and Courier-IMAP PDF
Saturday, 25 March 2006

This page is for installing postfix with ssl support with virtual users and domains (using mysql) and Courier-IMAP.

The following configuration was installed and tested on FreeBSD-5.4.

 

1) Installing and creating MySQL databases

The following packages need no compilation, so you can use pkg_add.

#pkg_add ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-5.4-release/All/mysql_client-4.0.24.tbz

#pkg_add ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-5.4-release/All/mysql_server-4.0.24.tbz

If you want your mysql logs placed someware you can modify in /usr/local/etc/rc.d/mysql.sh the line for command_args and add --log=/your/directory/mysql.log.

First thing, change your root password:

#mysqladmin -u root --password='your_password_here'

The following commands you should type at mysql prompt.

Create a database for virtual users and domains:

mysql>create database maildb;

Then you should create a mysql user that will be used by postfix and Courier-IMAP to interogate the database maildb.
In this case, we will name it mailadmin and the password will be mailpass.

 mysql>grant all privileges on *.* to "mailadmin"@"localhost" identified by "mailpass" with grant option;

mysql>grant reload, process on *.* to "mailadmin"@"localhost";


Creating tables:

#---------transport table (used for virtual domains)--------------------

CREATE TABLE transport (
id int(3) NOT NULL auto_increment,
domain varchar(128) NOT NULL default "",
transport varchar(128) NOT NULL default "",
PRIMARY KEY (id)
);

Insert a domain into the database:

mysql> INSERT INTO transport values("","mail.freebsdonline.com", "virtual");

#---------mailusers table (used for virtual users)--------------------

CREATE TABLE mailusers (
id int(5) NOT NULL auto_increment,
address varchar(128) NOT NULL default "",
pass varchar(128) NOT NULL default "",
name varchar(128) NOT NULL default "",
uid smallint(5) unsigned default "125",
gid smallint(5) unsigned default "125",
home varchar(128) default "/var/home/mail",
domain varchar(128) default "",
maildir varchar(255) NOT NULL default "",
quota int(11) default "200000",
active tinyint(1) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY id (id),
UNIQUE KEY address (address)
);

Insert a user:
mysql> INSERT INTO mailusers values(""," This e-mail address is being protected from spam bots, you need JavaScript enabled to view it ", "password", "any name", "125",\
 "125", "/var/home/mail", "mail.freebsdonline.com","mail.freebsdonline.com/user/Maildir", "","1");

Fields explained:
- address should be in form: "user@domain" (Ex: This e-mail address is being protected from spam bots, you need JavaScript enabled to view it )
- pass - is the password (crypted or plan, you will set this later)
- uid and gid - theese should be the system user and group id for postfix (usually 125).
- home - is where all your mails will be kept.
- maildir - here you should specify the Maildir used for this account (you can use something like: domain/username/Maildir).
Note that you should use the Maildir format because Courier-IMAP supports only this format!
- active - you can use this field (or not) to be able to disable users

#---------alias table (used for users aliases)--------------------

CREATE TABLE alias (
address varchar(255) NOT NULL default "",
goto text NOT NULL,
domain varchar(255) NOT NULL default "",
created datetime NOT NULL default "0000-00-00 00:00:00",
modified datetime NOT NULL default "0000-00-00 00:00:00",
active tinyint(1) NOT NULL default "1",
PRIMARY KEY (address));

The system needs some users in the mail system to send them notifications, so you might consider to add the following users: root, postmaster and operator, and eventually you may make an alias for these users to wherever you want the mails to come.

mysql>insert into mailusers values ("", "root", "12345", "root", 125, 125, "/root", "mail.freebsdonline.com", "Maildir/", 0, 1);
mysql>insert into mailusers values ("", "postmaster", "12345", "root", 125, 125, "/root", "mail.freebsdonline.com", "Maildir/", 0, 1);
mysql>insert into mailusers values ("", "operator", "12345", "root", 125, 125, "/root", "mail.freebsdonline.com", "Maildir/", 0, 1);

mysql>insert into alias values ("postmaster"," This e-mail address is being protected from spam bots, you need JavaScript enabled to view it ","","","",1);
mysql>insert into alias values ("root"," This e-mail address is being protected from spam bots, you need JavaScript enabled to view it ","","","",1);
mysql>insert into alias values ("operator"," This e-mail address is being protected from spam bots, you need JavaScript enabled to view it ","","","",1);


2) Installing Cyrus-sasl

Compile cyrus-sasl.2.1.20_1 with support for mysql:

# cd /usr/ports/security/cyrus-sasl2
# make install WITH_MYSQL_VER=51   # change this to your mysql version 

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

#-----------------------------smtpd.conf--------------------------
pwcheck_method: auxprop
auxprop_plugin: sql
sql_engine: mysql
mech_list: plain login
msql_hostnames: localhost
sql_user: mailadmin
sql_passwd: mailpass
sql_database: maildb
sql_select: SELECT pass FROM mailusers WHERE address = '%u@%r'
sql_verbose: yes


3) Installing and configuring Postfix

Compile Postfix-2.2,1 for mysql and SASL2.
Modify Postfix files:

#------------------------------main.cf---------------------------------

soft_bounce = no
queue_directory = /var/spool/postfix
command_directory = /usr/local/sbin
daemon_directory = /usr/local/libexec/postfix
mail_owner = postfix
default_privs = nobody

myhostname = mail.freebsdonline.com
inet_interfaces = all
unknown_local_recipient_reject_code = 550
mynetworks = 127.0.0.0/8
mail_spool_directory = /var/home/mail
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/local/sbin/sendmail
html_directory = no
manpage_directory = /usr/local/man
sample_directory = /usr/local/etc/postfix
setgid_group = maildrop
readme_directory = no
alias_database = mysql:/usr/local/etc/postfix/mysql/virtual_alias_maps.cf
alias_maps = mysql:/usr/local/etc/postfix/mysql/virtual_alias_maps.cf
virtual_mailbox_limit = 0
mailbox_size_limit=0
message_size_limit = 102400000

#sasl
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_application_name=smtpd
smtpd_sasl_security_options = noanonymous
smtpd_helo_required = yes
smtpd_recipient_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_invalid_hostname,
reject_non_fqdn_hostname,
reject_non_fqdn_sender,
reject_non_fqdn_recipient,
reject_unknown_sender_domain,
reject_unknown_recipient_domain,
reject_unauth_destination,
permit

#virtual
virtual_uid_maps = static:125
virtual_gid_maps = static:125
virtual_transport = virtual
virtual_alias_maps = mysql:/usr/local/etc/postfix/mysql/virtual_alias_maps.cf
transport_maps=mysql:/usr/local/etc/postfix/mysql/transport.cf
virtual_mailbox_base=/var/home/mail
virtual_mailbox_maps=mysql:/usr/local/etc/postfix/mysql/users.cf
mydestination = $mydomain, $myhostname, $transport_maps

#set local recipient maps
local_recipient_maps = $virtual_mailbox_maps
smtpd_sender_login_maps=mysql:/usr/local/etc/postfix/mysql/sender_check.cf
smtpd_sender_restrictions=reject_sender_login_mismatch, permit_sasl_authenticated


Leave master.cf file default.
Create the directory /var/spool/postfix and chown it to root:
mkdir /var/spool/postfix
chown root /var/spool/postfix

Create a directory named mysql owned by root in /usr/local/etc/postfix and put the following files and content in it:

#-----------------------------sender-check.cf---------------------------------
user=mailadmin
password=mailpass
dbname=maildb
hosts=localhost
query = SELECT address FROM mailusers WHERE address='%s' and active=1

#-----------------------------transport.cf---------------------------------
user=mailadmin
password=mailpass
dbname=maildb
hosts=localhost
query = SELECT transport FROM transport WHERE domain='%s'

#-----------------------------users.cf---------------------------------
user=mailadmin
password=mailpass
dbname=maildb
hosts=localhost
query = SELECT maildir FROM mailusers WHERE address='%s'

#-----------------------------virtual_alias_maps.cf---------------------------------
user=mailadmin
password=mailpass
dbname=maildb
hosts=localhost
query = SELECT goto FROM alias WHERE address='%s' and active=1

#-----------------------------virtual_domains_maps.cf---------------------------------
user=mailadmin
password=mailpass
dbname=maildb
hosts=localhost
query = SELECT domain FROM mailusers WHERE domain='%s'

Change mod to 640 for all files in mysql directory

#cd /usr/local/etc/postfix/mysql
#chmod 640 *


4) Installing Courier-IMAP and Courier-authlib

Compile courier-imap-4.0.2,1 with support for openssl and courier-authlib-0.55_1 with support for mysql.

Configure courier-authlib (the authentication daemon for courier-imap):
Go to /usr/local/etc/authlib and modify authdaemonrc.dist into authdaemonrc
Make sure that in authmodulelist authmysql is listed.
Modify authmysqlrc.dist into authmysqlrc and place the following content:

#--------------------authmysqlrc-----------------------------
MYSQL_SERVER localhost
MYSQL_USERNAME mailadmin
MYSQL_PASSWORD mailpass
MYSQL_PORT 3306
MYSQL_OPT 0
MYSQL_DATABASE maildb
MYSQL_USER_TABLE mailusers
#MYSQL_CRYPT_PWFIELD crypt #use this instead of the following in case you prefer to use crypted passwords
MYSQL_CLEAR_PWFIELD clear
MYSQL_UID_FIELD '125'
MYSQL_GID_FIELD '125'
MYSQL_LOGIN_FIELD address
MYSQL_HOME_FIELD '/var/home'
MYSQL_NAME_FIELD name
MYSQL_MAILDIR_FIELD CONCAT("/var/home/mail/",maildir) # in this particular case, you need this to get the full path to the maildir

Note: Make sure not to add spaces in authmysqlrc, only tabs are allowed, and use only single quotes!

Configure courier-imap
Rename the files: imapd-dist, imapd-ssl-dist, pop3d-dist, pop3d-ssl-dist into imapd, imapd-ssl, pop3, pop3-ssl
(choose which daemons you want to run). The ones that you want to start, modify the line that contains the "START" word
from NO to YES ( for example in imapd modify IMAPDSTART=NO to IMAPDSTART=YES).

Last Updated ( Monday, 16 April 2007 )
 

Other BSD Systems

OpenBSD

Misc

Solaris

Polls

Best BSD firewall?