Parent Category: Tutorials
Hits: 17928

This tutorial will show you how you can setup a mail server with Postfix/ Postfixadmin / PostgreSQL / Courier / Squirrelmail / SpamAssassin / ClamAV on Debian.

First step is to install Debian
No surprise there... I installed via netboot, and ended up with a fairly minimal
setup. You'll probably do it a different way. I told it to install as a 'mail server' and a
'web server'. The 'mail server' option was probably a mistake as it installs uw-imapd
and exim, neither of which I wanted/needed.

You probably want to install openssh-server and molly-guard :)
apt-get install postfix postfix-pgsql

(Or postfix-mysql if you're going to use that instead)

I selected the Internet Site configuration when asked to pick a configuration.

In order to have slightly more recent versions of a few packages (PHP5, ClamAV and
PostgreSQL mainly), I added the following into my /etc/apt/sources.list file :
deb stable all
deb etch-backports main contrib
deb etch/volatile main contrib non-free
Install PostgreSQL

I installed PostgreSQL 8.2 from ...
apt-get install -t etch-backports postgresql-8.2

(Note: there is no requirement on using v8.2, but I'm under the impression that
it's faster than previous versions). I'd suggest you use at least v8.1 (in Etch) from
a maintenance point of view.
Install PHP5

I always install the suhosin extension to PHP in the hope it will provide extra security.
APC (Alternative PHP Cache) is also installed in the expectation it will improve performance.
apt-get install php5 libapache2-mod-php5 php5-pgsql php5-suhosin php5-apc php-pear

(The above packages nearly all come from

Install Postfixadmin

Although I have created .deb for Postfixadmin; at the time of writing, v2.2.0 hasn't been
released; so I instal Postfixadmin from SVN. Hopefully, we'll release version 2.2.0 of
Postfixadmin sometime soon, and you will want to see this page to download it.
cd /var/www
svn co postfixadmin

If you now hit http://your.server/postfixadmin you should see a slightly useful 'welcome'
screen, follow the link through to the 'setup.php' page. And you should get some sort
of instant gratification that at least something works :) (although some of the checks will fail)
Setting up PostgreSQL (or MySQL)

As postfixadmin stores all of it's configuration within a database, we need to setup the
database before we can do much further. You may find that phppgadmin or phpmyadmin
help with this.

Basically - create a user (e.g. 'postfix') and a database (e.g. 'postfix'). The user should own
the database. Ensure there's a password set on the user.

If security is a concern, you should probably have a user that is 'read-only' which is used
by postfix (as it only ever queries the DB) while postfixadmin will need a read-write user account.

If you're using PostgreSQL, the following shows what I typed in from a shell (all lines
containing a $ or #)on the server when logged in as root
mail:~# su - postgres
postgres@mail:~$ psql template1
Welcome to psql 8.2.4, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

template1=# CREATE USER postfix WITH PASSWORD 'complexpassword';
template1=# \q

If, like me, you are useless at picking passwords, try using pwgen
Load the Postfixadmin Database Schema into your database

As of subversion revision 328, the setup.php script should automatically create the
database structure for you. If you are using an older version of PostfixAdmin you'll need
to do the following :
cd /var/www/postfixadmin
psql -U postfix -h localhost postfix < DATABASE_PGSQL.TXT

This may spew out a few errors about roles that don't exist, but it should work
Configuration of Postfixadmin

Edit /var/www/postfixadmin/ in your favourite editor (vi[m]).
$CONF['configured'] = false;

$CONF['configured'] = true;
$CONF['postfix_admin_url'] = '';

$CONF['postfix_admin_url'] = 'http://your.server/postfixadmin';
$CONF['database_type'] = 'mysql';

to pgsql (assuming you want PostgreSQL!)
Change the other database parameters to match what you used above.

You'll want to change other parameters, but they're not normally essential

Once your file has the right database credentials, and you refresh
http://your.server/postfixadmin/setup.php you should some output indicating that the
database tables have been created, and also see a dialog box to Create the superadmin
account. You should treat these details a bit like the 'root' password for a Unix server.
This user will be able to add/remove/edit any domains/users/aliases etc.

Anyway, choose an admin account, this could be (for example) This email address is being protected from spambots. You need JavaScript enabled to view it.

Submitting this form, successfully, should result in the page giving you a message like
'Admin has been added!'

Delete setup.php (rm setup.php or mv setup.php setup.php.blah)
Configuring Postfix

This always seems to be the bit that causes others trouble....
New configuration files
In my world, the following go in /etc/postfix/pgsql

You'll need to change the xxxxxx's to appropriate values

(Who we relay mail for (as a backup mx))
user = postfix
password = xxxxxxx
dbname = postfix
hosts = localhost
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = true

(Think: /etc/aliases or similar)
user = postfix
password = xxxxxxxx
dbname = postfix
hosts = localhost
query = SELECT goto FROM alias WHERE address='%s' AND active = true

(Domains we accept mail for...)
user = postfix
password = xxxxxxxx
dbname = postfix
hosts = localhost
query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = false
AND active = true

(Only used if you're checking quota etc)
user = postfix
password = xxxxxxx
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username = '%s'

(What mailboxes exist that we can deliver to)
user = postfix
password = xxxxxxxx
dbname = postfix
hosts = localhost
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true changes

Add in the following :
# All virtual mailboxes live somewhere in here ..
virtual_mailbox_base = /var/mail/vmail

# The (virtual) domains we accept mail for
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/pgsql/

# Lookup mailbox location, uid and gid based on email address received.
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/pgsql/
virtual_uid_maps = static:1001
virtual_gid_maps = static:8

virtual_alias_maps = proxy:pgsql:/etc/postfix/pgsql/

relay_domains = proxy:pgsql:/etc/postfix/pgsql/
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps


adduser vmail -g mail -uid 1001 -d /var/mail/vmail/
chown -R vmail:mail /var/mail/vmail



Postfix SMTP Auth Support

If your users are likely to be trying to send mail through your mail server when they
are not on a trusted network, you'll need to add this to /etc/postfix/
smtpd_sasl_authenticated_header = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
And in /etc/postfix/sasl/smtpd.conf put the following :
pwcheck_method: saslauthd
saslauthd_path: /var/run/saslauthd/mux
log_level: 3
mech_list: PLAIN LOGIN

(As you can see, we'll be using SASL as a backend for authentication)

Thankfully the SASL package works a bit better under Etch than it did under Sarge/etc.
apt-get install sasl2-bin

Edit /etc/default/saslauthd so it has :
OPTIONS="-r -c -O localhost -m /var/spool/postfix/var/run/saslauthd"


To set the run directory using dpkg-statoverride, run this command as root:
dpkg-statoverride --add root sasl 710 /var/spool/postfix/var/run/saslauthd

Finally, to add the postfix user to the sasl group:
adduser postfix sasl



You'll need to mkdir -p /var/spool/postfix/var/run/saslauthd before SASL will start

(One day, I might change to use the pam_sql module; as this would remove unnecessary
IMAP logins... )
apt-get install courier-authdaemon courier-imap courier-imap-ssl courier-pop courier-pop-ssl
Configuring Courier's authdaemon

You'll need to edit /etc/courier/authpgsqlrc (or authmysqlrc if using MySQL)
PGSQL_HOST localhost
PGSQL_HOME_FIELD '/var/mail/vmail'

And also edit /etc/courier/authdaemonrc, and set authmodulelist="authpgsql" (or authmysql
if you're using MySQL)

If you now create a user in a test domain on postfixadmin, you should be able to connect to
your mail server successfully, and receive mail
Basic Testing (pop3)

Assuming you've created a domain, and a user within that domain from Postfixadmin, you
should be able to do something like the following :
mail:~# tail -f /var/log/mail.log &
mail:~# echo 'test email' | mail This email address is being protected from spambots. You need JavaScript enabled to view it.
Dec 6 22:31:56 mail postfix/pickup[11888]: A811A2B10063: uid=0 from=<root>
Dec 6 22:31:56 mail postfix/cleanup[11897]: A811A2B10063: message-id=<This email address is being protected from spambots. You need JavaScript enabled to view it.>
Dec 6 22:31:56 mail postfix/qmgr[11889]: A811A2B10063: from=<root>, size=297,
nrcpt=1 (queue active)
Dec 6 22:31:56 mail postfix/virtual[11902]: A811A2B10063: to=<This email address is being protected from spambots. You need JavaScript enabled to view it.>,
relay=virtual, delay=0.11, delays=0.05/0.04/0/0.02, dsn=2.0.0, status=sent (delivered
to maildir)
Dec 6 22:31:56 mail postfix/qmgr[11889]: A811A2B10063: removed

Additionally, if you now look in /var/mail/vmail, you should see a folder called This email address is being protected from spambots. You need JavaScript enabled to view it.'.
No guesses should be needed to figure out what this contains!

Squirrelmail is a mature web based mail client. It's been around for some time now, and
thankfully plugins exist for a number of additional "features". As your author patched up
the squirrelmail postfixadmin plugin, he's going to take a small amount of time <plug>it.
apt-get install squirrelmail

Squirrelmail-postfixadmin install:

dpkg -i squirrelmail-postfixadmin_2.1.0-1_all.deb

svn co -r35

mv trunk/ /usr/share/squirrelmail/plugins/squirrelmail-postfixadmin

cd /usr/share/squirrelmail/plugins/squirrelmail-postfixadmin

mv config.php.sample config.php

Edit /etc/squirrelmail/plugins/postfixadmin-config.php - use the same settings from Postfixadmin
pear install MDB2
pear install MDB2#pgsql (or MDB2#mysql)
Run squirrelmail-configure and enable the Postfixadmin plugin

Squirrelmail should be accessible at http://youserver/squirrelmail by default.

This is easiest to integrate via Amavis. You should get ClamAV from, or Debian
volatile via apt-get. Relying on the 'default' clamav shipped with etch is probably not a good
idea (and ClamAV will also moan when it tries to update it's definitions list).
apt-get install amavisd-new clamav spamassassin

You'll want to edit

In my case, it looks a bit like :
use strict;

# Place your configuration directives here. They will override those in
# earlier files.
# See /usr/share/doc/amavisd-new/ for documentation and examples of
# the directives you can use in this file

chomp($myhostname = `hostname`);

$forward_method = 'smtp:';
# Where to submit notifications
$notify_method = $forward_method;

# Net::Server Pre-forking settings; note max_servers should match Postfix's
$max_servers = 5;
$max_requests = 10;
$child_timeout = 5*60; # abort child if it takes longer than x seconds to complete.

# MTA specific settings...
$relayhost_is_client = 0;
$insert_received_line = 1;

$inet_socket_bind = '';
@inet_acl = qw ( );

# How we handle viruses and spam; options being discard, bounce or pass.
$final_virus_destiny = D_DISCARD;
$final_banned_destiny = D_BOUNCE;
$final_spam_destiny = D_PASS;
$final_bad_header_destiny = D_BOUNCE;

# Headers..
$X_HEADER_TAG = 'X-Virus-Scanned';
$X_HEADER_LINE = "by Amavis+SpamAssassin+ClamAV and more at $mydomain";

$remove_existing_x_scanned_headers = 1;
$remove_existing_spam_headers = 1;

$sa_tag_level_deflt = -99.0; # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 5.0;
$sa_kill_level_deflt = 5.0; # triggers spam evasive actions

$recipient_delimiter = '+';
$replace_existing_extension = 1;
$localpart_is_case_sensitive = 0;

# SpamAssassin settings
$sa_timeout = 30;
$sa_auto_whitelist = 1;
$sa_local_tests_only = 0;
$sa_spam_modifies_subj = 1;
$sa_spam_subject_tag = '*** SPAM *** ';
$sa_spam_report_header = 1;
$first_infected_stops_scan = 1;
$sa_debug = 1;

$LOGFILE = "/var/log/amavis.log";

@local_domains_acl = ('.');
#------------ Do not modify anything below this line -------------
1; # insure a defined return

The above configures Amavis to :
Scan and label Spam for all mail that goes through the server (And not just for some specified
domains - see @local_domains_acl)
Forward scanned mail to for delivery by Postfix
Listen for mail (from Postfix) on
Discard Viruses
Remove any existing anti-virus tags etc (as these will be from some.other.system)
If SpamAssassin scores more than 5.0, then rewrite the subject etc

Some notes:
SpamAssassin does not need to run via the SpamC/SpamD mechanism - Amavis handles this
all internally
Amavis appears to ignore most, if not all, settings you would otherwise set for SpamAssassin in
e.g. /etc/spamassassin/
When I initially started using Amavis it seemed to be a bit clueless when it came to listening and
delivering on the same IP address. Perhaps I did something wrong, but nevertheless, this is why
it listens on a different IP address ( to the one it delivers to ( You don't need
to do anything to setup on a Linux box.
Amavis / Postfix Integration
Edit /etc/postfix/
amavis unix - - - - 5 smtp
-o smtp_data_done_timeout=5000
-o smtp_send_xforward_command=yes
-o receive_override_options=no_address_mappings

# change or remove the existing smtp definition.
smtp inet n - - - 12 smtpd
-o content_filter=amavis:[]:10024

# where mail is re-injected back in by Amavis after it's
# done it's stuff. inet n - - - - smtpd
-o smtpd_autorized_xforward_hosts=
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,

Then reload Postfix, make sure Amavis and ClamAV are running (/etc/init.d/amavis start or
/etc/init.d/clamav-daemon ) and it should work.


We use Hosting and VPS Hosting, from:

We like and trust them.

Good prices, high security.