contact

Loading enum info ...

Postix virtual users mysql (Work in progress)

Index

About this document
Installing needed base packages
Mysql setup
Managing SSL certificates
Basic postfix configuration
Installing squirrelmail
Installing Postfixadmin and maildrop
Configure SASL and TLS
Installing amavisd-new
Moving Bayes and AWL to MySQL
Configure squirrelmail
Configure Razor
Additional postfix configuration
Configure VirtualVacation
Installing PostfixAdmin squirrelmail plugin
Installing MailZu
Configure quota support

About this document

This document describes how I did setup my mailserver.
The mailserver is a XeoN 1.6 GHZ with 2GB ram running Debian Etch.
If you run some other linux or bsd you will have to replace the installation commands
and paths to configuration files according to your setup.

This setup is heavily based upon the great tutorial by Gary V which you can find here.
I used some newer versions of software, which made some of his patches unusable.

This setup:

  • Uses Postfix virtual mailbox domains (with user and domain information stored in MySQL).
  • Uses the web based PostfixAdmin to maintain the database of administrators, domains, aliases, users, maildirs etc.
  • Uses the web based MailZu where users maintain their quarantined messages.
  • Uses Courier IMAP and POP3 servers. Also uses Courier authdaemon to authenticate users (via MySQL data).
  • Uses maildrop as a local delivery agent.
  • Uses maildirmake to create maildirs with quota information.
  • Divides each domain and user into a separate maildir, e.g.: /home/mail/virtual/three-dimensional.net/user/
  • Amavisd-new (with SpamAssassin) provides 'per user' settings via MySQL.
  • SquirrelMail allows for web based client access. Users can also modify their own spam sensitivity level and white/black lists.
  • Spam is automatically directed to the user's Spam folder or quarantine (user customizable).
  • Email borne virus scanning provided by ClamAV (and other optional vendors).
  • Is suitable for hundreds of users (depending on hardware).
  • Strives to connect users over secure connections thereby protecting their passwords from sniffing.
  • Assumes you have some experience with Linux and Postfix
  • Uses quite a few different passwords. Write them down and keep them safe.
  • Requires that you make no mistakes during copy and paste - please pay very close attention.

 

Installing needed base packages

We will need a bunch of software packages to be installed. You may or may not have those on your system.
Just to be sure run:

aptitude install ntp make build-essential gcc bison flex libc6-dev logcheck flip psmisc

You can ignore messages about packages already installed.

Now we install a webserver with php5 support and the ssl tools. This will fire a bunch of questions at you. Just go with the defaults for all, except the ones I outline here. The SSL certificate questions can be answered with whatever you want. We will resetup the SSL stuff later in this document.

aptitude install libapache2-mod-php5 php5 php5-common php5-mysql php5-gd php5-mcrypt ca-certificates openssl

And install postfix

aptitude install postfix postfix-pcre postfix-mysql libsasl2-modules-sql libsasl2-modules

Answer 'Internet Site' for general type and Mail name should be answered with a domain name you have (example.com)
And install courier for pop3/pop3s/imap/imap

aptitude install courier-imap-ssl courier-pop-ssl courier-authlib-mysql

Answer 'No' to the question wether to create directories for webbased administration. We are going to use PostfixAdmin for this.

Mysql setup

If you dont have a MySQL server installed do so now.

aptitude install mysql-server

The default Debian MySQL server setup is setup for small hardware. We will need some more power if we are going to host a lot of domains/users. You can stick with the defaults if your setup is just for your 3 domains with 5 users.
DONT blindly follow the next couple of instructions if you already use the mysql server. You will have to compare the settings with your running setup and alter whatever you need. Also, most of the settings here will apply to InnoDB only.
If you can't or dont want to use InnoDB you will have to tweak the backend settings you like to use to cache stuff.

We start by using the 'medium' sized mysql server settings, after we made a backup of the current configuration file.

cp /etc/mysql/my.cnf /etc/mysql/my.cnf-backup001
cp /usr/share/doc/mysql-server-5.0/examples/my-medium.cnf.gz /etc/mysql/my.cnf.gz
cd /etc/mysql
gunzip my.cnf.gz
wget "http://michiel.vanbaak.info/savefile/23/my-medium.cnf.patch.txt"
patch my.cnf < my-medium.cnf.patch.txt
/etc/init.d/mysql stop

Since the patch changed the innodb logsize we will have to remove the current ones and let mysql create new ones in the correct size.

rm /var/lib/mysql/ib_logfile0
rm /var/lib/mysql/ib_logfile1

Now it's time to start the mysql server and be done with this part

/etc/init.d/mysql start

The buffer pool size is raised from 8M to 192M. This is the biggest performance improvement. We also increased the logfile size to 25% of the buffer pool size. If you need more performance you can raise those limits, but be sure to not raise it to more then 25% of your physical RAM or it will start swapping and that will degrade performance.

Managing SSL certificates

Before we start creating and signing certificates:
Every client that connects to this server will need to be able to resolve the hostname. So either add it to your hosts file, or better, add it to the DNS. In the rest of the document we will refer to the server as 'mail.three-dimensional.net'
Because we dont have loads of money collecting dust on our bankaccount we are going to be our own CA (Certificate Authority) and sign our own certificates. If you have that money you can send the certificate signing requests to one of the commercial CA's out there and skip the signing step. If you do that, dont alter the default lifetime of certificates.
Selfsigned certificates must be installed by the client, so we make them valid for 10 years to not annoy our users every year with a new certificate:

sed -i 's/= 365\t/= 3653\t/' /etc/ssl/openssl.cnf

Now create a CA and certificate structure:

cd /root
mkdir CA
cd CA
mkdir demoCA
cd demoCA
mkdir newcerts
mkdir private
echo "01" > serial.txt
touch index.txt
cd ..

Create the Root Certificate

openssl req -new -x509 -extensions v3_ca -keyout demoCA/private/cakey.pem -out cacert.pem -days 3653

Provide a passphrase when asked. Be sure to remember this password for the next 10 years at least. You will need this password when performing actions on certificates, signing requests etc. I repeat, remember this password for the rest of your life! It will also ask you a couple of questions for the CA certificate. Here's some sample output. Provide answers that make sense, your users will see this.

Country Name: BE
State or Province Name: Viersel
Locality Name: Zandhoven
Organisation Name: Three-Dimensional VZW
Organisational Unit Name: Three-Dimensional VZW
Common Name (eg, YOUR name): Three-Dimensional RootCA
Email Address: support@three-dimensional.net

This will create two files: a private key in demoCA/private/cakey.pem and the RootCA in cacert.pem. Every keyfile we create should be protected from access by unauthorized persons and must be kept safe for at least 10 years. As this is a CA that can sign an unlimited number of certificates we only have to create it once. We now move the files to some more meaningfull names.

cp -i demoCA/private/cakey.pem demoCA/private/cakey.three-dimensional.pem
chmod 600 demoCA/private/*
cp -i cacert.pem cacert.three-dimensional.pem
cp -i cacert.pem cacert.three-dimensional.crt

The cacert.three-dimensional.pem and cacert.three-dimensional.crt are copies of our certificate and are the files that can be distributed and installed on the client's machines. Windows clients would use the .crt file. On my Windows 2000 system, double clicking this file would install it in Internet Explorer (which is exactly what want). Simply browsing to our server will give us the opportunity to install the web server certificate we will create (this will be the Common Name mail.three-dimensional.net) but this is not the same as installing the CA certificate in the Trusted Root Certification Authorities store (seen as the Common Name you entered above). Just in case you are not familiar, in IE6 it's Tools->Internet Options->Content->Certificates->Trusted Root Certification Authorities. Outlook and Outlook Express use the same certificate store as Internet Explorer. In Mozilla Thunderbird it's Tools->Options->Privacy->Security->View Certificates->Authorities. In Firefox it's Tools->Options->Advanced->Encryption->View Certificates->Authorities->Import. If you go through this process more than once while testing, don't install duplicate certificates. Delete any old 'test' certificate you previously installed before adding your new one that replaces it. I think the worst part of getting this server set up is getting the CA certificates installed on the clients. Sometimes it's worth it to buy a certificate from a well known commercial CA that is already in the Trusted Root Certification Authorities store.

We are now going to create a request for a certificate from the CA (which is us - but could be a commercial CA if you like). Everyone that connects to us will connect to the hostname of this machine. The Secure Web server, Secure IMAP server, Secure POP server and Postfix Secure SMTP server will all be mail.three-dimensional.net, so the 'Common Name' MUST be the FQDN when we create the request. DO NOT enter your email address, challenge password or an optional company name when creating the CSR:

openssl req -new -nodes -out req.pem

And answer with something like:

Country Name: BE
State or Province Name: Viersel
Locality Name: Zandhoven
Organisation Name: Three-Dimensional VZW
Organisational Unit Name: Mail Server
Common Name (eg, YOUR name) mail.three-dimensional.net
Email Address:

This again creates two files: a private key in privkey.pem and a CSR (Certificate Signing Request) in req.pem. These files should be kept. The private key is necessary for SSL encryption. We will make backup copies of these files with more descriptive names.

cp -i privkey.pem privkey.mail.three-dimensional.net.pem
chmod 600 privkey.*
cp -i req.pem req.mail.three-dimensional.net.pem

Now send the CSR to a commercial CA, or sign it yourself:

openssl ca -out cert.pem -cert cacert.pem -infiles req.pem

This process updates the CA database and produces two files as output, a certificate in cert.pem and a copy of the certificate in demoCA/newcerts/ named xx.pem, where xx is the serial number. We will copy the cert to a more descriptive name. The certificate has both the encoded version and a human-readable version in the same file. We want to strip off the human-readable portion as follows:

mv -i cert.pem temp.cert.mail.three-dimensional.net.pem
openssl x509 -in temp.cert.mail.three-dimensional.net.pem -out cert.pem
cp -i cert.pem cert.mail.three-dimensional.net.pem

Postfix will want the cert and the key in two separate files, apache-ssl will want the two combined (but can use two separate files if configured to do so). Courier will want the two combined, with a Diffie-Hellman code block added. Sheesh, why can't we all just get along?

cat privkey.mail.three-dimensional.net.pem cert.mail.three-dimensional.net.pem > key-cert.pem
cp -i key-cert.pem key-cert.mail.three-dimensional.net.pem
cp -i key-cert.pem key-cert-dh.mail.three-dimensional.net.pem
openssl gendh >> key-cert-dh.mail.three-dimensional.net.pem
chmod -R 600 /root/CA

After those steps, you have four installable components (and some more descriptive backup copies):
A private key in privkey.pem (with a copy in privkey.mail.three-dimensional.net.pem)
A certificate in cert.pem (with a copy in cert.mail.three-dimensional.net.pem)
A combined private key and certificate in key-cert.pem (with a copy in key-cert.mail.three-dimensional.net.pem)
A combined private key, certificate and DH code in key-cert-dh.mail.three-dimensional.net.pem

For apache2 we put the certificate somewhere where apache2 can read it.

cd /root/CA
mkdir /etc/apache2/ssl/
cp key-cert.mail.three-dimensional.net.pem /etc/apache2/ssl/key-cert.mail.three-dimensional.net.pem
chmod 600 /etc/apache2/ssl/key-cert.mail.three-dimensional.net.pem

We configure the default apache2 to provide us an SSL secured mail.three-dimensional.net.

echo "Listen 443" >> /etc/apache2/ports.conf
a2enmod ssl
cd /etc/apache2/sites-available

Now create a virtualhost file for mail.three-dimensional.net. Note that virtualhosting with SSL requires a seperate IP address for every virtualhost. Because IP addresses are not unlimited we will setup all services as subdirectories of https://mail.three-dimensional.net and bind this to the default ip address of our server. You can use this template as your virtualhost configuration file:

<VirtualHost *:443>
ServerName mail.three-dimensional.net
DocumentRoot /var/www
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/key-cert.mail.three-dimensional.net.pem
</VirtualHost>

Now enable this VirtualHost and reload the apache configuration

a2ensite mail.three-dimensional.net
/etc/init.d/apache2 reload

Give Postfix the files it needs and tell it where they are (and set a couple other TLS parameters). We also make a backup of main.cf before we modify it for the first time:

cp -i /etc/postfix/main.cf /etc/postfix/main.cf.backup001
mkdir /etc/postfix/ssl
cd /root/CA
cp privkey.mail.three-dimensional.net.pem /etc/postfix/ssl
cp cert.mail.three-dimensional.net.pem /etc/postfix/ssl
cp cacert.three-dimensional.net.pem /etc/postfix/ssl
postconf -e "smtpd_tls_key_file = /etc/postfix/ssl/privkey.mail.three-dimensional.net.pem"
postconf -e "smtpd_tls_cert_file = /etc/postfix/ssl/cert.mail.three-dimensional.net.pem"
postconf -e "smtpd_tls_CAfile = /etc/postfix/ssl/cacert.three-dimensional.net.pem"
postconf -e "smtpd_tls_received_header = yes"
postconf -e "smtpd_use_tls = yes"
chmod 600 /etc/postfix/ssl/*
postfix reload

Install certificates in Courier IMAP and configure imapd-ssl to use them (this changes the TLS_CERTFILE setting):

cp -i key-cert-dh.mail.three-dimensional.net.pem /etc/courier/
chmod 600 /etc/courier/key-cert-dh.mail.three-dimensional.net.pem
chown daemon /etc/courier/key-cert-dh.mail.three-dimensional.net.pem
sed -i 's/imapd.pem/key-cert-dh.mail.three-dimensional.net.pem/' /etc/courier/imapd-ssl
/etc/init.d/courier-imap-ssl stop
/etc/init.d/courier-imap-ssl start

And configure Courier POP3 to use the same certificates:

sed -i 's/pop3d.pem/key-cert-dh.mail.three-dimensional.net.pem/' /etc/courier/pop3d-ssl
/etc/init.d/courier-pop-ssl stop
/etc/init.d/courier-pop-ssl start

Basic postfix configuration

We want to set our domain name and hostname in postfix so it does not try to be 'smart' and find other locations to deliver mail:

postconf -e "mydomain = three-dimensional.net"
postconf -e "myorigin = three-dimensional.net"
postconf -e "myhostname = mail.three-dimensional.net"

Now we grab the Debian postfix source package, because we need some samples and configs from it:

cd /usr/local/src
wget "http://ftp.debian.org/debian/pool/main/p/postfix/postfix_2.3.8.orig.tar.gz"
tar zxvf postfix_2.3.8.orig.tar.gz

And we copy the example configuration over to our install. MAKE SURE YOU ANSWER 'n' to 'Overwrite?'

cp -i /usr/local/src/postfix-2.3.8/conf/* /etc/postfix

Now give some files a more meaningful name

cp -i /etc/postfix/header_checks /etc/postfix/body_checks
cp -i /etc/postfix/access /etc/postfix/sender_access
cp -i /etc/postfix/access /etc/postfix/rbl_client_exceptions
cp -i /etc/postfix/access /etc/postfix/rbl_recipient_exceptions
cp -i /etc/postfix/access /etc/postfix/reject_over_quota

On Debian, postfix runs chrooted. postfix comes with a shellscript to handle dependencies and copy files to the chroot:

cp /usr/local/src/postfix-2.3.8/examples/chroot-setup/LINUX2 /usr/sbin
chmod +x /usr/sbin/LINUX2
LINUX2

Installing squirrelmail

We will be using squirrelmail as webmail client.
Now install this, and some other tools that are needed.

aptitude install squirrelmail squirrelmail-locales sudo php-pear php5-cli php-db php-net-socket php-log php-net-smtp

Installing Postfixadmin and maildrop

We will be using maildrop to do the delivery (and optional filtering) on our virtual setup. And PostfixAdmin to provide a webbased administration tool for the whole mailsetup.

aptitude install maildrop

Now create a user and a group that will run the virtual setup

groupadd vmail -g 6060
useradd vmail -u 6060 -g 6060

We will grab PostfixAdmin from subversion so we need it installed:

aptitude install subversion

Now we grab the postfixadmin sources from subversion (this document was made when postfixadmin was at revision 313. It might work on later versions, but might not. That's why we checkout this explicit revision):

cd /var/www
svn -r 313 co https://postfixadmin.svn.sourceforge.net/svnroot/postfixadmin/trunk posfixadmin
cd postfixadmin

Postfixadmin comes with a default DATABASE_MYSQL.TXT file that can be run against your database server. We want to modify it a bit before we do this. We move all tables to InnoDB and alter the default passwords. Sometimes the file has the two lines to insert the postfix user into the users table commented out, so make sure you check that and remove the # at the beginning of the two lines which run "INSERT INTO user ..."

Change the database password for the postfix and postfixadmin user:

sed -i "s/password('postfix')/password('givepostfixaccess')/" DATABASE_MYSQL.TXT
sed -i "s/password('postfixadmin')/password('givepostfixadminaccess')/" DATABASE_MYSQL.TXT

Now patch it with our script and run it against the database server:

wget "http://michiel.vanbaak.info/savefile/24/database_mysql.patch.txt"
patch DATABASE_MYSQL.TXT < database_mysql.patch.txt
mysql -u root -p < DATABASE_MYSQL.TXT

And protect our passwords:

chmod 600 DATABASE_MYSQL.TXT

Now create a working configuration for postfixadmin:

sed -i "s|admin_url'] = ''|admin_url'] = 'https://mail.three-dimensional.net/postfixadmin'|" config.inc.php
sed -i "s/password'] = 'postfixadmin'/password'] = 'givepostfixadminaccess'/" config.inc.php
sed -i 's/postmaster@change-this-to-your.domain.tld/postmaster@three-dimensional.net/' config.inc.php
sed -i 's/abuse@change-this-to-your.domain.tld/abuse@three-dimensional.net/' config.inc.php
sed -i 's/hostmaster@change-this-to-your.domain.tld/hostmaster@three-dimensional.net/' config.inc.php
sed -i 's/postmaster@change-this-to-your.domain.tld/postmaster@three-dimensional.net/' config.inc.php
sed -i 's/webmaster@change-this-to-your.domain.tld/webmaster@three-dimensional.net/' config.inc.php
sed -i 's/autoreply.change-this-to-your.domain.tld/autoreply.three-dimensional.net/' config.inc.php
sed -i 's|to change-this-to-your.domain.tld|to https://mail.three-dimensional.net/postfixadmin|' config.inc.php
sed -i 's|http://change-this-to-your.domain.tld|https://mail.three-dimensional.net/postfixadmin|' config.inc.php
sed -i "s/domain_path'] = 'NO/domain_path'] = 'YES/" config.inc.php
sed -i "s/domain_in_mailbox'] = 'YES/domain_in_mailbox'] = 'NO/" config.inc.php
sed -i "s/mailboxes'] = '10'/mailboxes'] = '300'/" config.inc.php
sed -i "s/maxquota'] = '10'/maxquota'] = '500'/" config.inc.php
sed -i "s/quota'] = 'NO/quota'] = 'YES/" config.inc.php
sed -i "s/encrypt'] = 'md5crypt/encrypt'] = 'cleartext/" config.inc.php
sed -i "s/page_size'] = '10/page_size'] = '25/" config.inc.php
echo "\$CONF['create_mailbox_subdirs'] = array('Spam');" >> config.inc.php
echo "\$CONF['create_mailbox_subdirs_host'] = 'localhost';" >> config.inc.php
echo "\$CONF['create_mailbox_subdirs_hostoptions']=array('novalidate-cert','norsh');" >> config.inc.php

When we add a user to PostfixAdmin it will create the records in the MySQL database, but it does not create the Maildir for this user. We can make that happen by setting some variables in the config.inc.php script. However, by default PostfixAdmin does not promote the quota value to the scripts, and also does not run a script when we edit a user. This means we cannot use the quota settings by default. To make this happen you will have to patch PostfixAdmin with my patchfile. This file is also sent upstream but for now it's not included so we do it by hand. Also, the scripts that Postfixadmin includes dont take quota into account so I created my own versions.

cd /var/www/postfixadmin
wget "http://michiel.vanbaak.info/savefile/25/postfixadmin_support_quota.diff.txt"
patch -p0 < postfixadmin_support_quota.diff.txt
echo "\$CONF['create_mailbox_subdirs_hostoptions']=array('novalidate-cert','norsh');" >> config.inc.php
echo "\$CONF['mailbox_postcreation_script']='sudo /usr/local/sbin/maildirmake.sh';" >> config.inc.php
echo "\$CONF['mailbox_postedit_script']='sudo /usr/local/sbin/quotachange.sh';" >> config.inc.php
cd /usr/local/sbin
wget "http://michiel.vanbaak.info/savefile/26/maildirmake.sh.txt"
wget "http://michiel.vanbaak.info/savefile/27/quotachange.sh.txt"
mv maildirmake.sh.tx maildirmake.sh
mv quotachange.sh.txt quotachange.sh
chmod +x maildirmake.sh quotachange.sh
cd /var/www/postfixadmin

In order to allow the webserver to run those scripts we have to give it sudo access to run those without entering a password:

visudo

Add something like this:

www-data ALL=NOPASSWD: /usr/local/sbin/maildirmake.sh
www-data ALL=NOPASSWD: /usr/local/sbin/quotachange.sh

If you followed the tutorial about php5+fcgi you should add:

fcgi ALL=NOPASSWD: /usr/local/sbin/maildirmake.sh
fcgi ALL=NOPASSWD: /usr/local/sbin/quotachange.sh

And alter the script to set the correct owner and group for the generated files:

sed -i "s/www-data/fcgi/" /usr/local/sbin/maildirmake.sh

Now you can run the setup script to check your settings and create a super admin.
Do so by opening a browser and go to the url: https://mail.three-dimensional.net/postfixadmin/

Once you created the super admin account you should set PostfixAdmin to 'configured' and remove the setup.php script:

sed -i "s|configured'] = false|configured'] = true|" config.inc.php
rm setup.php

Now it's time to add our domain to the setup, and check if everything works as we want it to work.
Open https://mail.three-dimensional.net/postfixadmin in a browser and login with the superadmin you just created.
Create a domain 'three-dimensional.net' and after that create a mailbox for yourself 'info@three-dimensional.net'
Notice that Username: is only the local part; you choose the @domain from the drop down box. Create the username in lower case. This is your IMAP account. It is imperative that our maildirmake.sh script runs correctly when a mailbox is created in postfixadmin, otherwise Postfix will accept the message but will not be able to deliver it to a mailbox. Check that a mailbox exists, and a squirrelmail profile was created:

ls -lah /home/mail/virtual/three-dimensional.net
ls -lah /var/lib/squirrelmail/data

Note that if you delete a mailbox from postfixadmin, as a safety precaution we will not automatically delete the user's maildir (or mail). You will have to manually remove it. You should add another regular user "test@three-dimensional.net" to use when you need to test sending and receiving messages as a normal user (not related to any administrator accounts). At this point we still need to configure Postfix to send mail to our virtual mailboxes using the information stored in the postfixadmin databases. Begin by downloading and modifying Postfix data access configuration files:

cd /etc/postfix
wget "http://michiel.vanbaak.info/savefile/28/mysql_virtual_alias_maps.cf"
wget "http://michiel.vanbaak.info/savefile/29/mysql_virtual_domains_maps.cf"
wget "http://michiel.vanbaak.info/savefile/30/mysql_virtual_mailbox_maps.cf"
sed -i 's/password = postfix/password = givepostfixaccess/' mysql_virtual_alias_maps.cf
sed -i 's/password = postfix/password = givepostfixaccess/' mysql_virtual_domains_maps.cf
sed -i 's/password = postfix/password = givepostfixaccess/' mysql_virtual_mailbox_maps.cf
chmod 640 mysql_*
chown root:postfix mysql_*

We need to remove our domain name from $mydestination because our domain will soon be listed as a virtual mailbox domain - and you cannot have a domain in more than one address class:

postconf -e "mydestination = mail.three-dimensional.net, localhost.three-dimensional.net, localhost"

Now tell Postfix to use our MySQL data files and maildrop (which needs configuring, read on):

touch /etc/postfix/virtual
postmap /etc/postfix/virtual
postconf -e "virtual_minimum_uid = 6060"
postconf -e "virtual_gid_maps = static:6060"
postconf -e "virtual_uid_maps = static:6060"
postconf -e "virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf, hash:/etc/postfix/virtual"
postconf -e "virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf"
postconf -e "virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf"
postconf -e "virtual_transport = maildrop"
postconf -e "virtual_mailbox_base = /var/vmail/"
postconf -e "maildrop_destination_concurrency_limit = 2"
postconf -e "maildrop_destination_recipient_limit = 1"

Note that I use the proxy:mysql: syntax here. This will create persistant connections to MySQL and cache some stuff. This is really needed when doing more then a couple of emails an hour. It does have a drawback: changes to the MySQL tables wont be noticed by Postfix right away, but with some delay. You can remove the 'proxy:' during debugging, or reload postfix to get instant access to the changes.

To configure maildrop, get my maildroprc file. It will deliver spam to a users Spam folder, and also include a filterfile for the user if one is created:

cd /etc
rm maildroprc
wget "http://michiel.vanbaak.info/savefile/31/maildroprc"
touch /var/log/maildroprc.log
chown vmail:vmail /var/log/maildroprc.log
cd /etc/logrotate.d
wget "http://michiel.vanbaak.info/savefile/32/maildrop.logrotate.txt
mv maildrop.logrotate.txt maildrop

Now we need to edit the maildrop entry in postfix's master.cf because the the current one does not take virtualhosting into account.

vi /etc/postfix/master.cf

Locate the current maildrop transport and comment it out by prepending it with a # or simple remove it.
Now add the new version:

maildrop  unix  -  n  n  -  -  pipe
  flags=flags=ODRhu user=vmail:daemon argv=/usr/bin/maildrop -w 90 -d ${user}@${nexthop}
  ${extension} ${recipient} ${user} ${nexthop}

And reload postfix:

/etc/init.d/postfix stop
/etc/init.d/postfix start

If you get a message about files that differ in the postfix root and the system root, use the LINUX2 command to fix this.
Now, postfix is accepting mail, and handing it to maildrop for delivery. We should instruct maildrop how to find the relation between an email address and the maildir. Fortunately, both Courier and maildrop can use the same configuration daemon to get this kind of info. This is the courier-authdaemon. This daemon gets it's configuration from the file /etc/courier/authdaemonrc which in turn reads the configuration file for the specified backend. In our case it's MySQL with it's settings in /etc/courier/authmysqlrc

cd /etc/courier
rm authmysqlrc
wget "http://michiel.vanbaak.info/savefile/33/authmysqlrc.txt"
mv authmysqlrc.txt authmysqlrc
sed -i "s/MYSQL_PASSWORD\tpostfix/MYSQL_PASSWORD\tgivepostfixaccess/" authmysqlrc
chown daemon:daemon authmysqlrc
chmod 660 authmysqlrc

You also need to tell authdaemond to use the authmysqlrc file we just modified. We will use data in our MySQL postfix database to authenticate users for IMAP, POP and SASL. For remote clients to send mail we will use SASL with TLS. We can optionally use CRAM-MD5 for those clients that seem to have a broken TLS implementation. At least the password will be encrypted during its trip across the wire:

sed -i 's/authmodulelist="authpam"/authmodulelist="authmysql"/' authdaemonrc
/etc/init.d/courier-authdaemon restart

We will enable CRAM-MD5 login mechanism for imapd (port 143):

sed -i 's/SORT QUOTA IDLE/SORT QUOTA AUTH=CRAM-MD5 IDLE/' /etc/courier/imapd

Let's simply start off clean, we need to make certain stuff works after a reboot anyway:

reboot

Once the system comes back up:

tail -f /var/log/mail.log

Now we will send a message through the system to see if it lands in our maildir. You should already have a MUA set up to use this server as its outgoing server. You should also now be able to configure it to connect to the IMAP server using your username (full email address) and password. Assuming you have successfully created a maildir for yourself, send a message to yourself and see if you get it. Tail the mail.log file as the message goes through. Also: grep fatal /var/log/mail.log
Success should look like:

Jun 10 11:21:06 msa postfix/pipe[11513]: 0FBC5240C2: to=, relay=maildrop, 
delay=0.13, delays=0.07/0.02/0/0.04, dsn=2.0.0, status=sent (delivered via maildrop service)

If you have an error, you must fix it before you continue. We have made a lot of changes to a lot of files. It is certainly possible something happened along the way that would prevent proper delivery of a message. You should have an understanding of the files involved. You just have to find the incorrect setting(s). Some familiarity with Postfix would really be handy. Basic stuff like familiarity with the mailq, postsuper, qshape and postqueue commands. You will also want to set up the IMAP account for the test@three-dimensional.net user and send a message to that address.

ls -al /home/mail/virtual/three-dimensional.net/test/new
cat /var/log/maildroprc.log

If you can deliver mail to users, it would be a good idea to familiarize yourself with PostfixAdmin at this time. Add some aliases, add some domains. Play with the software. Postfix will no longer use /etc/aliases for our virtual domains so you will need to make aliases (or mailboxes) for root, abuse, postmaster, webmaster and logcheck @three-dimensional.net. If you fail to make aliases or mailboxes for recipients of system generated mail, maildrop will bounce the messages and complain with an 'Invalid user specified.' error. Set up your MUA to retrieve mail from the mailserver via IMAP SSL on port 993. If you must use POP3, use POP3 SSL on port 995. POP3 clients will only be able to retrieve mail from the /new folder which means they will never see their Spam folder unless they also use SquirrelMail. If you must use standard POP (110) or IMAP (143), configure the client to use TLS (if it's an option - some clients use it automatically). Install the CA certificate we created earlier on the test client if you have not already done so. Not having the root certificate properly installed will cause all kinds of grief.

If you need to debug pop3d/imapd/pop3d-ssl/imapd-ssl, edit those files in the /etc/courier directory and add DEBUG_LOGIN=2. Then of course restart any of those services as needed. This will give more details in mail.log. Also check /var/log/auth.log:
/etc/init.d/courier-pop restart
/etc/init.d/courier-pop-ssl restart
/etc/init.d/courier-imap restart
/etc/init.d/courier-imap-ssl restart

Now take a moment to relax, enjoy the messages in /var/log/mail.log and be happy with your working mail setup.
If you think you are ready for the next journey, let's move on and start adding the real cool stuff to our setup.

Configure SASL and TLS

SASL and TLS will allow you to send mail using this mailserver after a succesfull SMTP authentication. The whole dialog can be encrypted using SSL. To get it running follow this section.

First, we have to configure SASL, a Simple Authentication and Security Layer. It will allow using this server as relay host once a user is succesfull authenticated using SMTP auth.
Start by creating the file to link postfix and courier together for this:

vi /etc/postfix/sasl/smtpd.conf

and insert the following:

mech_list: plain login
pwcheck_method: auxprop
auxprop_plugin: sql
sql_engine: mysql
sql_user: postfix
sql_passwd: givepostfixaccess
sql_hostnames: 127.0.0.1
sql_database: postfix
sql_statement: select password from mailbox where username='%u@%r'

Make sure we are not using saslauthd (dont worry about this if /etc/init.d/saslauthd does not exist)

sed -i 's/START=yes/START=no/' /etc/default/saslauthd
/etc/init.d/saslauthd stop

Since Debian runs Postfix chrooted, Postfix will need the authdaemon socket in it's path. We will create a hardlink to it.

mkdir -p /var/spool/postfix/var/run/courier/authdaemon
ln /var/run/courier/authdaemon/socket /var/spool/postfix/var/run/courier/authdaemon/socket
chown -R daemon:daemon /var/spool/postfix/var/run/courier
chmod 755 /var/run/courier/authdaemon

We have to recreate this link to 'socket' prior to Postfix starting up so we will modify the init script:

vi /etc/init.d/postfix

and just after # Make sure that the chroot environment is set up correctly. (around line 45) insert the following:

ln -f /var/run/courier/authdaemon/socket /var/spool/postfix/var/run/courier/authdaemon/socket

Now tell Postfix to use SASL (we make a backup copy of main.cf should you need to refer to it):

cp -i /etc/postfix/main.cf /etc/postfix/main.cf-before-sasl
postconf -e "broken_sasl_auth_clients = yes"
postconf -e "smtpd_sasl_auth_enable = yes"
postconf -e "smtpd_sasl_local_domain = \$myhostname"
postconf -e "smtpd_sasl_security_options = noanonymous"
postconf -e "smtpd_sasl_authenticated_header = yes"
postconf -e "smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination"
/etc/init.d/postfix restart

If SASL auth stops working with "warning: SASL authentication failure: cannot connect to Courier authdaemond: Connection refused", a likely cause is Postfix can no longer write to the socket (due to running chrooted). Restarting postfix with the modified init script may solve the problem.
/etc/init.d/postfix restart

You should now edit your /etc/postfix/master.cf to make postfix listen on some ports to understand sasl etc.
The two grey lines donate the lines you will find in master.cf and all the other text should replace whatever is there:

smtp inet n - - - - smtpd

    -o smtpd_use_tls=no
-o smtpd_sasl_auth_enable=no
# -o receive_override_options=no_address_mappings
# If they want to relay, make them use port 587 (submission) or port 465 (smtps)
# If using submission port, configure client to use CRAM-MD5
submission inet n - - - - smtpd
-o smtpd_use_tls=no
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o receive_override_options=no_address_mappings
# Outlook and OE (and many others) expect smtpd_tls_wrappermode,
# so have them submit here (port 465):
smtps inet n - - - - smtpd
-o smtpd_enforce_tls=yes
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o receive_override_options=no_address_mappings
# We will use port 4650 for clients that use STARTTLS:
4650 inet n - - - - smtpd
-o smtpd_enforce_tls=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o receive_override_options=no_address_mappings

#628 inet n - - - - qmqpd

Just to be sure, grab my master.cf for this stage:

cd /etc/postfix
wget "http://michiel.vanbaak.info/savefile/34/master.cf.sasl"
mv master.cf.sasl master.cf

And then we need to restart postfix to apply those settings:

/etc/init.d/postfix restart

This should give you a mailserver setup able to send mail using this mailserver with SMTP auth.

Installing amavisd-new

some text

Moving Bayes and AWL to MySQL

some text

Configure squirrelmail

some text

Configure Razor

some text

Additional postfix configuration

some text

Configure VirtualVacation

some text

Installing PostfixAdmin squirrelmail plugin

some text

Installing MailZu

some text

Configure quota support

some text

Copyright (c) 2006-2008 Michiel van Baak.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU Free Documentation License".
< back | print | text | Postix virtual users mysql (Work in progress)