To my Homepage
Did this site help you?
Average rating (Rootserver):
2.93/3 (459 votes)

VExim and Debian GNU/Linux

...a minimal invasive approach

Vexim ("virtual exim") is an add-on to the Exim mailserver. It enables Exim to serve virtual mail domains independent from real machine accounts, provides an web interface for their administration and stores all domain and account related data in a MySQL or PostgreSQL database.

Background

With the advent of affordable internet servers, so called "virtual mail domains" got popular. Traditionally, an email address like john@example.com refers to a user john who has an account on the computer example.com. However, it is of course not feasible to allow everyone using a mail address shell access to the system by granting them a system account. In most cases, a server should also handle multiple mail domains, and keep their user base seperated, as well as assign each mail domain their own administrator who is allowed to manage mail accounts on their domain.

Virtual Exim (vexim) is a software that provides these functionality. It stores its configuration data (domain and POP/IMAP account data) in a MySQL database, and even employs a web interface for management of domains and accounts.

Vexim hooks into the famous Exim MTA. This is where the problems started: A german howto allegedly suited for Debian recommended the complete replacement of the debconf based configuration, disabling all Debian magic and leading to much discussion and controversy on various mailing lists.

I tried to include vexim into my Debian system with a minimal number of modifications of the debian-supplied files.

Preparations

After downloading the vexim package from its homepage, extract it into a temporary location. Also make sure that MySQL as well as the required PHP modules are installed. The following command line should supply you with the needed packages:

apt-get install php4-pear mysql-server

You could of course also use mysql-server-5.0 or any other packaged version of MySQL.

We should also create a new user account whom the mailboxes belong to. Since we do not want anyone to be able to login using that account, we will also disable it:

adduser --system --home /var/spool/vexim --disabled-password --disabled-login --group vexim

We also need a directory where vexim can store the mailboxes of te domains we wish to manage - thankfully adduser already does this by creating the home directory. Please memorize the uid and gid numbers assigned in this process: We will need them later.

Setting up the database

Inside the extracted archive, the file vexim2/setup/mysql.sql provides the database scheme used by vexim. But before importing it into MySQL, make sure no previously installed vexim is present: its configuration will be completely wiped by this procedure! Some changes must be made to the file in order to work:

Look for the word CHANGE and you will find the following two lines:

    uid              smallint(5)   unsigned  NOT NULL  default 'CHANGE',
    gid              smallint(5)   unsigned  NOT NULL  default 'CHANGE',

Replace CHANGE with the uid of your freshly created "vexim" user: This is the default owner of new mailbox files.

Further below you will find the following section:

---
--- Priviledges:
---
GRANT SELECT,INSERT,DELETE,UPDATE ON `vexim`.* to "vexim"@"localhost"
    IDENTIFIED BY 'CHANGE';
FLUSH PRIVILEGES;

Replace CHANGE with a secure password - It will be used both by the Exim MTA and the web interface to access the database.

It should now be possible to execute the database scheme within mysql:

mysql -u root -p < vexim2/setup/mysql.sql

Web Interface

Now that we have a working database, we will install the web interface. Just copy the vexim/ directory into your webserver root and make sure that PHP is configured correctly. Now check the file vexim/config/variables.php: There are a few things that should be set, at first of course the SQL password as indicated by CHANGE. You also might want to change the uid and gid values used for new mailboxes.

Right here is another catch that is not described in the official manual. Change the line

  $domaininput = "static";

to

  $domaininput = "textbox";

If you are done and feel confident, try accessing your vexim installation through your browser (e.g. http://example.com/vexim/). You can login by leaving the domain textbox empty (this is why we replaced the static field with it), entering siteadmin as your username and using CHANGE as your initial password. Be sure to change it after successfully logging in!

Hooking into Exim

With the database and the web interface running, you can already define domains and user accounts. But the most important part is still missing: vexim has to hook into the Mail Transfer Agent (exim) to actually influence the delivery of mails. This is also the most sensitiv part of the installation: The intention is to keep the Debian files untouched until forced to, which works quite well.

Vexim has to hook into three sections of the exim4 configuration, which should be split into several mall files as advised by Debian:

Fortunately, the Debian exim4 configuration provides some hooks to achieve these goals without having to modify the supplied files themselves.

The routing and transport part can be solved easily be copying excerpts from the vexim example configuration into the appropiate directories conf.d/router/250_vexim-virtual_domain and conf.d/transport/30_vexim_virtual_delivery. Using these numbers, vexim will drain messages for virtual domains before they are processed by the local (system) transport.

Getting exim to consider virtual domains as localdomains without blocking the Debian magic was a little bit more difficult, but quite possible in the end:

hide mysql_servers = localhost::(/var/run/mysqld/mysqld.sock)/vexim/vexim/password

VIRTUAL_DOMAINS = SELECT DISTINCT domain FROM domains WHERE type = 'local' AND enabled = '1' AND domain = '${quote_mysql:$domain}'
RELAY_DOMAINS = SELECT DISTINCT domain FROM domains WHERE type = 'relay'  AND domain = '${quote_mysql:$domain}'
ALIAS_DOMAINS = SELECT DISTINCT alias FROM domainalias WHERE alias = '${quote_mysql:$domain}'

MAIN_LOCAL_DOMAINS = DEBCONFlocal_domainsDEBCONF : ${lookup mysql{VIRTUAL_DOMAINS}} : ${lookup mysql{ALIAS_DOMAINS}}
MAIN_RELAY_TO_DOMAINS = DEBCONFrelay_domainsDEBCONF : ${lookup mysql{RELAY_DOMAINS}}

These lines placed under conf.d/main/00_vexim_domains provide the basic configuration for database access (be sure to change the database password) and add the virtual domains stored in the database to the list of local domains managed by debconf, therefore merging the bet of both world.

Optional goodies

Things left to do: