Andy's Debian Sarge Virtual Mail Server Howto: Part One

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

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

Introduction

This is the second revision of my Debian Virtual Domain Mail Server howto.

The howto describes the setup of a virtual domain/user mail server based on Debian Sarge, and using Postfix, mySQL Courier IMAP & POP3, Maildrop and Squirrel Mail.

Click to open larger image in to new browser window

system diagram

Our system supports:

  • Virtual domains and users
    No need for real unix users, full email address used as username.
  • Authenticated SMTP
    Clients autnenticate using a username and password for SMTP relay of outgoing mail.
  • TLS (SSL) 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
  • Content filtering
    Effective filtering of viruses, spam and phishing emails.
  • Easy web-based administration

Our Configuration is as follows:

  • Debian 3.1 Sarge
  • Postfix
  • mySQL
  • Maildrop
  • Amavis
  • Spam Assassin
  • Cyrus SASL2
  • Courier POP3
  • Courier IMAP
  • Squirrel Mail
  • Postfix Admin
  • Apache 1.3
  • PHP 4
  • Shorewall

Linux Email: Setup and Run a Small Office Email Server Using Postfix, Courier, ProcMail, SquirrelMail, ClamAV and SpamAssassin


Contents

Hardware

If you decide to run this setup on an office or home server then you can use whatever you have available to host a few tens of users. If you need to handle very high loads with thousands of users then you need good hardware. Lots of memory and a fast disk system are particularly important. The usual Debian minimum system specifications apply.

Virtual Servers

If you would like to run this setup on a remotely hosted server then I highly recommend a Bytemark Hosting virtual machine. And they will donate to the Debian project when you use this link :)

Bytemark Hosting

Installing Debian

Download the Debian Sarge net-installer ISO and burn it to a CD. The software in Woody is too out of date for our needs, and at time of writing Sarge should become stable very soon.

Reboot off the CD, checking your BIOS is set to boot from the CD drive as you do.

The Installer

Proceed through the installer and base-configuration. Its pretty simple. Select your nearest Mirror for use with the apt system. Dont select any packages in tasksel or dselect; we want to start with a clean system.

Partitioning

Sarge's partitioning tool can setup your partitions for you, but you might want to consider the notes below before finalising your layout.

/var

There is a good argument for having /var on a seperate partition. These files change a lot, and partiticly your log files may grow very large and very fast. Storing these on a seperate partition helps protect against failures as the result of unckeced log files from consuming all available free space.

/swap

Although its a good idea to have some swap space to hand, remeber that if you are using swap you really should add some more physical memory; swapping to disk will seriously hurt the capacity of your system.

/var/vmail

You will probably want a seperate partition for your Maildir store. When choosing a size for this partition, consider the number of users you will support and the storage quota you will set for each user. Try to allow some room for growth.

The XFS file system is recommended for use here, since I understand that is more efficient at storing many small files, and that it is a well tested, high performance file system.

Post Installation

Install the editor of your choice. Here, I use ee since it is easy for novices. Alternatively vi will already be installed.

# aptitude install ee

Install SSH

# aptitude install ssh

Edit the SSH configuration to suit your needs. Ideally restrict connections to your IP address, unless you are on a dynamic IP or something. Denying root logins and restricting logins to specific users helps protect against attacks on SSH.

# ee /etc/ssh/sshd_config
PermitRootLogin no
AllowUsers username

Restart SSH

# /etc/init.d/ssh restart

Install some miscellaneous utilities:

# aptitude install iptraf traceroute whois nmap dnsutils wget ftp bzip2 unzip zip ntp-simple ntpdate postal logwatch less

Firewall

We use the IPTables module for the 2.4 series kernel to firewall the system, and Shorewall to manage firewall rules. Install as shown below:

# aptitude install shorewall

Download the example for one interface, or the two interface example if the system will also function as a gateway.

Untar and copy the example configuration files. Edit each file according to the instructions in /usr/share/shorewall/doc, or on the Shorewall website, and the comments in the configuration files themselves. Often you will only need to adjust the rules file. When creating rules, checkout the pre-defined actions listed in /usr/share/shorewall/actions.std.

# wget http://www1.shorewall.net/pub/shorewall/Samples/samples-2.2.0/one-interface.tgz
# tar zxvf one-interface.tgz
# cp one-interface/* /etc/shorewall
# ee /etc/shorewall/interfaces
# ee /etc/shorewall/policy
# ee /etc/shorewall/zones
# ee /etc/shorewall/rules (see /usr/share/shorewall/actions.std)

Finally enable Shorewall and start the script.

# ee /etc/default/shorewall
# shorewall start

Apache

Intall Apache and check its configuration file.

# aptitude install apache apache-ssl
# ee /etc/apache/httpd.conf
# ee /etc/apache-ssl/httpd.conf

You should now be able to access the web-server through your browser.

mySQL

Install mySQL

# aptitude install mysql-server mysql-doc

Set a root password

# mysqladmin -u root password "newpwd"

Edit the configuration file. Enable logging for diagnostic purposes. High volume sites may want to increase max connections and later disable mySQL logging to reduce disk activity.

# ee /etc/mysql/my.cnf
[mysqld]
set-variable=max_connections=250
#log    = /var/log/mysql.log
log   = /var/log/mysql/mysql.log

Create the logfiles and set their permissions.

# touch /var/log/mysql/mysql.log
# touch /var/log/mysql/mysql.err
# touch /var/log/mysql/mysql-slow.log
# chown mysql:adm /var/log/mysql/mysql.log
# chown mysql:adm /var/log/mysql/mysql.err
# chown mysql:adm /var/log/mysql/mysql-slow.log

Restart MySQL

# /etc/init.d/mysql restart

You should now be able to connect to your mySQL server using the mySQL client.

# mysql -u root -p

Create the Database

Connect to the mySQL server using the mySQL client, entering your root password when prompted.

# mysql -u root -p

Copy paste in the SQL code below to create the database structure, then quit. Note that this schema is a modified version of the one included with Postfix Admin. I have added tables to support relocated maps and sasl authentication.

#
# Postfix Admin
# by Mischa Peters 
# Copyright (c) 2002 - 2005 High5!
# License Info: http://www.postfixadmin.com/?file=LICENSE.TXT
#

# This is the complete MySQL database structure for Postfix Admin.
# If you are installing from scratch you can use this file otherwise you
# need to use the TABLE_CHANGES.TXT or TABLE_BACKUP_MX.TXT that comes with Postfix Admin.
#
# There are 2 entries for a database user in the file.
# One you can use for Postfix and one for Postfix Admin.
#
# If you run this file twice (2x) you will get an error on the user creation in MySQL.
# To go around this you can either comment the lines below "USE MySQL" until "USE postfix".
# Or you can remove the users from the database and run it again.
#
# You can create the database from the shell with:
#
# mysql -u root [-p] < DATABASE_MYSQL.TXT

#
# Postfix / MySQL
#
USE mysql;
# Postfix user & password
INSERT INTO user (Host, User, Password) VALUES ('localhost','postfix',password('postfix'));
INSERT INTO db (Host, Db, User, Select_priv) VALUES ('localhost','postfix','postfix','Y');
# Postfix Admin user & password
INSERT INTO user (Host, User, Password) VALUES ('localhost','postfixadmin',password('postfixadmin'));
INSERT INTO db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv) VALUES ('localhost', 'postfix', 'postfixadmin', 'Y', 'Y', 'Y', 'Y');
FLUSH PRIVILEGES;
GRANT USAGE ON postfix.* TO postfix@localhost;
GRANT SELECT, INSERT, DELETE, UPDATE ON postfix.* TO postfix@localhost;
GRANT USAGE ON postfix.* TO postfixadmin@localhost;
GRANT SELECT, INSERT, DELETE, UPDATE ON postfix.* TO postfixadmin@localhost;
CREATE DATABASE postfix;
USE postfix;

#
# 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 (
  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  (address),
  KEY address (address)
) 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 '0',
  `mailboxes` int(10) NOT NULL default '0',
  `maxquota` int(10) NOT NULL default '0',
  `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` (`domain`)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Domains' AUTO_INCREMENT=2 ;

#
# 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,
  `username` varchar(255) NOT NULL default '',
  `password` varchar(255) NOT NULL default '',
  `name` varchar(255) NOT NULL default '',
  `maildir` varchar(255) NOT NULL default '',
  `quota` int(10) NOT NULL default '0',
  `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 `username` (`username`)
) TYPE=MyISAM COMMENT='Postfix Admin - Virtual Mailboxes' AUTO_INCREMENT=2 ;

#
# 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';

# Modified or added by Andy www.besy.co.uk

#
# Table structure for table `saslauth`
#

CREATE TABLE `saslauth` (
  `id` int(255) NOT NULL auto_increment,
  `username` varchar(50) NOT NULL default '',
  `password` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  KEY `username` (`username`)
) TYPE=MyISAM COMMENT='SASL Auth - Users' AUTO_INCREMENT=2 ;


#
# Table structure for table `relocated`
#

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;

PHP and PHPMyAdmin

Install the PHP to enable PHP support in Apache, the PHP mySQL module to enable mySQL support in PHP, the PHP4 pear library and the PHPMyAdmin tool.

# aptitude install php4 php4-mysql phpmyadmin php4-pear

You should now be able to access PHPMyAdmin through your browser at http://hostname.domain.tld/phpmyadmin.

I would suggest you use it to verify that your database permissions are correct and secure. Futher details can be found on the mySQL website. Particually, delete the anonymous users and check both root users have passwords set.

Postfix Admin

Postfix Admin is a web-based administration tool. We will use it to manage our database of virtual domains and users. Download and install Postfix admin. Installation instructions on available at high5.net, and in the tar file you download. My commands were as follows:

# cd /root
# wget http://high5.net/postfixadmin/postfixadmin-2.1.0.tgz
# tar zxvf postfixadmin-2.1.0.tgz
# mv postfixadmin-2.1.0 /usr/share/postfixadmin-2.1.0
# ln -s /usr/share/postfixadmin-2.1.0 /var/www/postfixadmin
# cp /usr/share/postfixadmin-2.1.0/config.inc.php.sample /usr/share/postfixadmin-2.1.0/config.inc.php
# ee /usr/share/postfixadmin-2.1.0/config.inc.php
# chown root:www-data /usr/share/postfixadmin-2.1.0 -R
# chmod 640 /usr/share/postfixadmin-2.1.0/*.*
# chmod 640 /usr/share/postfixadmin-2.1.0/ADDITIONS/*.*
# chmod 640 /usr/share/postfixadmin-2.1.0/VIRTUAL_VACATION/*.*
# chmod 640 /usr/share/postfixadmin-2.1.0/admin/*.*
# chmod 640 /usr/share/postfixadmin-2.1.0/media/images/*.*
# chmod 640 /usr/share/postfixadmin-2.1.0/languages/*.*
# chmod 640 /usr/share/postfixadmin-2.1.0/templates/*.*
# chmod 640 /usr/share/postfixadmin-2.1.0/users/*.*
# rm /usr/share/postfixadmin-2.1.0/motd.txt
# rm /usr/share/postfixadmin-2.1.0/motd-users.txt
# rm /usr/share/postfixadmin-2.1.0/motd-admin.txt
# rm /usr/share/postfixadmin-2.1.0/setup.php

You should now be able to access Postfix Admin through your browser at http://hostname.domain.tld/postfixadmin. Setup a test domain & account.

Unix User

You need a single real UNIX user to deliver mail as. Your mail store will be owned by this user. Create the user, group and home directory. If you have a seperate parition for your Maildir store, mount it at /var/vmail.

# groupadd vmail -g 1004
# useradd vmail -u 1004 -g 1004
# mkdir /var/vmail
# chown -R vmail:vmail /var/vmail
# chmod -R 700 /var/vmail

TODO: Explain that you could choose to use a user for each domain to seperate the ownership of mail on the file system.

Postfix

Postfix is a powerful and refined MTA. Its the obvious choice for our system. Install Postfix, allowing aptitude to remove exim as you go. We also install the SASL2 libraries to support authenticated SMTP connections, and the TLS library to support SMTP with SSL encryption.

# aptitude install postfix postfix-mysql postfix-tls libsasl2 libsasl2-modules-sql libsasl2-modules

Backup master.cf and create a new one as shown below. Please check the Postfix documentation in /usr/share/doc/postfix or on the Postfix website for an explanation of this file.

# cp /etc/postfix/master.cf /etc/postfix/master.cf~
# ee /etc/postfix/master.cf
#
# Postfix master process configuration file.  Each logical line
# describes how a Postfix daemon program should be run.
#
# A logical line starts with non-whitespace, non-comment text.
# Empty lines and whitespace-only lines are ignored, as are comment
# lines whose first non-whitespace character is a `#'.
# A line that starts with whitespace continues a logical line.
#
# The fields that make up each line are described below. A "-" field
# value requests that a default value be used for that field.
#
# Service: any name that is valid for the specified transport type
# (the next field).  With INET transports, a service is specified as
# host:port.  The host part (and colon) may be omitted. Either host
# or port may be given in symbolic form or in numeric form. Examples
# for the SMTP server:  localhost:smtp receives mail via the loopback
# interface only; 10025 receives mail on port 10025.
#
# Transport type: "inet" for Internet sockets, "unix" for UNIX-domain
# sockets, "fifo" for named pipes.
#
# Private: whether or not access is restricted to the mail system.
# Default is private service.  Internet (inet) sockets can't be private.
#
# Unprivileged: whether the service runs with root privileges or as
# the owner of the Postfix system (the owner name is controlled by the
# mail_owner configuration variable in the main.cf file). Only the
# pipe, virtual and local delivery daemons require privileges.
#
# Chroot: whether or not the service runs chrooted to the mail queue
# directory (pathname is controlled by the queue_directory configuration
# variable in the main.cf file). Presently, all Postfix daemons can run
# chrooted, except for the pipe, virtual and local delivery daemons.
# The proxymap server can run chrooted, but doing so defeats most of
# the purpose of having that service in the first place.
# The files in the examples/chroot-setup subdirectory describe how
# to set up a Postfix chroot environment for your type of machine.
#
# Wakeup time: automatically wake up the named service after the
# specified number of seconds. A ? at the end of the wakeup time
# field requests that wake up events be sent only to services that
# are actually being used.  Specify 0 for no wakeup. Presently, only
# the pickup, queue manager and flush daemons need a wakeup timer.
#
# Max procs: the maximum number of processes that may execute this
# service simultaneously. Default is to use a globally configurable
# limit (the default_process_limit configuration parameter in main.cf).
# Specify 0 for no process count limit.
#
# Command + args: the command to be executed. The command name is
# relative to the Postfix program directory (pathname is controlled by
# the daemon_directory configuration variable). Adding one or more
# -v options turns on verbose logging for that service; adding a -D
# option enables symbolic debugging (see the debugger_command variable
# in the main.cf configuration file). See individual command man pages
# for specific command-line options, if any.
#
# General main.cf options can be overridden for specific services.
# To override one or more main.cf options, specify them as arguments
# below, preceding each option by "-o".  There must be no whitespace
# in the option itself (separate multiple values for an option by
# commas).
#
# In order to use the "uucp" message tranport below, set up entries
# in the transport table.
#
# In order to use the "cyrus" message transport below, configure it
# in main.cf as the mailbox_transport.
#
# SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS.
# ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL.
#
# DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES.
#
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
smtp      inet  n       -       n       -       -       smtpd
#submission inet n      -       -       -       -       smtpd
# -o smtpd_etrn_restrictions=reject
#628      inet  n       -       -       -       -       qmqpd
pickup    fifo  n       -       -       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      fifo  n       -       -       300     1       qmgr
#qmgr     fifo  n       -       -       300     1       oqmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       -       -       0       bounce
defer     unix  -       -       -       -       0       bounce
trace     unix  -       -       -       -       0       bounce
verify    unix  -       -       -       -       1       verify
flush     unix  n       -       -       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
smtp      unix  -       -       -       -       -       smtp
relay     unix  -       -       -       -       -       smtp
#       -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq     unix  n       -       -       -       -       showq
error     unix  -       -       -       -       -       error
local     unix  -       n       n       -       -       local
virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
#
# Interfaces to non-Postfix software. Be sure to examine the manual
# pages of the non-Postfix software to find out what options it wants.
#
# maildrop. See the Postfix MAILDROP_README file for details.
#
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/local/bin/maildrop -d ${recipient}
uucp      unix  -       n       n       -       -       pipe
  flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail    unix  -       n       n       -       -       pipe
  flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp     unix  -       n       n       -       -       pipe
  flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -d -t$nexthop -f$sender $recipient
scalemail-backend unix  - n n - 2 pipe
  flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}

# only used by postfix-tls
#tlsmgr   fifo  - - n 300 1 tlsmgr
#smtps    inet  n - n - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
#587    inet  n - n - - smtpd -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes

# Amavis
#smtp-amavis unix -      -       n       -       2  smtp
#    -o smtp_data_done_timeout=1200
#    -o smtp_send_xforward_command=yes
#    -o disable_dns_lookups=yes
#    -o max_use=20

#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
#    -o smtpd_error_sleep_time=0
#    -o smtpd_soft_error_limit=1001
#    -o smtpd_hard_error_limit=1000
#    -o smtpd_client_connection_count_limit=0
#    -o smtpd_client_connection_rate_limit=0
#    -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks

Note that we have disabled chroot for smtp, cleanup, rewrite, proxymap, local, virtual, lmtp, anvil, maildrop, uucp, ifmail, bsmtp, scalemail, tlsmgr, sntps, 587. Some of these are disabled by default.

Also note that configuration for Amavisd-new (covered later) is included but commented out. You will enable this later.

Backup main.cf and create a new one as shown below.

# cp /etc/postfix/main.cf /etc/postfix/main.cf~
# ee /etc/postfix/main.cf /etc/postfix/main.cf
# core
program_directory = /usr/lib/postfix
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix
mail_owner = postfix
soft_bounce = yes
# debug_peer_list = domain.tld
# debug_peer_level = 2
message_size_limit = 10240000
biff = no

# local
myhostname = hostname.domain.tld
mydomain = domain.tld
myorigin = $myhostname
mynetworks = 127.0.0.0/24
mydestination = $myhostname localhost localhost.$mydomain localhost.localdomain
alias_maps = hash:/etc/aliases
local_recipient_maps = proxy:unix:passwd.byname $alias_maps
local_transport = local

# virtual
virtual_mailbox_base = /var/vmail
virtual_mailbox_domains = mysql:/etc/postfix/maps/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/maps/mysql_virtual_mailbox_maps.cf
virtual_alias_maps = mysql:/etc/postfix/maps/mysql_virtual_alias_maps.cf mysql:/etc/postfix/maps/mysql_virtual_mailbox_maps.cf
virtual_uid_maps = static:1004
virtual_gid_maps = static:1004
virtual_minimum_uid = 1001
virtual_transport = virtual
# virtual_uid_maps = mysql:/etc/postfix/maps/mysql_virtual_uid.cf
# virtual_gid_maps = mysql:/etc/postfix/maps/mysql_virtual_gid.cf
maildrop_destination_recipient_limit = 1

# backup-mx relay maps
relay_domains = proxy:mysql:/etc/postfix/maps/mysql_relay_domains_maps.cf
relay_transport = relay

# transport maps
transport_maps = mysql:/etc/postfix/maps/mysql_transport_maps.cf

# relocated maps
relocated_maps = mysql:/etc/postfix/maps/mysql_virtual_relocated_maps.cf

# quota support
# virtual_mailbox_limit = 51200000
# virtual_create_maildirsize = yes
# virtual_mailbox_extended = yes
# virtual_mailbox_limit_maps = mysql:/etc/postfix/maps/mysql_virtual_mailbox_limit_maps.cf
# virtual_mailbox_limit_override = yes
# virtual_maildir_limit_message = Sorry, the user's maildir has overdrawn his diskspace quota, please try again later.
# virtual_overquota_bounce = yes

# what do we / dont we allow

smtpd_helo_required = yes
disable_vrfy_command = yes
strict_rfc821_envelopes = yes

smtpd_recipient_restrictions =
  # reject_invalid_hostname,
  # reject_non_fqdn_hostname,
  # reject_non_fqdn_sender,
  # reject_non_fqdn_recipient,
  reject_unknown_sender_domain,
  # reject_unknown_recipient_domain,
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_unauth_destination,
  reject_rbl_client relays.ordb.org,
  # reject_rbl_client opm.blitzed.org,
  # reject_rbl_client list.dsbl.org,
  reject_rbl_client sbl.spamhaus.org,
  reject_rbl_client cbl.abuseat.org,
  # reject_rbl_client dul.dnsbl.sorbs.net

#smtpd_data_restrictions =
# reject_unauth_pipelining,
#  permit

# 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

# 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

# Send all email through Amavis
# content_filter = smtp-amavis:[127.0.0.1]:10024

Please check the Postfix documentation in /usr/share/doc/postfix or on the Postfix website for an explanation each parameter, but as a minimum you should only have to change your hostname and domain name.

Note that we have softbounce enabled while we configure our mail system, but you will want to disable this after testing.

Also note that content_filter setting for Amavisd-new (covered later) is included but commented out. You will enable this later.

The maps files are text files containing the settings Postfix will use to connect to our mySQL database and lookup virtual domain and user information. Create each of the files listed as shown below.

# mkdir /etc/postfix/maps
# ee /etc/postfix/maps/mysql_relay_domains_maps.cf
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '1' and active = '1'
# ee /etc/postfix/maps/mysql_transport_maps.cf
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = domain
select_field = transport
where_field = domain
additional_conditions = and active = 1
# ee /etc/postfix/maps/mysql_virtual_alias_maps.cf
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = alias
select_field = goto
where_field = address
# ee /etc/postfix/maps/mysql_virtual_domains_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'
# ee /etc/postfix/maps/mysql_virtual_mailbox_limit_maps.cf
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = mailbox
select_field = quota
where_field = username
#additional_conditions = and active = '1'
# ee /etc/postfix/maps/mysql_virtual_mailbox_maps.cf
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = mailbox
select_field = concat(maildir,'Maildir/')
where_field = username
#additional_conditions = and active = '1'
# ee /etc/postfix/maps/mysql_virtual_relocated_maps.cf
user = postfix
password = postfix
hosts = localhost
dbname = postfix
table = relocated
select_field = destination
where_field = email

Then set their permissions to protect your database password.

# chown root:postfix /etc/postfix/maps/*.*
# chmod 640 /etc/postfix/maps/*.*

Check your local aliases and update the aliases database. Note that these are just our local UNIX aliases, not the virtual aliases our system will support using mySQL.

# ee /etc/aliases
# newaliases

Create the SASL configuration file as shown below. Note the log level. You will no doubt want to decrease this later.

# ee /etc/postfix/sasl/smtpd.conf
pwcheck_method: auxprop
auxprop_plugin: sql
mech_list: plain login cram-md5 digest-md5
log_level: 7
sql_engine: mysql
sql_hostnames: localhost
sql_user: postfix
sql_passwd: postfix
sql_database: postfix
sql_select: select password from saslauth where username='%u@%r'

And set its permissions securely.

# chown root:postfix /etc/postfix/sasl/smtpd.conf
# chmod 640 /etc/postfix/sasl/smtpd.conf

Generate an SSL certificate to support encrypted SMTP connections, move it and secure it.

# cd ~
# openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509
# mv smtpd.cert /etc/postfix/
# mv smtpd.key /etc/postfix/
# chown root:postfix /etc/postfix/smtpd.cert /etc/postfix/smtpd.key
# chmod 640 /etc/postfix/smtpd.cert /etc/postfix/smtpd.key

Restart Postfix

# /etc/init.d/postfix restart

You should now be able to send and receive mail. Connect on port 25 in telnet and do some testing while tailing the log file to make sure everything is working right.

# tail -f /var/log/syslog

Then from another shell (Alt+F1 through Alt+F6), or from another computer:

# telnet hostname.domain.tld 25
> helo client.hostname
> mail from:
> rcpt to:
> data
>

> hello world!
>
> .

You will need to test SMTP-AUTH (SASL authentication) using an email client, unless you can do base-64 mentally.

Courier POP3 & Courier IMAP

courier mysql user

We will use Courier IMAP and Courier POP3 to provide clients with two ways to access their mail. Both will support SSL connections. FAM will enable the IMAP server to provide clients with real-time updates without the need for clients to poll every x minutes.

Install the necessary packages.

# aptitude install courier-imap courier-imap-ssl courier-pop courier-pop-ssl courier-authmysql fam

Courier uses a centralised authentication daemon. Set it to lookup authentication details using its mySQL module.

# ee /etc/courier/authdaemonrc
authmodulelist="authmysql"

Create the authmysqlrc configuration file and tell Courier how to lookup details in your mySQL database.

# ee /etc/courier/authmysqlrc
MYSQL_SERVER  localhost
MYSQL_USERNAME  postfix
MYSQL_PASSWORD  postfix
MYSQL_PORT  0
MYSQL_OPT 0
MYSQL_DATABASE  postfix
MYSQL_USER_TABLE  mailbox
MYSQL_CRYPT_PWFIELD password
MYSQL_UID_FIELD '1004'
MYSQL_GID_FIELD '1004'
MYSQL_LOGIN_FIELD username
MYSQL_HOME_FIELD  concat('/var/vmail/',maildir)
MYSQL_NAME_FIELD  name
MYSQL_WHERE_CLAUSE  active='1'

Check your IMAP and POP3 daemon configuration files. Please consult the documentation in /usr/share/doc/courier or the Courier website for details.

# ee /etc/courier/imapd
# ee /etc/courier/pop3d

Self signed SSL certificates were generated for us during the package install, but unfortunately these were created for localhost and so are of little use to us. No matter, simply backup the certs and create new ones, specifying accurate details for your server.

# mkdir /etc/courier/oldcerts
# mv /etc/courier/*.pem /etc/courier/oldcerts
# ee /etc/courier/imapd.cnf
# ee /etc/courier/pop3d.cnf
# mkimapdcert
# mkpop3dcert
# chown root:daemon /etc/courier/*
# chmod 640 /etc/courier/*

Check FAM's configuration file

# ee /etc/fam.conf

You should now be able to connect to POP3 and IMAP and login. To test POP3, connect to port 110 using telnet and do some testing while tailing the log file to make sure everything is working right.

# tail -f /var/log/syslog

Then from another shell (Alt+F1 through Alt+F6), or from another computer:

# telnet hostname.domain.tld 110
> user local.user@local.domain.tld
> pass xxxxxx
> list
> retr 1
> quit

TODO: IMAP telnet session

Part Two

This brings us to the end of the first part of my Debian Sarge Virtual Mail Server Howto. You should now be able to send and receive e-mail via SMTP, and to access that e-mail through POP3 and IMAP. Please see below for the second part of my virtual mail server howto.

Part Two of my Debian virtual mail server howto is available now. We will add support for server side filtering, content filtering and webmail.

Discussion

sebaj, 2009/09/07 13:17:

send me the part two

Enter your comment (wiki syntax is allowed):

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_sarge_virtual_mail_server_howto_part_one.txt · Last modified: 2008/08/01 23:56 (external edit) · [Old revisions]
Recent changes RSS feed Powered by Debian Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki