Abstract:

This is a brief memo, intented to help out in building a mail system comprised
of postfix as MTA, Courier-IMAP/POP3 and various other useful stuff like SASL2
user authentication, pop-before-smtp (whichever one chooses);
Amavisd-new/Spamassasing antivirus and spamchecking system; and finally MySQL
as a backend. In some places this little document is following almost by heart
the instructions found in different places the net, and especially the excellent
http://high5.net/howto


Installation of Postfix

The entire setup is performed on an (almost) fresh install Redhat Linux 7.3.
The Postfix version, used in this example is 2.0.13, and the appropriate
SSL/TLS patch version is 0.8.15-2.0.13-0.9.7b. Before initiating the postfix
installation itself, it is necessary to install several of the other
programmes, i.e. MySQL - I used the version shipped with RH 7.3, and the latest
BerkeleyDB from here:
http://www.sleepycat.com/download/index.shtml
Here I wont describe the compillation and setup of the above.
Go get the latest postfix source from one of the mirrors around the world:
http://www.postfix.org/download/
and the Postfix TLS patch:

ftp://ftp.aet.tu-cottbus.de/pub/postfix_tls/pfixtls-0.8.15-2.0.13-0.9.7b.tar.gz

 tar zxf postfix-2.0.13.tar.gz
 tar zxf pfixtls-0.8.15-2.0.13-0.9.7b.tar.gz
 cd /usr/src/postfix-2.0.13
 patch -p1 < <path to you pfix-tls patch>make makefiles 'CCARGS=-I/usr/include/mysql -DHAS_MYSQL   
        -I/usr/local/include/sasl -DUSE_SASL_AUTH   
        -I/usr/local/BerkeleyDB.4.1/include -DHAS_DB   
        -I/usr/include/openssl -DUSE_SSL'   
        'AUXLIBS=-L/usr/lib/mysql/ -lmysqlclient   
        -lssl -lcrypto -lz -lm   
        -L/usr/local/lib/sasl2 -lsasl2   
        -L/usr/local/BerkeleyDB.4.1/lib -ldb'
 groupadd postdrop
 groupadd postfix
 useradd -g postfix postfix
 make && make install


Configuration

Information on TLS setup is described here:
http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/


Create the database

Create a Postfix user and the Postfix database.
Use mysql or mysql -p to login to the MySQL Monitor.

 USE mysql;
 INSERT INTO user (Host, User, Password) VALUES
 ('localhost','postfix',password('postfix123'));INSERT INTO db (Host, Db, User,
 Select_priv) VALUES ('localhost','postfix','postfix','Y');CREATE DATABASE
 postfix;


Create the Tables

In order to use MySQL with Postfix we need to create 3 tables. All of
these tables have information for Postfix, and some for Courier-IMAP as
noted by each table. There are a couple of columns that are not used by
neither Postfix or Courier-IMAP. These columns are:

  • domain (in some tables)
  • create_date
  • change_date
  • active

These columns are used to make your life easier together with Postfix
Admin. The “active” column is not used at the moment.


Create the Alias Table

 #
 # Table structure for table alias
 #
 USE postfix;
 CREATE TABLE alias (
   address varchar(255) NOT NULL default '',
   goto text NOT NULL,
   domain varchar(255) NOT NULL default '',
   create_date datetime NOT NULL default '0000-00-00 00:00:00',
   change_date datetime NOT NULL default '0000-00-00 00:00:00',
   active tinyint(4) NOT NULL default '1',
   PRIMARY KEY (address)
 ) TYPE=MyISAM COMMENT='Virtual Aliases - mysql_virtual_alias_maps';

Postfix is using the “address” and “goto” column.
Courier is not using this table.
NOTE: This table can be used for virtual .foward files. This table is nothing
more than /etc/aliases that you will find on any *nix-like OS.
Multiple destination email addresses need to be separated by a “,” (comma).


Create the Domain Table

 #
 # Table structure for table domain
 #
 USE postfix;
 CREATE TABLE domain (
   domain varchar(255) NOT NULL default '',
   description varchar(255) NOT NULL default '',
   create_date datetime NOT NULL default '0000-00-00 00:00:00',
   change_date datetime NOT NULL default '0000-00-00 00:00:00',
   active tinyint(4) NOT NULL default '1',
   PRIMARY KEY (domain)
 ) TYPE=MyISAM COMMENT='Virtual Domains - mysql_virtual_domains_maps';

Postfix is using the “domain” and “description” column.
Courier is not using this table.


Create the Mailbox Table

 #
 # Table structure for table mailbox
 #
 USE postfix;
 CREATE TABLE mailbox (
   username varchar(255) NOT NULL default '',
   password varchar(255) NOT NULL default '',
   name varchar(255) NOT NULL default '',
   maildir varchar(255) NOT NULL default '',
   domain varchar(255) NOT NULL default '',
   create_date datetime NOT NULL default '0000-00-00 00:00:00',
   change_date datetime NOT NULL default '0000-00-00 00:00:00',
   active tinyint(4) NOT NULL default '1',
   PRIMARY KEY (username)
 ) TYPE=MyISAM COMMENT='Virtual Mailboxes - mysql_virtual_mailbox_maps';

Postfix: is using the “username” and “maildir” column.
Courier: is using the “username, “password”, “name” and “maildir” column.


Populate the Tables

 USE postfix;
 INSERT INTO domain (domain,description) VALUES ('domain.tld','Test Domain');
 INSERT INTO alias (address,goto) VALUES ('alias@domain.tld','user@domain.tld');
 INSERT INTO mailbox (username,password,name,maildir) VALUES
 ('user@domain.tld','$1$DOrHOomo$U6MleaFKGwWLB3iS9P1Yx0','Mailbox
 User','user@domain.tld/');

The first INSERT is to let Postfix know that this domain is a virtual
domainand should be handled by Postfix. It’s also possible to have everything in
one table but probably this way it’s nicer.
The second INSERT is a virtual alias pointing to the third INSERT.
The third INSERT is the actual virtual mailbox, as you can see here
it’s used MD5 password for backward compatibility with local defined mail
accounts. If you are using MD5 passwords, make sure you don’t use the builtin
MySQL routine to generate MD5 passwords. This is not compatible with
Courier-IMAP. If you want you can also use cleartext or encrypted passwords.
To make sure that the new MySQL users are working, do the following
from the command line:

 $ mysqladmin reload


Postfix Install

You have to create a directory to have all your virtual users mail dropped in,
this directory needs to be owned by Postfix.


Postfix Setup


main.cf

The below example is the part that goes into your main.cf file of Postfix. The
path to the mysql files might be different on your setup. The same might be for
uid_maps, gid_maps and minimum_uid values. These
values should be the ones from the postfix user and group. You can find these
in your /etc/passwd file.

 virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
 virtual_gid_maps = static:12345
 virtual_mailbox_base = /virtual
 virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
 virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
 virtual_mailbox_limit = 51200000
 virtual_minimum_uid = 12345
 virtual_transport = virtual
 virtual_uid_maps = static:12345

 $ mkdir /virtual
 $ chown -R postfix:postfix /virtual
 $ chmod -R 751 /virtual


mysql_virtual_alias_maps.cf

You will need to put this into a text file for postfix to pickup.

 user = postfix
 password = postfix123
 hosts = localhost
 dbname = postfix
 table = alias
 select_field = goto
 where_field = address


mysql_virtual_domains_maps.cf

You will need to put this into a text file for postfix to pickup.

 user = postfix
 password = postfix123
 hosts = localhost
 dbname = postfix
 table = domain
 select_field = description
 where_field = domain


mysql_virtual_mailbox_maps.cf

You will need to put this into a text file for postfix to pickup.

 user = postfix
 password = postfix123
 hosts = localhost
 dbname = postfix
 table = mailbox
 select_field = maildir
 where_field = username


Postfix Admin

Here you can find information on the excellent tool PostfixAdmin that Mischa
Peters has written in PHP. It’s in production at least 2 sites that he maintains,
and at a couple of sites tham I’m administering. If you want to install this
make sure that you have a running webserver that handles PHP correctly and is
able to handle .htaccess fiels. Here you wont find any instrucions on your
webserver/PHP install.
Postfix Admin is a way to give virtual domain owners total control over
their domains.


Postfix Admin Download

You can get PostfixAdmin here:
http://high5.net/postfixadmin/


Postfix Admin Install

Unpack Postfix Admin in the directory where you want it. For example:
/var/www/html/<site>/pfadmin. There is also an Admin Admin part, change
directory to the “admin” directory and sue some authentication or other
means for controlling access to this dir.
Some other information that you might want to look at is in the
site_lib.php file.
In order to be able to read and write from the database I have created a
seperate user in MySQL. I do this because Postfix Admin needs to have
more rights on the Postfix database. If you are worried about the
password for the database. I have Postfix Admin running as the
WebServer owner

:group, that way your postfix username and password are
somewhat protected against local users.

 USE mysql
 INSERT INTO user (Host, User, Password) VALUES
 ('localhost','postfixadmin',password('postfixadmin123'));INSERT INTO db (Host,
 Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv) VALUES
 ('localhost', 'postfix', 'postfixadmin', 'Y', 'Y', 'Y', 'Y');

Make sure you reload MySQL.

 $ mysqladmin reload


Postfix Admin Setup

In order to use Postfix Admin you have to add another table to the
Postfix database.

 #
 # Table structure for table admin
 #
 USE postfix;
 CREATE TABLE admin (
   username varchar(255) NOT NULL default '',
   password varchar(255) NOT NULL default '',
   domain varchar(255) NOT NULL default '',
   create_date datetime NOT NULL default '0000-00-00 00:00:00',
   change_date datetime NOT NULL default '0000-00-00 00:00:00',
   active tinyint(4) NOT NULL default '1',
   PRIMARY KEY (username)
 ) TYPE=MyISAM COMMENT='Virtual Admins - Store Virtual Domain Admins';


Postfix Admin Usage

Once you have done all this you can take your browser and browse to the
location where you have Postfix Admin installed. Goto the admin part first in
order to put some real domains that you host in the database. This will be
http://your.domain.tld/postfixadmin/admin. The default login is admin
/ admin.


Cyrus SASL2 install and config

For user authentication one can choose between several methods, of which SASL
is probably the best regarding security. From users’ perspective, though,
pop-before-smtp is easier to work with.


SASL2

http://asg.web.cmu.edu/cyrus/download/
There are two ways for using SASL2 authentication - one is through PAM, which is
fairly easy to setup, though probably not so scalable, and the other is
directly through auxprop.

 ./configure  --with-bdb-libdir=/usr/local/BerkeleyDB.4.1/lib   
--with-bdb-incdir=/usr/local/BerkeleyDB.4.1/include --with-openssl   
--enable-login --with-ldap --with-mysqlmake

SASL2 auth through PAM/MySQL

http://pam-mysql.sourceforge.net/

 /etc/pam.d/smtp
 auth required pam_mysql.so user=postfix passwd=postfix123 db=postfix
 table=mailbox usercolumn=username passwdcolumn=password crypt=1
 account required pam_mysql.so user=postfix passwd=postfix123 db=postfix
 table=mailbox usercolumn=username passwdcolumn=password crypt=1

You HAVE to use the full email address as username, or else auth will fail. In
the given setup, though, you can use the name itself by selecting
usercolumn=name.
NB: This works, but is NOT fully tested.

SASL2 through auxprop

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

 mech_list: plain login
 pwcheck_method: auxprop
 auxprop_plugin: mysql
 mysql_user: postfix
 mysql_passwd: postfix123
 mysql_hostnames: junip3r.mnet.bg
 mysql_database: postfix
 mysql_statement: "SELECT %p FROM mailbox WHERE username = '%u' and domain =
 '%r'"#mysql_verbose: yes

Note that in main.cf of postfix’s configuration we are setting
“smtpd_sasl_local_domain = <NULL>”, i.e. empty value. For this reason we have
to select on ‘name’ and not on ‘username’.
NB: If you change any of the mechs or the contents of smtpd.conf, make sure to
do a ‘postfix reload’, because there’s some kind of caching, obviously.
Finally: NOT WORKING! Auxprop doesnt want to send the correct realm,
i.e. domain. Have to investigate further.


POP-before-SMTP

Here you can use ONE OF:

POP before SMTP

The setup of POP-before-SMTP is fairly
easy, compared at least with the other software described here. Following the instructions on the web page I was able to set it up in a matter of 2 minutes. You just have to uncoment the line:

 $file_tail{'name'} = '/var/log/maillog';

and add this line, in order our setup to work with courier 2.0.0:

 $pat = '^(... .. ..:..:..) \S  (?:imapd-ssl|pop3d-ssl|imapd|pop3d):
 LOGIN, user=\S , ip=\[\:\:ffff\:(\d \.\d \.\d \.\d )\].*';

then you can change the grace period if you like. Default is 30 minutes, which
is fairly long, IMHO.

 $grace = 30*60;

DRAC

http://mail.cc.umanitoba.ca/drac/

WHOSON

http://whoson.sourceforge.net/
As a matter of simplicity probably popbsmtp is the best, since it is a
single daemonized perl script watching the mail logs, and DRAC needs
that the POP daemon used has to be recompiled. DRAC and WHOSON are not
tested in this setup.


Courier-IMAP install and config

Do a

 tar jxf courier-imap-2.0.0.tar.bz2 -C /home/nikky/src
 ./configure --sysconfdir=/etc/courier
 will do the job. Then
 $ make && make check
 $ su root
 # make install


authmysqlrc

NOTE: Make sure that there are no (trailing) spaces in this file, only
tabs!!
Below is part of the authmysqlrc file that is relevant to our setup.
The things that you might need to change are the mysql_password,
mysql_uid and mysql_gid.

 MYSQL_CRYPT_PWFIELD        password
 MYSQL_DATABASE         postfix
 MYSQL_OPT          0
 MYSQL_SERVER           junip3r.mnet.bg
 MYSQL_USERNAME         postfix
 MYSQL_USER_TABLE       mailbox
 MYSQL_PASSWORD         postfix123
 MYSQL_UID_FIELD            '12345'
 MYSQL_GID_FIELD            '12345'
 MYSQL_HOME_FIELD       '/virtual'
 MYSQL_LOGIN_FIELD      username
 MYSQL_MAILDIR_FIELD        maildir
 MYSQL_NAME_FIELD       name

Read the hints if you have trouble logging in:
Make sure that there are NO spaces in the authmysqlrc file, only tabs. Make
sure that there are only single quotes ' around static values like
'/virtual', 'UID', 'GID'. NO single quotes around
localhost! Make sure that localhost exists in your /etc/hosts file.
Including IPv6 during the compilation could cause a problem. The
MYSQL_GID_FIELD and MYSQL_UID_FIELD are for the
UIDand GID of the postfix user and group, NOT for the MySQL
user andgroup.


Amavisd/Spamassassin/F-Prot install and config

amavisd-new is a high-performance interface between message transfer agent
(MTA) and one or more content checkers: virus scanners, and/or SpamAssasin.
http://www.ijs.si/software/amavisd/
Specific information on installing Amavisd-new on Redhat can be found
here:
http://www.rmorales.com.ar/rpms/amavis/

 perl -MCPAN -e shell is your friend!

In this example we are using the home version of F-Prot, which is a
non-daemonised command line virus scanner, used for checking files and
triggering the necessary alerts. You can download it from here: http://www.f-prot.com/download/download_fplinux_personal.html
The installation of the three flavours (RPM,DEB and TGZ) is fairly
straight-forward and does not need any instructions.


Links

http://small.dropbear.id.au/myscripts/postfixmysql.html