Automated build and setup of exim-tls with virtuals users
Table of contents
- Licence
- Introduction
- Credits
- The Automated build process
- Requirements
- Script setup
- Exim setup
- Mysql setup
- Bugs
Copyright (c) 2003 Vinai Kopp
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the "GNU Free Documentation License" can be found here.
All programs listed on this site are free software; you can redistribute
them and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
These programs are distributed in the hope that they will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You can obtain a copy of the GNU General Public License here
along with these programs; or write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
When building a new server I wanted to use virtual users for mail accounts using exim-tls.
The users should be stored in mysql tables so I could easily integrate courier-popd and
spamassassin.
I luckily found an excelent description of the setup by Thomas Pircher.
The current debian exim-tls package is built without mysql support. That
almost convinced me not to use this setup because I didn't want to have to rebuild
the exim-tls-mysql package manualy if a security update would be announced.
So I decided to use the debian source package to build an exim-tls-mysql.deb and
automate the build of the reconfigured package as much as possible. But
I didn't want a build environment on the production server.
Here is what I decided to do:
I set up some scripts on a development host with a permanent internet connection.
When a new exim-tls package is announced on the debian security-announce
mailing list I run a script on the server to trigger the buildhost to fetch the
source of the new package, patch the required files and build a new exim-tls-mysql.deb.
Once the package is finished the server downloads it and I can install it using dpkg -i.
A lot of the scripts could be recoded to have fewer dependencies and it leaves some
things to be desired (e.g. if the patch fails with the new source the automatic
build fails - but at least it should be easy to figure out how to fix it)
I also tried to avoid fancy scripting in favor of easy to understand and maintainable
scripts.
I also included my version of the mysql tables and my exim.conf because it is slightly
different from the ones used by Thomas Pircher, in case somebody finds them useful.
Please send any corrections, comments and questions to <vinai@netzarbeiter.com>.
The mysql and exim setup is nothing but a modified version of the setup by
Thomas Pircher <tehpeh@gmx.net> described here: http://www.tty1.net/virtual_domains_en.html
requirements on the production server:
- curl (or curl-ssl if the buildhost is reachable over https)
requirements on the buildhost:
- must be reachable via a static IP or (dyndns) domain name
- a httpd with php4 support (apache)
- a directory in the web-tree where the httpd is allowed to write (so the new deb
can be offered for download)
- perl
- mmv
- sudo
- a sudoers entry for httpd user for "/usr/bin/apt-get update"
(e.g. "www-data ALL = NOPASSWD: /usr/bin/apt-get update")
- a build environment (dpkg-buildpackage, fakeroot, patch etc)
- up-to-date development libraries (e.g. libmysqlclient-dev and libssl-dev)
On the server side there is one script: get-exim-tls-mysql-deb
It needs to be configured where the buildhost is and how to authorize
(www-authenticate user and pass). I just droped the script in /usr/local/bin.
On the buildhost side there is one php script, one bash script and one patch file
exim-tls-mysql.php - triggers the download and build process
must be configured where the final deb will be
and where the build script is
build-exim-tls-mysql - downloads the new sources and builds the new deb
needs to be configured where the diff file can be found
exim-tls-to-exim-tls-mysql.diff - a couple of patches to the pakage source
please update the maintainer on line 11to reflect your name
and email so people would blame you for the package
This is my setup (ajust to your directory structure):
/var/www/domain/ssl/debbuild/exim-tls-mysql.php <--- the trigger script
/var/www/domain/ssl/debbuild/exim-tls-mysql <--- directory for the finished new deb
/var/www/domain/debian-build/exim-tls-mysql <--- here the build-exim-tls-mysql script and the diff live
All virtual users are handled by the same system user (mail in my case).
I went with the maildir format because I wanted to use the courier-popd.
The maildir directories for the virtual users are located at
/var/mail/vusers/{username}/Maildir.
They must be writeable by the system account for the virtual users.
Here is the exim.config we use.
Here are the parts that are interresting for the mysql virtual user setup:
######################################################################
# MAIN CONFIGURATION SETTINGS #
######################################################################
# The mysql server
hide mysql_servers = "/dbname/dbuser/dbpass"
local_domains = localhost : host.example.com : mysql;SELECT id FROM domains WHERE domain = '${sg {$key}{'}{}}' AND status = '1';
######################################################################
# DIRECTORS CONFIGURATION #
######################################################################
# mysql aliases director
# The same regarding the file_- and pipe_transport options
# applies as with the system_aliases director
mysql_aliases:
driver = aliasfile
file_transport = address_file
pipe_transport = address_pipe
search_type = mysql
queries = SELECT value FROM aliases WHERE lookup = '${sg {$local_part@$domain}{'}{}}' AND value != '' AND status = '1'; : \
SELECT value FROM aliases WHERE lookup = '${sg {@$domain}{'}{}}' AND value != '' AND status = '1';
# .forward equivalent lookup or virtual users
# virtual users may not use forwards to files, pipes or use includes
vuser_forward:
driver = forwardfile
check_local_user = false
check_ancestor
forbid_file
forbid_include
forbid_pipe
user = mail
group = mail
data = ${lookup mysql {SELECT forward FROM vusers WHERE user='${sg {$local_part}{'}{}}' AND forward != '' AND status = '1';} {$value} fail}
# This director searches for a matching user in tha mysql database
virtual_user:
driver = aliasfile
file_transport = address_file
directory_transport = address_directory
pipe_transport = address_pipe
search_type = mysql
query = SELECT CONCAT(maildir, '/') FROM vusers WHERE user = '${sg {$local_part}{'}{}}' AND maildir != '' AND status = '1';
user = mail
group = mail
######################################################################
# AUTHENTICATION CONFIGURATION #
######################################################################
plain:
driver = plaintext
public_name = PLAIN
server_condition = "${if crypteq {$3} {${lookup mysql {SELECT crypt FROM vusers WHERE user = '${sg {$2}{'}{}}' AND status = '1' AND asmtp = '1';}}} {1}{0}}"
server_set_id = $2
login:
driver = plaintext
public_name = LOGIN
server_prompts = "Username:: : Password::"
server_condition = "${if crypteq {$2} {${lookup mysql {SELECT crypt FROM vusers WHERE user = '${sg {$1}{'}{}}' AND status = '1' AND asmtp = '1';}}} {1}{0}}"
server_set_id = $1
cram:
driver = cram_md5
public_name = CRAM-MD5
server_secret = "${lookup mysql {SELECT clear FROM vusers WHERE user = '${sg {$1}{'}{}}' AND status = '1' AND asmtp = '1';} {$value} fail}"
server_set_id = $1
Here are our mysql tables, they are probably self explanatory.
The exim mysql user only needs the select privilege.
- probably a lot: this is a hack
- diff doesn't apply cleanly to the current stable mysql-tls source package (it works but with a fuzz factor)