Setting up a Debian server as a POP3 mail host for a collection of domains with MySQL, Exim & Courier.
Sponsored Links:
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 TABLEdomains
(userid
char(128) NOT NULL default ”, KEYuserid
(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 ”, KEYid
(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 INTOusers
(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/Maildir johnnie@example.com R=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_directoryvirtual_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