Andy's Debian Woody Virtual Mail Server HowTo

This HOWTO is now considered depreciated and is no longer supported.

For up to date HOWTOs see my Debian Wiki index page.

Introduction

Postfix + mySQL + TLS + SASL + Courier IMAP/POP3 + Maildrop + Squirrelmail

This document discussed the installation and configuration of a Debian GNU Linux based mail server supporting virtual domains.

The system is centred around the Postfix mail transfer agent, with clients connecting via encrypted POP3, IMAP and authenticated SMTP connections. Mail is stored on the file system in Maildir format. Local users and domains, as well as authentication credentials for POP3, IMAP and authenticated SMTP clients are stored in a mySQL database. Administration is entirely web-based, and a high degree of automation can be achived.

Our system supports:

  • Virtual domains and users - no need for real unix users, full email address used as username
  • Authenticated SMTP - configure authentication using a username and password for clients requiring relay access to send email
  • SMTP with TLS support - encrypted SMTP connections from clients, and to and from other MTAs
  • POP3 with SSL support - encrypted POP3 connections from remote email clients
  • IMAP with SSL support - encrypted IMAP connections from remote email clients
  • Webmail - a powerful, standards compliant, cross-browser web mail system
  • Effective content filtering against spam and viruses
  • Easy web-based administration

Our Configuration is as follows:

  • Debian Woody
  • Postfix
  • mySQL
  • Maildrop
  • Amavis
  • Spam Assassin
  • Razor
  • Cyrus SASL
  • Courier POP3
  • Courier IMAP
  • Squirrel Mail
  • Postfix Admin
  • Apache
  • PHP4

Contents

  • Apache
  • PHP
  • MySQL
  • PHPMyAdmin
  • Our Database
  • Postfix Admin
  • Postfix
  • SASL2
  • TLS for SMTP
  • Courier IMAP / POP3
  • Maildrop
  • Amavisd-New
  • SquirrelMail
  • Client Notes
  • Mail Reports
  • Mailgrep.pl
  • Mailgraph
  • Postal
  • To Do
  • Reference
  • Credits

Apache

Install Apache:

apt-get install apache

PHP

Install PHP with MySQL support:

apt-get install php4-mysql

The installer should add the necessary line in to apache's configuration file to load the PHP module, but you may need to uncomment it manually. Uncomment the line below from /etc/apache-ssl/httpd.conf to have Apache load the PHP module:

LoadModule php4_module /usr/lib/apache/1.3/libphp4.so

Next check the PHP configuration file at /etc/php4/apache/php.ini and check that MySQL support is enabled. The installer should have added the line below for you:

extension=mysql.so

Restart apache-ssl:

/etc/init.d/apache-ssl restart

MySQL

Install MySQL Server

apt-get install mysql-server

Choose not to have your databases and configuration deleted should you ever purge the MySQL package from the system

Opt to have MySQL started at boot

Create MySQL database by entering the command below:

mysql_install_db

Set root@localhost password:

mysqladmin -u root password "newpwd"

Optionally enable networking in the config file at /etc/mysql/my.cnf by uncommenting the like shown below:

skip-networking

and restarting the daemon:

/etc/init.d/mysql restart

You can connect to your MySQL server using the locally installed MySQL client using the command below:

mysql -u root -p

PHPMyAdmin

Install the phpmyadmin package the Debian way:

apt-get install phpmyadmin

You should then be able to administer your MySQL databases at https://localhost/phpmyadmin. Note the use of the HTTPS protocol.

I usually go right ahead and delete those anonymous users, which are those that PHPMyAdmins shows as user “any”. Our Database

Use PHPMyAdmin to create a new database called postfix.

Create the Postfix database by importing the MySQL schema below through PHPMyAdmin.

# Table structure for table admin
CREATE TABLE admin (
username varchar(255) NOT NULL default '',
password 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  (username),
KEY username (username)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Admins';


# Table structure for table alias
CREATE TABLE alias (
id int(11) NOT NULL auto_increment,
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  (id),
KEY address (id)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Aliases';

# Table structure for table domain
CREATE TABLE domain (
id int(11) NOT NULL auto_increment,
domain varchar(255) NOT NULL default '',
description varchar(255) NOT NULL default '',
aliases int(10) NOT NULL default '-1',
mailboxes int(10) NOT NULL default '-1',
maxquota int(10) NOT NULL default '-1',
transport varchar(255) default NULL,
backupmx tinyint(1) NOT NULL default '0',
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  (id),
KEY domain (id)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Domains';

# Table structure for table domain_admins
CREATE TABLE domain_admins (
username varchar(255) NOT NULL default '',
domain varchar(255) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
KEY username (username)
) TYPE=MyISAM COMMENT='Postfix Admin - Domain Admins';

# Table structure for table log
CREATE TABLE log (
timestamp datetime NOT NULL default '0000-00-00 00:00:00',
username varchar(255) NOT NULL default '',
domain varchar(255) NOT NULL default '',
action varchar(255) NOT NULL default '',
data varchar(255) NOT NULL default '',
KEY timestamp (timestamp)
) TYPE=MyISAM COMMENT='Postfix Admin - Log';

# Table structure for table mailbox
CREATE TABLE mailbox (
id int(11) NOT NULL auto_increment,
uidnumber int(11) NOT NULL default '1004',
gidnumber int(11) NOT NULL default '1004',
username varchar(255) NOT NULL default '',
password varchar(255) NOT NULL default '',
name varchar(255) NOT NULL default '',
homedir varchar(50) NOT NULL default '/var/vmail/',
maildir varchar(255) NOT NULL default '',
quota int(10) NOT NULL default '-1',
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',
access tinyint(4) NOT NULL default '1',
PRIMARY KEY  (id),
KEY username (id)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Mailboxes';

# Table structure for table vacation
CREATE TABLE vacation (
email varchar(255) NOT NULL default '',
subject varchar(255) NOT NULL default '',
body text NOT NULL,
cache text NOT NULL,
domain varchar(255) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(1) NOT NULL default '1',
PRIMARY KEY  (email),
KEY email (email)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Vacation';

# Table structure for table `saslauth`
CREATE TABLE saslauth (
id int(255) NOT NULL auto_increment,
domain varchar(50) NOT NULL default '',
username varchar(50) NOT NULL default '',
password varchar(255) NOT NULL default '',
PRIMARY KEY (id),
KEY id (id)
) TYPE=MyISAM COMMENT='SASL Auth - Users';

# Table structure for table `relocated`</code>
CREATE TABLE relocated (
id int(11) NOT NULL auto_increment,
email varchar(255) NOT NULL default '',
destination varchar(255) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;


===== Postfix Admin =====

Add a new database user called postfixadmin to be accessed from localhost only. The user should have permission to perform select, insert, update and delete to all tables within the postfix database. Use PHPMyAdmin to add the user and grant privileges.

Download latest version of postfixadmin from High5.net/postfixadmin/

Extract the files and copy them to within your webserver's document root:

<code>tar -xf postfixadmin-2.0.4.tar
mv postfixadmin-2.0.4 /var/www
cd /var/www
mv postfixadmin-2.0.4 postfixadmin
cd /var/www/postfixadmin</code>

Create a configuration file by copying the same one:

<code>cp config.inc.php.sample config.inc.php</code>

Edit the config file and set your options. I set them as follows:

<file>
// Database Config
// 'database_type' is for future reference.
$CONF['database_type'] = 'mysql';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'postfixadmin';
$CONF['database_name'] = 'postfix';

// Site Admin
// Define the Site Admins email address below.
// This will be used to send emails from to create mailboxes.
$CONF['admin_email'] = 'postmaster@yourdomain.tld';

// Mail Server
// Hostname (FQDN) of your mail server.
// This is used to send email to Postfix in order to create mailboxes.
$CONF['smtp_server'] = "localhost";
$CONF['smtp_port'] = "25";

// Encrypt
// In what way do you want the passwords to be crypted?
// md5crypt = internal postfix admin md5
// system = whatever you have set as your PHP system default
// cleartext = clear text passwords (ouch!)
$CONF['encrypt'] = 'md5crypt';

// Generate Password
// Generate a random password for a mailbox and display it.
// If you want to automagicly generate paswords set this to 'YES'.
$CONF['generate_password'] = 'YES';

// Page Size
// Set the number of entries that you would like to see
// in one page.
$CONF['page_size'] = '100';

// Default Aliases
// The default aliases that need to be created for all domains.
$CONF['default_aliases'] = array (
  'abuse' => 'abuse@yourdomain.tld',
  'hostmaster' => 'hostmaster@yourdomain.tld',
  'postmaster' => 'postmaster@yourdomain.tld',
  'webmaster' => 'webmaster@yourdomain.tld'
);

// Mailboxes
// If you want to store the mailboxes per domain set this to 'YES'.
// Example: /usr/local/virtual/domain.tld/username@domain.tld
$CONF['domain_path'] = 'YES';
// If you don't want to have the domain in your mailbox set this to 'NO'.
// Example: /usr/local/virtual/domain.tld/username
$CONF['domain_in_mailbox'] = 'NO';

// Default Domain Values
// Specify your default values below. Quota in MB.
$CONF['aliases'] = '-1';
$CONF['mailboxes'] = '-1';
$CONF['maxquota'] = '100';

// Quota
// When you want to enforce quota for your mailbox users set this to 'YES'.
$CONF['quota'] = 'YES';
// When using maildrop use '102400' otherwise use '1048576'
// AB: Added an additional 0 to correct mathematical error
// 100MB was being stored as 10240000 (which is 10MB)
$CONF['quota_multiplier'] = '1024000';

// Virtual Vacation
// If you want to use virtual vacation for you mailbox users set this to 'YES'.
// NOTE: Make sure that you install the vacation module. http://high5.net/postfixadmin/
$CONF['vacation'] = 'NO';

// Alias Control
// Postfix Admin inserts an alias in the alias table for every mailbox it creates.
// The reason for this is that when you want catch-all and normal mailboxes
// to work you need to have the mailbox replicated in the alias table.
// If you want to take control of these aliases as well set this to 'YES'.
$CONF['alias_control'] = 'YES';

// Logging
// If you don't want logging set this to 'NO';
$CONF['logging'] = 'YES';

// Header
// Some header configuration.
// If you don't want the Postfix Admin logo to appear set this to 'NO'.
$CONF['logo'] = 'YES';
$CONF['header_text'] = ':: Welcome to Postfix Admin ::';

// Footer
// Below information will be on all pages.
// If you don't want the footer information to appear set this to 'NO'.
$CONF['show_footer_text'] = 'YES';
$CONF['footer_text'] = 'Return to hostname.domain.tld';
$CONF['footer_link'] = 'http://hostname.domain.tld/';

When adding a domain, be sure to specify virtual or maildrop: as the description. The description field is read by Postfix as used as the name of the transport (mail delivery agent) to deliver mail for that domain. Virtual is the transport built in to Postfix that is used to deliver mail for virtual users. Maildrop is the additional transport we added as an alternative that can deliver mail to virtual users exactly like the virtual transport, but which also has support for quotas and server side mail filtering rules. Use maildrop: if you want your quota setting in the mailbox table for the virtual to be respected. Postfix

Create a vmail user and group for postfix to deliver mail as. We could use the postfix user and group automatically created for us during the postfix install later, but we wont because we will use another mail delivery agent called maildrop that will need to run as a user other than postfix:

groupadd vmail -g 1004
useradd vmail -u 1004 -g 1004

Here we use a UID and GID of 1004. Maildrop, or the Postfix virtual delivery agent will lookup the UID and GID to use when delivering mail from the database we created previously. If you choose to use another UID or GID then you must remeber to update both the UID and GID values for any existing records, and also the default value for the UID and GID fields to be used when a new record is created. Failure to do so will prevent local delivery of mail to your virtual users.

Create a directory to have all your virtual users mail dropped in, this directory needs to be owned by the vmail user you just created.

mkdir /var/vmail
chown -R vmail:vmail /var/vmail
chmod -R 751 /var/vmail

Use PHPMyAdmin to create a new MySQL user for localhost only called postfix. Grant the postfix user select permissions to all tables in the postfix database.

We want to use Postfix 2, but unfortunately only Postfix 1 is available within the Debian stable distribution. Your options are to install Postfix 2 from the Debian testing distribution, or to install a backport of Postfix 2 from backports.org. The main difference is that when installing from testing, Postfix's dependancies will also need to be met from testing. The backport on the other hand is built to meet its dependancies from your existing stable distribution. You should be aware that neither of these options will benefit from the timely security updates made available by the security team for the Debian stable distribution.

Here, we will install Postfix from the testing distribution using a technique called apt pinning that allows us to selectively install from testing whilst maintaining a primarilly stable system. You will need to setup apt, checkout Google or my apt pinning howto.

Install Postfix from testing the Debian way with MySQL support. When prompted, go with internet site config.

apt-get install postfix-mysql -u -t testing

Add the lines shown below to your Postfix configuration file at /etc/postfix/main.cf. These enable support for virtual domains, and tell Postfix how to look up details of virtual domains, users, aliases etc.

# What virtual domains are there?
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf

# Where are virtual mailboxes located on the disk
virtual_mailbox_base = /var/vmail

# Where in the above directory are the user's mailboxes.
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf

# What is the DEFAULT lda transport?
# see transport_maps for overrides
virtual_transport = virtual

# What lda transport is used for this domain?
transport_maps = mysql:/etc/postfix/mysql_virtual_transport_maps.cf

# What user/group ownerships are used when writing to the mailbox?
virtual_uid_maps = static:1004
virtual_gid_maps = static:1004
# as an alternative to having them static we can lookup the user from MySQL
virtual_minimum_uid = 100
virtual_uid_maps = mysql:/etc/postfix/mysql_virtual_uid.cf
virtual_gid_maps = mysql:/etc/postfix/mysql_virtual_gid.cf

# virtual aliases
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf

# What domains will we relay mail to?
# This is used so Postfix will queue mail for backup MX domains
relay_domains = proxy:mysql:/etc/postfix/mysql_relay_domains_maps.cf

# relocated maps for account has moved messages
relocated_maps = mysql:/etc/postfix/mysql_virtual_relocated_maps.cf

Create /etc/postfix/mysql_virtual_domains_maps.cf:

user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = 0 and active = 1

Create /etc/postfix/mysql_virtual_mailbox_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = mailbox m, domain d
select_field = m.maildir
where_field = m.username
additional_conditions = and d.active = 1 and d.backupmx = 0 and d.domain = m.domain and m.active = 1

Create /etc/postfix/mysql_virtual_transport_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = domain
select_field = description
where_field = domain
additional_conditions = and backupmx = 0 and active = 1

Create /etc/postfix/mysql_virtual_alias_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = alias a, domain d
select_field = a.goto
where_field = a.address
additional_conditions = and d.active = 1 and d.backupmx = 0 and d.domain = a.domain and a.active = 1

Create /etc/postfix/mysql_virtual_uid.cf

user = postfix
password = postfix
dbname = postfix
table = mailbox
select_field = uidnumber
where_field = username
additional_conditions = and active = 1
hosts = localhost

Create /etc/postfix/mysql_virtual_gid.cf

user = postfix
password = postfix
dbname = postfix
table = mailbox
select_field = gidnumber
where_field = username
additional_conditions = and active = 1
hosts = localhost

Create mysql_relay_domains_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and active = 1 and backupmx = '1'

Create /etc/postfix/mysql_virtual_relocated_maps.cf

user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = relocated
select_field = destination
where_field = email

Set permissions to postfix will be able to read these files:

chown root:postfix /etc/postfix/mysql_*

edit /etc/aliases so that your local users forward mail to your virtual users. remember to run 'newaliases' after editing the file.

ee /etc/aliases
newaliases

Restart the postfix daemon:

/etc/init.d/postfix restart

SASL2

Update: This section of the howto has been updated to show the use of the new Cyrus SASL2 libraires and SQL module to support authenticated SMTP connections through Postfix. This configuration removes the requirement to use PAM and its MySQL module to perform authentication against the database, but requires that you install the postfix-tls package from the Debian testing distribution. See my notes on apt pinning for help doing this if you are running stable.

The page here previously, which used the older Cyrus SASL7 library in conjunction with PAM and the PAM MySQL module remains available here. It should be used only by those who are installing the postfix-tls package from stable.

Thank you to Robert for contributing this improved configuration! Installation & Configuration

Stop postfix, and install the build of Postfix that support TLS, and also the SASL2 library, its SQL module and its authentication modules:

/etc/init.d/postfix stop
apt-get install postfix-tls libsasl2 libsasl2-modules-sql libsasl2-modules -t testing -u

Prevent postfix from running in a chroot jail, by editing the line for the smtp daemon in /etc/postfix/master.cf. You need to change a y to a n in the column which determines if the daemon runs in a chroot jail or not, as shown below:

smtp inet n - n - - smtpd

Tell postfix to allow sasl authenticated clients to relay, by adding the permit_sasl_authenticated parameter to the smtpd_recipient_restrictions directive in the Postfix configuration file at /etc/postfix/main.cf:

smtpd_recipient_restrictions =
  permit_mynetworks
  permit_sasl_authenticated
  reject_unauth_destination

Enable SASL support within Postfix by adding the lines shown below to /etc/postfix/main.cf:

# SMTP AUTH (SASL)
smtpd_sasl_auth_enable = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_security_options = noanonymous
# Be nice to brokenware like Outlook Express:
broken_sasl_auth_clients = yes

Configure the SASL2 library and its SQL module, by creating a configuration file at /etc/postfix/sasl/smtpd.conf with the lines shown below:

pwcheck_method: auxprop
auxprop_plugin: sql
mech_list: plain login cram-md5 digest-md5
sql_engine: mysql
sql_hostnames: 127.0.0.1
sql_user: smtpauth
sql_passwd: smtpauth
sql_database: postfix
sql_select: select password from saslauth where username='%u' and domain='%r'

We created the table to store sasl client authentication credentials when we created our postfix database previously. We just need to create a new mySQL user called smtpauth. Create the user for localhost only, and grant the user select privilges to your saslauth table.

Postfixadmin doesnt currently have an interface to administer the information within the saslauth table, and so you will have to populate this table manually, modify Postfix admin yourself, or write your own interface. Store plain text passwords- im working on a way yto use MD5 hashed passwords currently. Its also on my todo list to have a look at putting a web based interface together.

Then restart postfix:

/etc/init.d/postfix restart

TLS for SMTP

Follow the optional additional steps to enable TLS support for your clients when using an sasl authenticated connection. This is strongly reccomended for security reasons - but be sure to also enable the setting within your mail clients.

First you will need an SSL certificate. If you don't want to pay for one from your favorite certificate authority you can well use a self-signed one. The only drawback: the mail clients don't 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. Making your own certificate is very easy thanks to a script called mkx509cert from Rene Mayrhofer. Get it from here and place it at /usr/local/bin or /root. You will need to set the script executable

chmod a+x mkx509cert

To generate the certificate you call this script using these parameters:

key-length valid-days key-file cert-file self-signed country-code state locality organisation organisational-unit host-name email-address

For a certificate that is valid for one year for smtp.domain.tld you would run something like this:

mkx509cert 2048 365 smtpd.key smtpd.cert true "" "" "" "" "" smtp.domain.tld support@domain.tld

You should end up with the 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 only readable for the 'postfix' user or security will be seriously compromised.

Enable support in postfix by adding/enabling the lines below:

Enable TLS encryption

smtpd_use_tls = yes

The location of the SSL certificate

smtpd_tls_cert_file = /etc/postfix/smtpd.cert

The location of the SSL private key

smtpd_tls_key_file = /etc/postfix/smtpd.key

Restart postfix

/etc/init.d/postfix restart

Telnet to your server on port 25, and you should see 250-STARTTLS indicating that TLS is available. Courier IMAP / Courier POP3

First we need to install the courier-imap, courier-pop3 and courier-authmysql packages:

apt-get install courier-imap
apt-get install courier-pop
apt-get install courier-authmysql

Then we need to tell the courier authdaemon to use its authmyslrc (MySQL) module instead of PAM for authenticating users. Do this by modifying the line in /etc/courier/authdaemonrc as shown below:

authmodulelist="authmysql"

Create a file at /etc/courier/authmysqlrc containing the settings that the MySQL module of Courier authdaemon will use to connect to your database:

#MYSQL_SOCKET /var/lib/mysql/mysql.sock
MYSQL_SERVER localhost
#MYSQL_PORT 0
MYSQL_USERNAME courier
MYSQL_PASSWORD courier
MYSQL_DATABASE postfix
MYSQL_USER_TABLE mailbox
MYSQL_CRYPT_PWFIELD password
MYSQL_LOGIN_FIELD username
MYSQL_MAILDIR_FIELD maildir
MYSQL_NAME_FIELD name
MYSQL_HOME_FIELD '/var/vmail'
MYSQL_GID_FIELD gidnumber
MYSQL_UID_FIELD uidnumber
MYSQL_WHERE_CLAUSE access=1
MYSQL_OPT 0
#MYSQL_QUOTA_FIELD quota
#DEFAULT_DOMAIN domain.tld

Use PHPMyAdmin to create a new MySQL user for localhost only called “courier”. The user should have select privildges to your mailbox table in the postfix database.

Check courier's configuration at /etc/courier/imapd. I had a problem where by a client may browse a few folders, but would then loose connection to the server. I found that increasing the number of connections permitted from a single IP address within the Courier configuration was necessary to resolve this. The Mozilla Thunderbird client will establish up to 5 connections to the server by default, so 4 is inadequate. Consider also, that your web mail system will be connecting to your IMAP server also. Each web mail user will generate a connection from the IP address 127.0.0.1, and so the limit you set should be sufficient for the number of simultaneous web mail users you wish to support. Increase the number of connections per IP address by adjusting the line shiwn below:

MAXPERIP=100

Restart the courier-imap and courier-pop daemons:

/etc/init.d/courier-imap restart
/etc/init.d/courier-pop restart
/etc/init.d/courier-authdaemon restart

If you want TLS (SSL) support, install the package POP3 and IMAP SSL packages:

apt-get install courier-imap-ssl
apt-get install courier-pop-ssl

In order to use SSL you need certificates. Usually these would be issued by Thawte or Verisign (and would cost a lot of money!), but its also possible to “self sign” your certificates. Be aware that self signed certificates have the disadvantage of causing warnings to be displayed in your users email clients, but its usually possible to permanantly accept them causing the error to be no longer displayed. Handily, self signed certificates will be generated for you and placed in /etc/courier/imapd.pem and /etc/courier/pop3d.pem automatically when you install the above packages.

I found that the self signed certificates described above were setup for “localhost”, and not my real hostname. This caused Mozilla Thunderbird to persistantly issue a second warning about the hostnames of the certificate the system not mathing. To correct this problem we need to generate new certificates with the correct hostname. First edit /etc/courier/imapd.cnf to include the details you want your certificate to use:

RANDFILE = /usr/lib/courier/imapd.rand

[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no

[ req_dn ]
C=GB
ST=London
L=MyCompanyLtd
O=Courier Mail Server
OU=Automatically-generated IMAP SSL key
CN=host.domain.co.uk
emailAddress=postmaster@domain.co.uk

[ cert_type ]
nsCertType = server

Then backup your existing certificates and generate new ones:

cd /etc/courier
mv *.pem /root
mkimapdcert

Restart the courier-imap-ssl and courier-pop-ssl daemons:

/etc/init.d/courier-imap-ssl restart
/etc/init.d/courier-pop-ssl restart
/etc/init.d/courier-authdaemon restart

Maildrop

Download the latest Courier Maildrop from here. Then extract and use the configure script with the parameters as shown below to configure it it:

wget http://optusnet.dl.sourceforge.net/sourceforge/courier/maildrop-1.6.3.tar.bz2
tar jxf maildrop-1.6.3.tar.bz2
cd maildrop-1.6.3
./configure --enable-syslog=1 --enable-maildropmysql --with-mysqlconfig=/etc/maildropmysql.config --without-db --enable-maildirquota

Bewore this would compile on my system, i need to install a few extra packages:

apt-get install libmysqlclient10-dev
apt-get install zlib1g-dev

Then compile and install your configured source:

make
make install-strip
make install-man

Add the lines below to /etc/postfix/main.cf to enable postfix to use maildrop as the transport.

virtual_transport = maildrop
maildrop_destination_recipient_limit = 1

Add then add the lines below to /etc/postfix/master.cf to enable the Maildrop delivery agent.

maildrop  unix  -     n     n     -     -     pipe
  flags=Rhu user=vmail argv=/usr/local/bin/maildrop -V 10 -w 75 -d ${recipient}

Note: the spaces preceeding the second line are important.

The V paramater determines logging verbosity. 10 is high, 5 is default. The d paramater tells Maildrop to run in devlivery mode and is required. The w paramater tells Maildrop to enable quota support, and to deposit warning messages in to a user's account once they exceed this percentage of their capacity. The first time Maildrop delivers to an account when quota support is enabled, it creates a file in the user's home directory called maildirsize. A record of the maildir's current size is kept here. The quota for the user's maildir is in our case is to be taken from the quota field in the mailbox table. Maildrop will respect the quota value when delivering a message. If the maildir size will exceed the size specified in your quota field once the message has been stored, then Maildrop will not deliver the message, and Postfix will return a temporary error code.

Use PHPMyAdmin to create a MySQL user for localhost only called maildrop, and grant that user select privileges to your mailbox table.

Then create the file /etc/maildropmysql.config with the details Maildrop will use to connect to MySQL.

hostname localhost
port 3306
database postfix
dbuser maildrop
dbpw maildrop
dbtable mailbox

uid_field username

default_uidnumber 1004
default_gidnumber 1004

<code>uid_numberfield uidnumber
gidnumber_field gidnumber</code>

homedirectory_field homedir
maildir_field maildir
quota_field quota
mailstatus_field active

When the account reaches the percentage capacity specified on the command line with the w paramater, an email warning message is copied from the template found at /usr/local/etc/quotawarnmsg in to the user's maildir. Create a template file of your own similar to the example shown below. If the location /usr/local/etc/ doesnt exist, just create it using the mkdir command.

From: postmaster@domain.tld
Reply-To: postmaster@domain.tld
To: User: user;
Subject: Mail Quota Warning - Account Usage at More Than 75%
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 7bit

Dear User,

Your mailbox on the server is now at more than 75% capacity.

So that you can continue to receive email, you need to remove some messages
from the mailbox. We suggest that you:

  * download old messages you want to keep to your "local folders"
  * empty your spam folder

Please note that if your account has insufficient spare capacity to hold
a message sent to you, then the message will be retured to it's sender.

Yours Sincerely,
  The Postmaster
  postmaster@domain.tld

You can define filtering rules either globally for all users whose mail is delivered via the maildrop transport at /etc/maildroprc, or on a user by user basis at var/vmail/domain.tld/username/.mailfilter. When delivering mail, Maildrop will first look for the global mail filter, and if it doesnt find that will then look for a mail filter file in the user's directory. If you want to use both then you can include the per-user file from the global file.

You need at least a basic mail filter file in order for Maildrop to know how to deliver messages. For now, create a global filtering file at /etc/maildroprc. The example below will deliver messages tagged as spam to the user's spam directory, creating it on the fly if necessary, or otherwise deliver the message to the user's default mail folder (INBOX). You can then elaborate upon this later, or instead switch to using per-user mail filter files.

Myself, I use a plugin for SquirrelMail called serversidefilter. It allows for users to manage their maildrop filtering rules through an easy web-based interface. Indeed the example below was generated by this plugin (thus the odd comments). See the SquirrelMail page for further details.

turn logging on
logfile "/var/log/maildrop.log"

MAILDIR=$HOME

Default mail directory

###Subject Rosebud INBOX.Rosebud m on off Contains if (/^Subject:.*Rosebud/:h) { to “$MAILDIR/.Rosebud” } ###Any Header X-Spam-Flag: Yes INBOX.Spam m on off Contains if (/.*X-Spam-Flag\: Yes/:h) { to “$MAILDIR/.Spam” }

import per-user filter rules

include $HOME/.mailfilter

You will need to set the permissions on the configuration and mail filter these files so mail drop can access them.

chown root:vmail /etc/maildropmysql.config
chown root:vmail /etc/maildroprc
chown root:vmail /usr/local/etc/quotawarnmsg

If you are going to later create per-user mail filter files then dont forget to set the permissions on these also:

chown vmail:vmail /var/vmail/domain.tld/user/.mailfilter
chmod 700 /var/vmail/domain.tld/user/.mailfilter

You can now go ahead and set your domains to use Maildrop as an aternative transport. The transport can be set on a domain by domain basis and so you can poick and choose from the virtual transport provided by Postfix, and the alternative maildrop: transport we have just setup. Specify virtual as the description for a domain in your MySQL domains table to use the Postfix Virtual transport, or specify maildrop: to have messages delivered by Maildrop. Note that quota and mail filtering support will only be available for domains that use Maildrop as a mail delivery agent.

To have Courier IMAP respect your quotas (noting that files can be uploaded via IMAP as well as delivered via Postfix/Maildrop), edit /etc/courier/imapd, and add quota to the IMAP_CAPABILITY variable as shown below:

IMAP_CAPABILITY="IMAP4rev1 CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT AUTH=CRAM-MD5 AUTH=CRAM-SHA1 QUOTA"

ClamAV

Install ClamAV

apt-get install clamav clamav-daemon

ClamAV should ask you necessary configuration optiuons when installed through APT. If not, you can run the command below to reconfigure:

dpkg-reconfigure clamav-daemon

You dont need ClamAV to decompose youe MINE, ZIP, TAR etc, Amavis does this for you and does it better. To work around an issue with clamav not running as root, you will at least need to manually add the line below to /etc/clamav/clamav.conf. Also when promoted add clamav to the clamav and amavis group. This fixes the “cannot connect to socket” error message.

AllowSupplementaryGroups

Razor

Install Razor

apt-get install razor

SpamAssassin

Install SpamAssasin:

apt-get install spamassassin

You can configure custom Spam Assassin rules at /etc/mail/spamassassin/local.cf, but the default configuration will be ok in many cases. AmavisNew

Install the decompressors Amavisd-New will use:

apt-get install zoo lha unarj unzip lzop unrar

Install Amavisd-New itself:

apt-get install amavisd-new

Amavisd-New requires that a number of Perl modules be installed. We use CPAN for this:

perl -MCPAN -e shell
cpan> install MD5
cpan> install Compress::Zlib
cpan> install Archive::Tar
cpan> install Archive::Zip
cpan> install IO::Stringy
cpan> install Mail::Internet
cpan> install Net::Server
cpan> install Convert::TNEF
cpan> install Convert::UUlib
cpan> install MIME::Base64
cpan> install MIME::Parser
cpan> install Net::SMTP
cpan> install Digest::MD5
cpan> install Time::HiRes
cpan> install Unix::Syslog
cpan> q

Enable support in postfix by adding the lines shown below to your /etc/postfix/main.cf file:

Send all email through Amavis (leave it out if you don't want amavis)

content_filter = smtp-amavis:[127.0.0.1]:10024

Then edit the /etc/postfix/master.cf and append the lines shown below to the file, to add the according amavis service:

For Amavis

smtp-amavis unix - - n - 2 smtp

  1. o smtp_data_done_timeout=1200
  2. o disable_dns_lookups=yes
For Amavis
  127.0.0.1:10025 inet n - n - - smtpd
  -o content_filter=
  -o local_recipient_maps=
  -o relay_recipient_maps=
  -o smtpd_restriction_classes=
  -o smtpd_client_restrictions=
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks=127.0.0.0/8
  -o strict_rfc821_envelopes=yes

Amavisd-New is configured at /etc/amavis/amavisd.conf. It has one of those very verbose configuration files full of settings that everyone will want to set differently. Probably the best thing to do is to read through the while thing, adjusting settings as required. A few of the things I changed are detailed below. Basic Settings

Change the $mydomain setting to your domain. SQL Lookups

The @lookup_sql_dsn setting controls access to the SQL server. Its syntax is (dsn,user,passw). Set this so that Amavisd-New can lookup settings from a SQL database. See the relevant plugin in the Squirrel Mail section for an appropriate DB schema and web-based interface. Sender Notifications Admin Notifivations

Restart Amavisd-New in debug mode. After a few seconds you will see all sorts of feedback on the console - check for errors etc.

/etc/init.d/amavis stop
/usr/sbin/amavisd-new debug

If everything looks ok then restart Amavisd-New as normal:

/etc/init.d/amavis restart

Squirrel Mail

Create a working directory, download Squirrelmail to it and extract:

mkdir /root/squirrelmail
wget http://...
tar xzvf squirrelmail.tar

Copy Squirrelmail to your web root:

cp -R squirrelmail /var/www/

Set permissions

cd /var/www/
chown root:www-data squirrelmail
cd squirrelmail
chown -R root:www-data *
chmod -R 700 *
chown -R www-data:www-data data

Create a directory to store your attachments in and set it's permissions:

mkdir attachments
chown -R root:www-data data
chmod -R 755 attachments

Configure Squirrelmail by running the configure script:

/var/www/squirrelmail/config/conf.pl

Set the attachment directory to the path of the one you created.

Set the default folder prefix to (the dot is important):

Inbox.

Squirrelmail Plugins Squirelmail Plugin - Quota Usage Squirelmail Plugin - Compatibility

Download and extract:

mkdir /root/squirrelmail_compatibility
cd /root/squirrelmail_compatibility
wget http://...
tar xzvf compatibility.tar

Install:

cp -R compatibility /usr/share/squirrelmail/plugins

Run the Squirrelmail configure secript and enable the plugin:

/var/www/squirrelmail/config/conf.pl

Squirelmail Plugin - Server Side Filter

Download and install plugin:

mkdir /root/squirrelmail_serversidefilter
cd /root/squirrelmail_serversidefilter
wget http://...
tar xzvf serversidefilter-1.42.tar
cp -R serversidefilter /usr/share/squirrelmail/plugins
chown -R root:www-data /usr/local/squirrelmail/plugins/serversidefilter/*.*

Some packages are required in order to compile:

apt-get install comerr-dev libcomerr2 libkadm55 libkrb5-dev libkrb53 libssl-dev

Edit /var/www/squirrelmail/plugins/serversidefilter/script/Makefile:

- Update path setting looking for c-client libs in /usr/lib to show /usr/local/include - Update path to c-client mail.h to show /usr/local/include

Compile and test:

make
make test

Run the Squirrelmail configure secript and enable the plugin:

/var/www/squirrelmail/config/conf.pl

Edit the make file as per the supplied instructions:

make
make test

Download uw-c-client from http://www.washington.edu/imap/. I couldnt get either of these two Debian packages to work: libc-client-dev / libc-client2002edebian.

wget http://....

Copy c-client dir to /usr/local/include

I needed to make sure cram-md5 was disabled in the Courier imap capability setting

apt-get install libc-client2001 libc-client2001-dev libc-client-ssl2001-dev
apt-get install libssl-dev libkrb53 comerr-dev libkadm55 libkrb5-dev
Squirelmail Plugin - Amavis-New + SQL + SpamAssassin + Quarantine

Create DB from the supplied MySQL schema.

Install the required PEAR modules:

apt-get install php4-pear

Extract the plugin to your Squirrelmail plugins directory.

tar zxfv amavisnewaql.gz /var/www/squirrelmail/plugins

Set permissions:

chown -R root:www-data amavisnewsql

Create a config file from the supplied default and edit as necessary:

cp config.php.dist config.php
ee config.php

In /etc/amavis/amavisd.conf enable sql lookups with by setting the @lookup_sql_dsn as to match your database settings.

Then change the default sql statement for $sql_select_white_black_list to the following:

$sql_select_white_black_list = 'SELECT wb FROM wblist'.
  ' WHERE (rid=?) AND (wblist.email IN (%k))'.
  ' ORDER BY wblist.priority DESC';

Enter the SquirrelMail configuration menus and enable the plugin:

/var/www/squirrelmail/config/conf.pl

Email Client Notes

Thunderbird Tweaks

How to have sub-folders (including the Drafts, Sent and Trash special folders) appear at root level rather than as sub-folders of Inbox

By default all folders are displayed as sub-folders of Inbox. This includes the Drafts, Sent and Trash special folders. While this is technically correct, many users may be more familiar and comfortable with folders appearing at root level, as a peer of Inbox.

Follow the procedure below To set Mozilla Thunderbird to display special folders in this way:

 1. Select the Tools menu; then
 2. select Account Settings from the menu; then
 3. select the appropriate email account from the list on the left; then
 4. select the Server Settings group of options from tghe list on the left; then
 5. click the Advanced button; then
 6. enter INBOX. in to the box labelled IMAP server directory (note that the dot on the end of INBOX. is important); then
 7. close the advanced dialogue by clicking the OK button; then
 8. close the account settings dialogue by clicking the OK button; then
 9. restart Mozilla Thunderbird.

Your folders should now appear at root level as peers of the Inbox folder, rather then as children of Inbox. Be sure to make this change to any other client's you use to access this account to avoid confusing folders. How to check all sub-folders for new messages

By default Mozilla Thunderbird checks only the Inbox of IMAP accounts for new messages, and not any sub-folders. If you are organising your mail in to sub-folders manually, or using client-side filtering rules setup within your Thunderbird client then this is sufficient, as all new mail is initially recieved in to the Inbox and stored here until it is moved by the client.

However, if you are using server side filtering rules then new messages may be recieved directly in to one of your sub-folders. In this circumstance it is important that the email client check all of your account's sub-folders for new messages, or else you may never know they are there without manually clicking through folders and checking for new messages.

There are two ways to have Mozilla Thunderbird check sub-folders for new messages: How to set Thunderbird to check sub-folders for new messages on a per-folder basis

To have Mozilla Thunderbird check specified sub-folders for new messages on startup and subsequent checks, right click the appropriate folder and select Properties from the contextual menu. Check the Check this folder for new messages checkbox, and OK out of the dialogue box. How to globally set Thunderbird to check sub-folders for new messages

To globally set Mozilla Thunderbird to check all sub-folders for new messages, we need to create a simple file within your profile directory, or add a couple of lines to that file if it already exists. The profile folder is where Thunderbird saves all your settings and refers to a location on your hard drive.

On Windows 2000/XP, the path is usually %AppData%\Thunderbird\Profiles\default\xxxxxxxx.slt\, where xxxxxxxx is a random string of 8 characters. Just browse to C:\Documents and Settings\[User Name]\Application Data\Thunderbird\Profiles\ and the rest should be obvious.

On Windows 95/98/Me, the path is usually C:\WINDOWS\Application Data\Thunderbird\Profiles\default\xxxxxxxx.slt\.

On Linux, the path is usually ~/.thunderbird/default/xxxxxxxx.slt.

On MacOS X, the path is usually ~/Library/Thunderbird/Profiles/default/xxxxxxxx.slt.

Once you have found your profile folder check for a file called user.js. If you dont see the file just create it. Then add the lines shown below to the end of the file:

// Download mail from all accounts on startup user_pref(“mail.check_all_imap_folders_for_new”, true);

Then restart Mozilla Thunderbird. Next time it checks your account for mail, it should check all the sub-folders. Where a folder contains new messages, you should see the number to the right of the folder indicating that there are unread messages in the folder. Further Reference

Mozilla Thunderbird Help, FAQs, Tips & Tricks Outlook Express Tweaks How to have sub-folders (including the Drafts, Sent and Trash special folders) appear at root level rather than as sub-folders of Inbox

By default all folders are displayed as sub-folders of Inbox. This includes the Drafts, Sent and Trash special folders. While this is technically correct, many users may be more familiar and comfortable with folders appearing at root level, as a peer of Inbox.

Follow the procedure below To set Mozilla Thunderbird to display special folders in this way:

 1. Select the Tools menu; then
 2. select Accounts from the menu; then
 3. select the Mail tab; then
 4. click to highlight the appropriate email account from the list; then
 5. click the properties button on the right; then
 6. select the IMAP tab on the new dialogue box; then
 7. enter INBOX. in to the box labelled Root folder path (note that the dot on the end of INBOX. is important); then
 8. Close the account properties dialogue box by clicking the OK button
 9. Close the Internet Accounts dialogue box by clicking the OK button
10. Confirm to fresh the folder list.

Your folders should now appear at root level as peers of the Inbox folder, rather then as children of Inbox. Be sure to make this change to any other client's you use to access this account to avoid confusing folders. How to check all sub-folders for new messages

Outlook Express is set to check all sub-folders by default. Self Signed Security Certificates

It appears it is not possible to have Outlook Express permenantly accept a self signed security certificate. Mixing Email Clients

IMAP email accounts are preferable to POP3 email accounts when it is desireable to access an account from more than one location. However due to differences in the way different email clients handle IMAP, it is important to give some prior thought to how your email is to be accessed in each location.

Generally speaking we reccoment that you use the same email client to access your account from all locations. You can also use the SquirrelMail web mail system of course.

If you choose to mix the use of Outlook Express and Thunderbird then you may need to tweak various settings in order to have the two coexist hapilly. A few hints can be found below:

  • How messages are deleted. Thunderbird and Squirrel Mail both by default moved deleted messages to the trash folder. Outlook Express on the other hand marks messages for deletion using the deleted flag. Messages then remain within the same folder, but are displayed differently and can later be expunged as a seperate process.
  • The names of special folders. Thunderbird and Squirrel Mail both use Drafts, Sent and Trash. Outlook uses Drafts and Sent Items, and by default does not have a Trash folder. We reccomend you stick to the special folder naming schema used by Thunderbird.

Mail Reports

enter the CPAN interface:

perl -MCPAN -e shell

install the Date::Calc perl module

~ install Date::Calc ~ quit

install the pflogsumm.pl utility

cd /root
wget http://jimsun.linxnet.com/downloads/pflogsumm-1.1.0.tar.gz
tar zxvf pflogsumm-1.1.0.tar.gz
cd pflogsumm-1.1.0
cp pflogsumm.pl /usr/bin
chown bin:bin /usr/bin/pflogsumm.pl
chmod 755 /usr/bin/pflogsumm.pl

and also install the pflogsumm.pl man pages

cp pflogsumm.1 /usr/local/man/man1/pflogsumm.1
chown bin:bin /usr/local/man/man1/pflogsumm.1
chmod 644 /usr/local/man/man1/pflogsumm.1

enter the crontab interface to setup the cron job to email you the reports

crontab -e

add the two lines below:

10 3 * * * /usr/bin/pflogsumm.pl -d yesterday /var/log/mail.log 2>&1 |/usr/bin/mail -s "Postfix daily mail summary" postmaster
10 3 * * 0 /usr/bin/pflogsumm.pl /var/log/mail.log 2>&1 |/usr/bin/mail -s "Postfix WEEKLY mail summary" postmaster

Mailgrep Utility

Download the mailgrep.pl and openlogfile.pl files, copy them to /usr/bin, and set them executable:

mkdir /root/mailgrep
cd /root/mailgrep
wget http://www.besy.co.uk/projects/debian/mailserver/mailgrep.pl
mv mailgrep.pl /usr/bin/mailgrep.pl
chmod +x /usr/bin/mailgrep.pl
wget http://www.besy.co.uk/projects/debian/mailserver/openlogfile.pl
mv openlogfile.pl /usr/bin/openlogfile.pl
chmod +x /usr/bin/openlogfile.pl
perl -MCPAN -e shell

~ install File::MMagic ~ quit

mailgrep.pl
mailgrep.pl -s someuser@somedomain.com /var/log/mail.log

* Note: our mail log is not “mail.log” (the default for this tool), so we need to type the correct mail log path and file name - /var/log/maillog -when we use it. E.g., to search for all mail log entries dealing with mail to or from “someuser@somedomain.com”, we would use: . To see what mailgrep.pl does for you, compare the output of the above to grep -i someuser@somedomain.com /var/log/maillog. Mailgraph

Install Mailgraph:

apt-get install mailgraph

Create a configuration file by copying the default one:

cp /etc/default/mailgraph /etc/mailgraph

Edit the Mailgraph statup script in /etc/init.d/mailgraph and change path to the config file to point to the one you created at /etc/mailgraph.

Edit /etc/mailgraph, and point it to /var/log/syslog.

Edit /etc/amavis/amavisd.conf and check that $do_syslog is set to true.

Resart Mailgraph

/etc/init.d/mailgraph restart

Web-based stats should then be availible at http://your.domain.com/cgi-bin/mailgraph.cgi. Postal

Postal is an SMTP client that can be used to load test your mail server. It can send lots of emails through your system, allowing you to control the rate per minuite, and number of connections used.

Postal can be run either on the local machine or on a remote machine. If your mail server is going to be accepting incoming connections across the Internet than you should do so when load testing, rather than just running Postal from another machine on your LAN. The reason is that when a connection is made across a slower link it will need to remain open for longer, and so will consume more resources. Obviously you need to install Postal on an appropriate computer.

Install Postal:

apt-get install postal

The command below will execute the Postal program. The respective meaning of the parameters is; use two processes; with a maximum of 2 messages per connection; at a rate of 10 messages per minuite; and with nought percent of connections using SSL encryption. Then follows the IP address or hostname to make the connections to, then the path to a plain text file containing the recipient email addresses the messages should be sent to, and then a dash to specify not to bother with the optional list of variations to apply to those recipient addresses.

postal -p 2 -c 2 -r 10 -s 0 -a localhost /root/postal/list.txt -

For further information read the MAN page:

man postal

Performance Tweaks

  • Set filesystem mount not to record date/time (affect trash cycling?)
  • Use asyncronous logging in Postfix
  • Mount postfix spool on seperate HD
  • Set maildrop not to log by default
  • Set amavis to log less verbosely

Discussion

Enter your comment:

Subscribe to the RSS feed for Andy's Debian HOWTOs

Article from Andy's Debian HOWTOs (http://www.besy.co.uk/debian/debian)

 
debian/debian_woody_virtual_mail_server_howto.txt · Last modified: 2008/08/01 22:56 (external edit) · [Old revisions]
Recent changes RSS feed Powered by Debian Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki