Setting up a Debian server as a POP3 mail host for a collection of domains with MySQL, Exim & Courier.
SMTP & POP3 Email for Virtual Users on Debian Sarge
Abstract
I’m setting up a Debian server as a POP3 mail host for a collection of miscellaneous domains. I want to administer the domains & user accounts through a PHP front end, so it’s easiest for me if the configuration is stored in MySQL. After a brief period of reseach, I’m using Exim 4, Courier POP3 + SSL and SpamAssassin.
Below are my notes so far.
Current status:
The server will receive messages on port 25 (or 587) for users in the MySQL database and file them into the correct mailbox. Messages can be downloaded using POP3 using the same database for authentication using plain text authentication (port 110) or SSL (993). Messages can be sent using the server as an SMTP relay providing they authenticate first. TLS is available for sending.
Todo
- Quotas
- Optional mail forwarding
- Write front end for user administration
Notes
Required packages:
sudo apt-get install mysql-server mysql-client libmysqlclient12-dev sudo apt-get install exim4-daemon-heavy sudo apt-get install courier-pop-ssl sudo apt-get install courier-authmysql
If you want to use PHPMyAdmin:
sudo apt-get install apache2 sudo apt-get install apache2-ssl sudo apt-get install php4 sudo apt-get install phpmyadmin
Create the mail directory
sudo mkdir -m 600 /usr/local/vdomains sudo chown mail:mail /usr/local/vdomains
Create an example domain
sudo mkdir -m 600 /usr/local/vdomains/example.com sudo mkdir -m 600 /usr/local/vdomains/example.com/users sudo chown mail:mail /usr/local/vdomains/example.com
Database
Create a new database called mail, and a user mail with all privileges on that database.
Tables:
CREATE TABLE `domains` ( `userid` char(128) NOT NULL default '', KEY `userid` (`userid`) ) ENGINE=MyISAM; CREATE TABLE `users` ( `id` char(128) NOT NULL default '', `crypt` char(128) NOT NULL default '', `clear` char(128) NOT NULL default '', `name` char(128) NOT NULL default '', `uid` int(10) unsigned default '8', `gid` int(10) unsigned default '8', `home` char(255) NOT NULL default '', `maildir` char(255) NOT NULL default '', `quota` char(255) NOT NULL default '', KEY `id` (`id`) ) ENGINE=MyISAM;
Note - I later changed the schema when developing a PHP front end for administration. I found that the id field could be named anything you like, as long as it’s not exactly username. That is: Courier Authdaemon will not authenticate if the id field is named username. These are fine: userName, name, email.
Example User:
INSERT INTO `users` (`id`, `crypt`, `clear`, `name`, `uid`, `gid`, `home`, `maildir`, `quota`) VALUES ('johnnie@example.com', ENCRYPT('johnniepass'), 'johnniepass', 'johnnie', 8, 8, '/usr/local/vdomains/example.com/users/johnnie', '/usr/local/vdomains/example.com/users/johnnie/Maildir/', '');
Note The Maildir field has a trailing slash. Without this exim uses file_transport instead of directory_transport, and you’ll get error messages in the format:
2007-04-04 11:17:43 /usr/local/vdomains/example.com/users/johnnie/MaildirR=virtual_user defer (-30): file_transport unset in virtual_user router
Make a directory for the user’s data
sudo maildirmake /usr/local/vdomains/example.com/users/johnnie
Configuring Courier
File: /etc/courier/authdaemonrc
Set: authmodulelist="authmysql"
File: /etc/courier/authmysqlrc
Set:
MYSQL_SERVER localhost MYSQL_USERNAME mail MYSQL_PASSWORD secret MYSQL_SOCKET /var/run/mysqld/mysqld.sock MYSQL_DATABASE mail MYSQL_USER_TABLE users MYSQL_CRYPT_PWFIELD crypt MYSQL_UID_FIELD uid MYSQL_GID_FIELD gid MYSQL_LOGIN_FIELD id MYSQL_HOME_FIELD home MYSQL_NAME_FIELD name
Configuring Exim
Define MySQL server
Edit file: /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
Tell Exim which domains it’s handling mail for
# domainlist local_domains = MAIN_LOCAL_DOMAINS domainlist local_domains = localhost:january.randomsequence.com:mysql;SELECT userid FROM domains WHERE userid='$domain';
New File: /etc/exim4/conf.d/router/999_exim4-config_mysql_user
virtual_user:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{ SELECT maildir FROM users WHERE id='${local_part}@${domain}' }}
directory_transport = address_directory
virtual_catchall_user:
driver = redirect
allow_fail
allow_defer
data = ${lookup mysql{ SELECT maildir FROM users WHERE id='*@${domain}' }}
directory_transport = address_directory
Edit File: /etc/exim4/conf.d/transport/35_exim4-config_address_directory
# This transport is used for handling file addresses generated by alias # or .forward files if the path ends in "/", which causes it to be treated # as a directory name rather than a file name. address_directory: debug_print = "T: address_directory for $local_part@$domain" driver = appendfile envelope_to_add = true return_path_add = true check_string = "" escape_string = "" maildir_format = true mode = 0600 user = mail group = mail
Allow remote connections to Exim
Edit file: /etc/exim4/update-exim4.conf.conf
# …snip # This is a Debian specific file dc_eximconfig_configtype='internet' dc_other_hostnames='' dc_local_interfaces='127.0.0.1:[SERVER IP ADDRESS]' dc_readhost='' dc_relay_domains='' dc_minimaldns='false' dc_relay_nets='' CFILEMODE='644' dc_use_split_config='true' dc_hide_mailname='false' dc_mailname_in_oh='true'
Removing Lookup Delays
Edit file: /etc/exim4/conf.d/main/02_exim4-config_options
Set: rfc1413_query_timeout = 0s
Allow Exim to use Courier Authdaemon
Add Exim to the daemon group:
sudo usermod -G daemon Debian-exim
Edit file: /etc/exim4/conf.d/auth/30_exim4-config_examples
Un-comment plain_courier_authdaemon: & login_courier_authdaemon:, comment out cram_md5:, plain: & login: sections.
Enable Exim TLS
Generate a self-signed certificate for Exim using the tool:
/usr/share/doc/exim4-base/examples/exim-gencert
New file: /etc/exim4/conf.d/main/000_localmacros
# switch on tls MAIN_TLS_ENABLE = true # Listen on Standard TLS Port daemon_smtp_ports = smtp : 587 #enable login without TLS / SSL AUTH_SERVER_ALLOW_NOTLS_PASSWORDS = true
SpamAssassin
To install the latest spamassassin with sa-update, it was necessary to use the unstable Debian branch. This my come back to haunt me.
Add Unstable Source
Edit file: /etc/apt/sources.list
deb http://ftp.us.debian.org/debian unstable main non-free contrib
Make sure we use stable packages by default for everything else:
Edit file: /etc/apt/apt.conf
APT::Default-Release "stable";
Install spamassain & required packages for sa-update
sudo apt-get install -t unstable spamassassin sudo apt-get install libnet-dns-perl gnupg
This involves upgrading a bunch of other libraries to unstable, and therefore probably isn’t a good idea.
Start spamd each reboot
Edit file: /etc/default/spamassassin
# Change to one to enable spamd ENABLED=1
Enable SpamAssassin in Exim
Edit file: /etc/exim4/sa-exim.conf
# Remove or comment out the following line to enable sa-exim # SAEximRunCond: 0
Cron Job for sa-update
New file: /etc/cron.daily/sa-update
#!/bin/sh # Update SpamAssassin Rules /usr/bin/sa-update -D channel,dns /etc/init.d/spamassassin restart
Run the update now:
sudo /usr/bin/sa-update -D channel,dns
Training SpamAssassin
sudo sa-learn --showdots --spam folder_of_spam/* sudo sa-learn --showdots --ham folder_of_ham/*
Starting SpamAssassin
sudo /etc/init.d/spamassassin start
Dubugging Exim problems
Enable extended logging (to file /var/log/exim4/mainlog):
File: /etc/exim4/conf.d/main/02_exim4-config_options
Set: log_selector = +all
# Show log for a particular message: sudo /usr/sbin/exim4 -Mvl [Message ID] # Force Exim to process the mail queue: sudo /usr/sbin/exim4 -qf
Helpful Links
http://www.tty1.net/virtual_domains_en.html
http://koivi.com/exim4-config/
http://www.sput.nl/software/exim.html
http://bradthemad.org/tech/notes/exim_cheatsheet.php?FOO
http://swik.net/Exim
http://www.exim.org/exim-html-4.10/doc/html/spec_toc.html
