Tuesday, February 08, 2005

Setting up Postfix (TLS) / Courier-IMAP (SSL) / MySQL / Postfixadmin

This is an install guide for setting up a secure mail server using Postfix, Courier-IMAP, MySQL, and Postfixadmin on Debian Woody.

Before we begin here are a few notes regarding how things are handled:
  • Virtual domains - All domains including the local domain are handled as virtual domains. This allows a central location for all mail.
  • All interactions with the server are authenticated and encrypted using libsasl2 and TLS/SSL (Please see the packages section for what to install)
1. Packages to Install

This install guide assumes the following packages are already installed:
  • mysql-client
  • mysql-server
  • openssl (to create the certificate)
  • apache
To add Postfix add the following line to your /etc/apt/sources.list

deb http://www.backports.org/test/postfix/ ./

Install the following packages:
  • Postfix 2.1.4-4
  • Postfix-mysql 2.1.4-4
  • Postfix-pcre 2.1.4-4
  • Postfix-tls 2.1.4-4
  • libsasl2 (the Cyrus SASL library)
  • libsasl2-modules
  • libsasl2-modules-sql
Note: Make sure you use the source above to install the packages. DON'T use the stable version of backports to install Postfix and libsasl. The stable version of Postfix is linked against libsasl1 which does not allow authentication via the libsasl2 sql module.

Comment out the previous package line and add the following line in your sources.list file:

deb http://www.backports.org/debian stable courier

Install the following packages:
  • courier-authdaemon 0.47-2
  • courier-authmysql 0.47.2
  • courier-base 0.47.2
  • courier-imap 3.0.8-2
  • courier-imap-ssl 3.0.8-2
Finally unpack the latest version of Postfixadmin (2.1.0 as of this writing) into your web directory.

2. Create the Tables in MySQL

Go to the postfixadmin directory that you unpacked and run the DATABASE_MYSQL.TXT in MySQL to setup the complete table structure for Postfix.

It should create the following 7 tables under a database called 'postfix':
  • admin
  • alias
  • domain
  • domain_admins
  • log
  • mailbox
  • vacation
3. Create a Mail Directory

Create a directory to have all your virtual users mail dropped in, this directory needs
to be owned by Postfix.
% mkdir /usr/local/virtual

% chown -R postfix:postfix /usr/local/virtual
% chmod -R 771 /usr/local/virtual
4. Postfix Configuration

Use the following /etc/postfix/main.cf file. The items in <> are values you need to change.

myhostname= <your.hostname>
mydomain= <your.domain>
mydestination =
myorigin = /etc/mailname

virtual_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_alias_maps = $virtual_maps
virtual_gid_maps = static:<postfix group id from /etc/passwd>
virtual_mailbox_base = </your/mailbox/path>
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = <postfix user id from /etc/passwd>
virtual_transport = virtual
virtual_uid_maps = static:<postfix user id from /etc/passwd>

# SMTP Authentication
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_security_options = noanonymous
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reje
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/postfix/smtpd.cert
smtpd_tls_key_file = /etc/postfix/smtpd.key
append_dot_mydomain = no

Notes: Leave mydestination blank if you want your local domain to be considered virtual. If you list your local domain in mydestination, as is commonly the case, you need to have a system user for every email user. Postfix will look for a system user corresponding to the email user and if none is found it will bounce the mail. It will also not deliver to the mailbox path.

Create the following files in /etc/postfix:


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


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


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

Now go to /etc/postfix/master.cf and change first smtp line to the following:

smtp inet n - n - - smtpd

This prevents postfix from running in a chrooted jail.

5. Postfix, Authenticated SMTP and TLS encryption

By default postfix only allows communication between users defined in mynetworks. This prevents an open relay that spammers can abuse to send out spam. This however, also prevents users of your domain to send out email to domains outside your box. So you have to authenticate your users with a username and password to allow them to be part of your circle of trust. Most email cilents such as Thunderbird have this feature included.

Use the following from Christoph Haas's tutorial located in http://workaround.org/articles/ispmail-sarge/ to setup authentication:

As written earlier Postfix uses the Cyrus SASL library for authenticated SMTP. So you need to tell Postfix how to access the data storage that keeps the usernames and passwords. This is easy. Create a directory /etc/postfix/sasl to put the SASL config file there:
mkdir /etc/postfix/sasl

Now you need to create a file smtpd.conf in that directory like this:

pwcheck_method: auxprop

auxprop_plugin: sql
allowanonymouslogin: no
mech_list: plain login cram-md5 digest-md5
sql_engine: mysql
sql_hostnames: localhost
sql_user: postfix
sql_database: postfix
sql_select: select password from mailbox where username='%u@%r'

(If you have trouble with SASL you may consider inserting a line like "log_level: 7" here. It will write more verbose information to the log files and perhaps help to find the cause.)

An important step is to encrypt the SMTP session. Otherwise the username and password could be transmitted in a very insecure way if the mail client chose to use one of plaintext authentication methods). So I encourage you to encrypt that communication using TLS. TLS is short for Transport Layer Security (RFC2246) and in short terms uses SSL (Secure Socket Layer) which encrypts the mail connection between the road-warrior and the mail server.

First you will need an SSL certificate. If you don't want to pay for one from your favorite trustcenter you can well use a self-signed one. (Personal note: I wonder how paying for something makes it more trusted.) The only drawback: the mail client does not know about your CA (certificate authority) and will spit out a warning to the user. Either tell the users to ignore the warning or let them install the certificate on their computers.

For a certificate that is valid for one year for the hostname smtp.domain.tld you would type this:

openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 365 -x509

You will then be asked a few question about the fields of the certificate. It does not matter what you enter. Just fill the fields. One exception though - the "Common Name" must be the hostname of your mail server. Example session:

Country Name (2 letter code) [AU]:DE

State or Province Name (full name) [Some-State]:Hamburg
Locality Name (eg, city) []:Hamburg
Organization Name (eg, company) [Internet Widgits Pty Ltd]:workaround.org email services
Organizational Unit Name (eg, section) []:Master of Disaster
Common Name (eg, YOUR name) []:smtp.domain.tld
Email Address []:postmaster@domain.tld

After a short moment you will get two files: "smtpd.key" (the private key file) and "smtpd.cert" (the certificate). Move these two files into /etc/postfix.

Make sure at least the key file is not readable for the whole wide world:
chmod o= /etc/postfix/smtpd.key

6. Configuring Courier-IMAP-SSL

Edit /etc/courier/authdaemonrc and change authmodulelist to "authmysql" like this:

Add or Change /etc/courier/authmysqlrc to contain the following:

MYSQL_SERVER            localhost


#MYSQL_CRYPT_PWFIELD password #Comment this out
MYSQL_HOME_FIELD '/location/to/mail/dir'
Notes: Make sure you have no spaces only tabs. Enclose user id and gid in single quotes.

7. Final Comments

By default libsasl2 only supports clear text passwords so make sure the user passwords in the mysql database are readable. Since our connections are encrypted using TLS/SSL this is not much of an issue. Make sure Postfixadmin is set for clear text passwords. Your config.inc.php in your Postfixadmin directory should have the following:

$CONF['encrypt'] = 'cleartext';

8. Helpful Links and Howto's

Much of the information for this guide was gathered from the following links:


Integrating Apache 2.0.x and Tomcat 5.0.x with mod_jk on Mandrake Linux 10

(Roger Kepler)

When it comes to Linux, nothing comes easy for me, but I get it done. Tonight I tried to install the connector between Apache and Tomcat. Ken Cochrane wrote on his blog page basic instructions for that, and he even e-mailed me the required mod_jk.so file. Unfortunately, Mandrake 10 didn't like it and I had to manually build it frmo the source. What a pain, but the instruction below helped quite a bit, I just had to install "autoconf" to get it to work. Mandrake asked for the installation CD to be inserted. I already had the other components (gcc).

Then another late night saga began. It's all in the details. The generic instructions didn't work for me, as usual. So, below you'll see my comments and the little I had to modify to get this to work. FYI, it took me again 4 hours to get this thing going. There are dozens of different configurations available out there, the trick is to find one that works. Finding the problem was also hard, but now it looks so trivial when one knows what is wrong.

Moral of the story: no pain, no gain.

Integrating Apache 2.0.x and Tomcat 5.0.x with mod_jk on Linux
(Using FlashGuide as a base.)

This FlashGuideTM covers integrating Apache 2.0.x and Tomcat 5.0.x on Unix via mod_jk. These instructions have been tested on SuSE 9.0, Red Hat 6.2 and Fedora Core 2. There are two ways to integrate Apache and Tomcat: mod_jk and mod_jk2. Mod_jk is the older but more stable version, which supports load balancing and non-standard web application locations. Mod_jk2 is newer, has bugs, and, as of 11/15/04, is no longer being actively developed.

These instructions are for the current version of Tomcat 5.0.28, but have worked the same for all previous versions of Tomcat.

1. Building Apache 2.0.x on Linux

Unless you can find a binary distribution of Apache with DSO support enabled, you will have to follow these instructions to build it yourself.

1. Check your prerequisites:

1. You will need GCC installed
2. You will need /usr/ccs/bin and the gcc executables in your $PATH

2. Download the latest Apache source from http://httpd.apache.org/download.cgi - currently, the latest is 2.0.52.
3. Unpack the distribution into a development directory (I used /usr/local)

The distribution directory will be something like apache_2.0.52
4. Cd into the distribution directory (e.g. /usr/local/apache_2.0.52)
5. Configure the makefile:

./configure --with-layout=Apache --prefix=/usr/local/apache2 --enable-module=most --enable-mods-shared=most

If you have to run this configuration again, note that configure saves the latest configure command in config.status
6. Build Apache:


7. Install Apache:

make install

8. Note the location of your Apache installation - we will refer to this as $APACHE2_HOME

2. Installing Tomcat 5 on Linux

1. Download the latest Tomcat binary from the Tomcat 5 section of http://jakarta.apache.org/site/binindex.cgi. Currently, Tomcat 5.0.28 is the latest.
2. Install Tomcat by unzipping/untaring the download file and placing in the desired directory (I used /usr/local)

cd /usr/local
tar zxf ./jakarta-tomcat-5.0.28.tar.gz

3. Note the location of your Tomcat installation - we will refer to this as $CATALINA_HOME
4. Optionally, save time on typing by creating a symbolic link like this:

ln -s jakarta-tomcat-5.0.28 tomcat5 //RK I used just “tomcat”

3. Installing mod_jk on Linux

Follow these steps to install a binary copy of mod_jk.

1. Go to the JK 1.2 section of http://jakarta.apache.org/site/binindex.cgi and look in the folder for your OS. If you find one, download it. If you don't, skip to the next section.
2. Rename the downloaded file to mod_jk.so
3. Copy mod_jk.so to $APACHE_HOME/libexec

4. Building mod_jk on Linux

Follow these steps if you can't find a mod_jk binary or just want to build your own.

1. Check your prerequisites:

1. Type 'which libtool' to see if libtool in your $PATH. If it is not, and it is really not on your system, you will need the latest libtools from GNU:
* Download the latest libtools from ftp://ftp.gnu.org/gnu/libtool/.
* Unpack the distribution into the desired directory
* Cd into the distribution directory and type the following:

make install

RK: Mandrake 10: use software update/install from the KDE to get this done. Will need CD’s 1 & 4

* Now type 'which libtool' to make sure that libtool is in your $PATH. If its not, make sure you find out where 'make install' put libtool and libtoolize and add that location to your $PATH.
2. Type 'which autoconf' to see if autoconf in your $PATH. If it is not, and it is really not on your system, you will need the latest autoconf from GNU:

On my system, I had to de-install older rpms for autoconf first.
* Download the latest autoconf from http://ftp.gnu.org/gnu/autoconf/.
* Unpack the distribution into the desired directory
* Cd into the distribution directory and type the following:

make install

* Now type 'which autoconf' to make sure that autoconf is in your $PATH. If its not, make sure you find out where 'make install' put autoconf and add that location to your $PATH.

RK: I don't believe Ant is necessary. I alredy had Ant 1.6.2 installed.

3. Make sure you have Ant 1.5.1 or greater installed and $ANT_HOME set. If not, follow these steps:
* Download the latest Ant (currently 1.6.2) from http://ant.apache.org/bindownload.cgi
* Unpack the distribution in the desired directory (I used /usr/local)
* Optionally, save time on typing by creating a symbolic link like this:

ln -s apache-ant-1.6.2 ant

* Set $ANT_HOME in your environment (or in /etc/profile so you don't forget it next time) to point to the ant installation
* Make sure $ANT_HOME/bin is in your $PATH

2. Download the latest JK 1.2 Tomcat Web Server Connectors from http://jakarta.apache.org/site/sourceindex.cgi. As of this writing, JK 1.2.6 is the latest.
RK: correction: JK 1.2.8 is now the latest version and it was available for download on 2/7/2005. It wasn't on the prior day (I even sent an e-mail to the Jakarta webmaster).

As of December, the download link for JK 1.2 doesn't seem to be working. In the meantime, therefore, you can find JK 1.2.6 on my site.
3. Unpack the distribution in the desired directory

Currently, the distribution directory is jakarta-tomcat-connectors-jk-1.2.6-src
4. Cd into the distribution directory
5. Configure the makefile:

cd jk/native
./configure --with-apxs=/usr/local/apache2/bin/apxs --enable-EAPI

Replace the values of --with-apxs with the appropriate path to the apxs executable in your Apache installation directory.
6. Now do the build:


7. Finally, install

cp ./apache-2.0/mod_jk.so $APACHE2_HOME/modules

$APACHE2_HOME refers to the directory in which you installed the compiled Apache 2.x - in my case, it is /usr/local/apache2.

5. Configuring mod_jk for Apache 2.0.x

1. Create workers.properties in $APACHE_HOME/conf with the following contents:

worker.list=default //rk: this is the worker name to be used in Apache’s httpd.conf


Naturally, you will take care to set workers.tomcat_home and workers.java_home as approriate for your environment.

Often, people put the workers.properties file in $CATALINA_HOME/conf/jk, as my previous FlashGuides have also recommended. However, putting it in $APACHE_HOME/conf is more appropriate since its purpose is to tell Apache about one or more local or remote Tomcat installations.
2. For Apache 1.3.x, edit $APACHE_HOME/conf/httpd.conf and add the following to the LoadModules section:

LoadModule jk_module libexec/mod_jk.so

3. For Apache 2.0.x, edit $APACHE_HOME/conf/httpd.conf and add the following to the LoadModules section:

LoadModule jk_module modules/mod_jk.so

4. Edit $APACHE_HOME/conf/httpd.conf and add the following to the AddModules section (if you have it - Apache 2 and later versions of Apache 1.3.x don't):

AddModule mod_jk.c RK: don’t need for Apache2

5. Edit $APACHE_HOME/conf/httpd.conf and add the following before Section 3 in httpd.conf:

# Mod_jk settings

JkWorkersFile "conf/workers.properties"
JkLogFile "logs/mod_jk.log"

JkLogLevel error

JkMount /jsp-examples default //RK: default is the worker name
JkMount /jsp-examples/* default

# End of mod_jk settings

The location of the Jk workers.properties and log files are relative to $APACHE_HOME. If you prefer other locations, make sure you fully qualify the paths.

In this test, we are directing all URIs that begin with "/jsp-examples" to Tomcat. The name "default" corresponds to the JK worker that we defined in $APACHE_HOME/conf/workers.properties. We define two JK Mounts in order to match the URI of "/jsp-examples" as well as any that start with "/jsp-examples". In a real world situation, we might only direct JSPs or servlets to the JK worker.
6. Find the line in $APACHE_HOME/httpd.conf that starts with "Port" - make sure you have it pointing to a port that is not in use. Lately, Apache has been coming with the "Port" directive set to "8080", which is the same port that Tomcat will listen on. If you don't have any other web server running, you can set it to "80" instead.
7. Test httpd.conf by typing the following:

apachectl configtest

new item inserted by RK:
5a server.xml

The connector will work only if it’s entered like this. Tomcat 5 has a default that doesn’t seem to work. Comment it out and paste the line below. Debuh=”1” should be “0” for production mode.

<Connector port="8009" minProcessors="5" maxProcessors="75" acceptCount="10" debug="1" protocol="AJP/1.3"/>

end of inserted item by RK

6. Testing

1. Make sure no other server is running on the default Tomcat ports of 8005, 8009 and 8080. Make sure no other server is running on the Apache port, which is normally 8080 or 80.
2. Start Tomcat first:

./catalina.sh start

Always start Tomcat first and then start Apache. If you have to bounce Tomcat, remember to take down Apache first and restart it after Tomcat restarts. mod_webapp is very sensitive that way. In fact, some users have reported that it is necessary to put in 10 second delay between starting Tomcat and Apache.
3. Start Apache:

cd $APACHE2_HOME/bin
./apachectl start

4. Point your browser to http://localhost and verify that you get the default Apache page

Substitute "localhost" for the actual machine name/ip if necessary.
5. Point your browser to http://localhost:8080 and verify that you get the default Tomcat page
6. Point your browser to http://localhost/jsp-examples/ and verify that you get the index page for the Tomcat examples. This will be served by Apache and will indicate that you have completed your integration of Apache and Tomcat successfully - congratulations!

Roger Kepler

Monday, February 07, 2005

Check out these sites from some co-workers of mine.

There might not be much now, but check back soon.

KennyLloyd.com RogerKepler.com

Ken Cochrane

Patriots Win Again!

Dynasty anyone? I am not sure if they are a Dynasty but I do know that they
  • Won 3 superbowls in 4 years.
  • Won 32 out of their last 34 games.
  • Won 9 strait playoff games.
  • Has the longest winning streak in NFL history.
  • All 3 superbowl victories were in February.
  • Is the only team in NFL History to win a SuperBowl in February (3-0)
The one year they didn't win the superbowl they ended up in a three way time atop the AFC East and lost the tie-breaker to the Jets. The way the patriots closed out that season, they had momentum to possibly do it again, but they had to wait until the next year.

What is going to happen next year? They are losing their offensive & defensive coordinator, and at least a couple of coaches. Can they hold it all together to make another run? or is this the beginning of the end? I guess we will have to wait until next year.. So until then, lets sit back and bask in the glory while we can. First the Red Sox now the Pats.. Boy it is a good time to be a New England sports fan.

Ken Cochrane

If SSH with Public/Private Keys isn't working For you, check out this bit of info from my friend Roger.

From Roger Kepler 02-06-05:

I finally got ssh to work! BUT it wasn't easy and there are some extra steps you may not be aware of (or just didn't apply to you). With the ssh client I was getting the message "key refused" even though everything was setup correctly and in the server the public key was also setup correctly.

Well, it's not enough to just have ~.ssh/authorized_keys setup. There's more to it.

I did everything by the book, but it still didn't work. It was very tough and, as always, the devil is in the details. Little did I now I had to edit the /etc/ssh/sshd_config file and enable this line (!):

#PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys -> I just couldn't believe this line is commented out by default!!!

Once I removed the #, it worked...Well, not really. By this time I was about to give up. But, one small detail: the permission on ~.ssh/ needed to be changed:

~ $> chmod 755 .ssh (set dir to 'drwxr-xr-x')
~ $>'chmod 644 .ssh/authorized_keys' ('-rw-r--r--')

That did it! SSH now works for me. It only took me about 4+ hours to get it going and it would be even longer without your help.

Thanks for the info Roger.

Sunday, February 06, 2005

Tomcat 4.1 + Apache 1.3 + mod_jk + Debian 3.0 (Woody)
(This is still in progress, Not quite finished yet)

This is a little install guide on how to install Tomcat 4.1 with Apache 1.3 using mod_jk on Debian.

Install and setup Tomcat 4.1
First off I went to apache.org and downloaded the latest version of Tomcat 4.1's bin distribution, I am using the binary distro instead of the debian package because I want to have more then one tomcat install, and the easiest way to do this is to not use the package.

Once you get the file extract it to /usr/local/tomcat.version (tar -xvzf tomcat.tar.gz)
Create a link from this install directory to /usr/local/tomcat4 (ln -s /usr/local/tomcat.version /usr/local/tomcat4) .
Go into tomcats conf dir (cd /usr/local/tomcat4/conf)
Edit the server.xml file so that it is using the ports that you want to use and make sure the mod_jk connector settings aren't commented out.
Remember what ports you used for the tomcat server (usually 8080 by default) and the mod_jk connector (usually 8009 is default).

Install and Setup Apache 1.3
Apache 1.3 is in the stable branch of woody so if you don't already have it installed all you need to do is an (apt-get install apache) .
If you are not sure if you have apache installed you can do an (dpkg -l apache*) and it will list any packages that you have installed that start with apache.

If you don't want to use the stable branch you can get a backported copy from (deb http://packages.dotdeb.org ./) This is where I got mine. Just add this entry to your (/etc/apt/sources.list) file, then do an apt-get update and then an ( apt-get install
apache=1.3.26-0.dotdeb.1) Or what ever the latest version is. I am using this package because I also want to setup PHP and I found this was the easiest package to use when trying to get php4 and MySQL 4.1 connected.

Install mod_jk
You will also need to install the apache module mod_jk. I got this file from backports.org.
Add the following line to your (/etc/apt/sources.list) file and then do an apt-get update.

deb http://www.backports.org/debian stable libapache-mod-jk

Then you can install it using the following command.

apt-get install libapache-mod-jk=1.2.5-1.backports.org.1

Configure Apache
Once apache is installed you will need to edit the httpd.conf file which is usually in (/etc/apache/httpd.conf).

Add the following lines.
#This will load the jk module
LoadModule jk_module /usr/lib/apache/1.3/mod_jk.so

#This is to configure mod_jk if you don't have a workers.properties file make sure you read below.
JkWorkersFile /etc/apache/workers.properties
JkLogFile /var/log/apache/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "

#setup your virtual host so that it will forward all requests to tomcat.
<VirtualHost *>
ServerAdmin help@example.com
ServerAlias www.example.com
DocumentRoot /var/www
ServerName example.com
JkMount /* ajp13
ErrorLog logs/example-com-error_log
CustomLog logs/example-com-access_log combined


(if you get an error that the log files can't be written, then you will most likely need to create a link from /var/log/apache/ to /etc/apache/logs (ln -s /var/log/apache /etc/apache/logs) )

Setup the workers.properties file
# Setup for Debian system
#Set your tomcat_home to where you installed tomcat
#set your java home to where you have java installed.

# Definition for Ajp13 worker This is what you setup in tomcats server.xml file
#Set to localhost if tomcat server is on the same box as apache, if not put the domain name or ip of the tomcat server.

Startup and Test
Now that you have this setup, you can start apache and tomcat and test it out to see if it works. If it doesn't work, check the logs to see what the problem is.

/etc/init.d/apache start

If you want tomcat to statup when the server starts add a start and stop script into /etc/init.d/ and then created symbolic links into the various /etc/rc#.d directories. Look at the scripts inside of /etc/init.d/ for an example of how to do this.

More Links:
Here is a link to another good install guide for apache 1.3 tomcat 4.1 and mod_jk.

I hope this was of some help to someone. I know it will help me when I need to do this again, in the future.

Ken Cochrane
(work in progress)
Last Updated: 02-06-05