Exim 3.36 and Web-cyradm

Contents

  1. Reason why
  2. Exim Installation
  3. Exim Configuration
  4. Information
  5. Author
  6. About this document ...

1. Reason why

In a standard Debian 3 (woody) installation exim is the standard MTA. Because I could get a very good book on exim (Philip Hazel, Exim. The Mail Transfer Agent. Official Guide for Release 3. O'Reilly and Associates, Inc. 2001) at a very reasonable price and ``it has to work somehow'' I tried to use Exim instead of postfix. This HOWTO should be an Addendum to the ``Postfix-Cyrus-Web-cyradm-HOWTO'' by Luc de Louw (http://www.delouw.ch/linux/Postfix-Cyrus-Web-cyradm-HOWTO/ html/index.html) and add an exim possibility to Cyrus and Web-cyradm.

This HOWTO only refers to exim 3.36 (and Debian 3.0 woody). There exist much more recent versions of exim (http://www.exim.org), I think version 4.20 is reached by now. Unluckily there are major changes in the configuration and I don't see the reason why I should get another book for a system that works perfectly according to my needs. If anybody should see such a reason why for her- or himself, please publish your results somewhere.

In short, it works, and here's how:

2. Exim Installation

For our configuration we use exim 3.36. Even if Exim is already installed as the Debian Woody standard MTA, these binaries don't support database lookups in mysql.

Exim has to be recompiled. The tarred sources are available at http://www.exim.org.

After unpacking change into the exim-directory and create a new directory called Local: mkdir Local. Copy the file src/EDITME (whitch is an example Makefile) to the Local-Directory: cp src/EDITME Local/Makefile. This Makefile will be used in the building process and has to be modified according to your needs. It contains quite a lot of information in itself, so I will not try to explain all the possible and useful changes (can't). In general make sure that the paths are set according to your system. Here's just our Makefile as one example. The changes apply basically to our paths of the mysqlclient, the pam-libraries (and the includes and libraries used for tls.)

If you want to understand the really real meaning of all these settings please take a close look at: http://www.exim.org/exim-html-3.30/doc/html/spec.html

After changing the settings according to your needs you can build the binary with a simple: make. If everything works fine the building process should end with the optimistic line: >>> exim binary built. Seeing this enables you to install the binary with: make install.

After that your new Exim with mysql-lookups, pam-authentication (and tls-encryption) is prepared to work.

For compiling, we needed the following packages:

Apparently the last library is necessary for the functional cooperation between pam_mysql and exim. When we installed a mysql-server (version 4x) without libmysqlclient10-dev, exim was linked against libmysqlclient12 (needed by the mysql-server 4x) during compilation and the results of pam_mysql-queries did not get back to exim (pam_mysql.so linked against libmysqlclient10). Installing libmysqlclient10-dev and recompiling exim solved the problem (even if I don't know why).

2.1. Exim Makefile: Local/Makefile

############################

#  The Exim mail transport agent  #

############################

CHOWN_COMMAND=/bin/chown

CHGRP_COMMAND=/bin/chgrp

MV_COMMAND=/bin/mv

RM_COMMAND=/bin/rm

PERL_COMMAND=/usr/bin/perl

AR=ar cq

AUTH_CRAM_MD5=yes

AUTH_PLAINTEXT=yes

BIN_DIRECTORY=/usr/sbin

COMPRESS_COMMAND=/bin/gzip

COMPRESS_SUFFIX=gz

ZCAT_COMMAND=/bin/zcat

CONFIGURE_FILE=/etc/exim/exim.conf

DIRECTOR_ALIASFILE=yes

DIRECTOR_FORWARDFILE=yes

DIRECTOR_LOCALUSER=yes

DIRECTOR_SMARTUSER=yes

DB_DIRECTORY_MODE=0750

EXICYCLOG_MAX=10

EXIM_UID=8

EXIM_GID=8

INPUT_DIRECTORY_MODE=0750

LOG_FILE_PATH=/var/log/exim/%slog

LOOKUP_DBM=yes

LOOKUP_LSEARCH=yes

LOOKUP_CDB=yes

# LOOKUP_DNSDB=yes

# LOOKUP_LDAP=yes

LOOKUP_MYSQL=yes   # needed for mysql-lookups

# LOOKUP_NIS=yes

# LOOKUP_NISPLUS=yes

# LOOKUP_PGSQL=yes

# Additional libraries and include directories may be required for some

# lookup styles, e.g. LDAP, MYSQL or PGSQL. LOOKUP_LIBS is included only on

# the command for linking Exim itself, not on any auxiliary programs. You

# don't need to set LOOKUP_INCLUDE if the relevant directories are already

# specified in INCLUDE.

LOOKUP_INCLUDE=-I /usr/include/mysql -I /usr/include/security

LOOKUP_LIBS=-L/usr/lib -lmysqlclient -L /lib/security -lpam   # mysql and pam support

PID_FILE_PATH=/var/run/exim/exim%s.pid

ROUTER_DOMAINLIST=yes

ROUTER_IPLITERAL=yes

ROUTER_LOOKUPHOST=yes

ROUTER_QUERYPROGRAM=yes

SPOOL_DIRECTORY=/var/spool/exim

SUPPORT_MAILDIR=yes

SUPPORT_MAILSTORE=yes

SUPPORT_MBX=yes

SUPPORT_MOVE_FROZEN_MESSAGES=yes

SUPPORT_PAM=yes

# SUPPORT_TLS=yes

# TLS_LIBS=-lssl -lcrypto

# TLS_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto

# TLS_INCLUDE=-I/usr/local/openssl/include/

TRANSPORT_APPENDFILE=yes

TRANSPORT_AUTOREPLY=yes

TRANSPORT_PIPE=yes

TRANSPORT_SMTP=yes

TRANSPORT_LMTP=yes

# End of EDITME

3. Exim Configuration

The configuration's results are:

Exim's main configuration file is /etc/exim/exim.conf. It is read by Exim any time it starts. So if you run Exim from within the inetd all the changes to the configuration file will be read any time inetd starts an exim process. In that case you don't need to restart Exim to apply the changes. Only if you run Exim as a daemon for itself from the boot-configuration you have to restart the program to make the changes work.

The configuration file consists of seven parts: Main Configuration, Transport Configuration, Director Configuration, Router Configuration, Retry Configuration, Rewrite Configuration, Authentication Configuration. The Retry Configuration is accepted with the default value, the Rewrite Configuration is commented: I didn't want Exim to rewrite addresses.

The Main Configuration sets general options to Exim, some of them explained here:

primary_hostname =
This is the primary hostname of the server
qualify_domain =
The domainname that is added to unqualified addresses, i.e. addresses that don't have the full part after the @.
local_domains =
These are the domains that are regarded as local. You can specify several domains separated by a colon. Here you have to enter all the domains (including virtuals) you want your mailserver to accept mail for. Of course these domains have to have valid MX records somewhere.
hide_mysql_servers =
The mysql-server that is used in database lookups. ``hide'' means, these settings don't show when a normal user lists the exim settings with ``exim -bv''. The value for this option consists of the database server, the database name, a database user who may subject queries to the database and the password for this user, all separated by slashes: database-server/database-name/database-user/this-users-password. The database should be the one you set up for Web-cyradm. Sorry, I don't know how to encrypt the password!
local_domains_include_host =
true or false: Allow mail addressed to our hostname
local_domains_include_host_literals =
true or false: Allow mail to our IP-address
relay_domains = *
Don't! Put in the name for domains that are not local, but you want to relay (ie send) mail for. Use it only for domains you really want to send mail for. Don't put in * if you don't want to be sued by spam-blockers. Best comment it!
relay_domains_include_local_mx =
Relay mails for non-local-domains whose MX-record point to your server. Don't put in ``true'' unless you are sure that only reliable and lawabiding persons can set up a DNS-Zone or you are in a secure intranet with its own DNS-servers.
headers_check_syntax
Make Exim check the syntax of e-mail headers. Apparently invalid mail are rejected.
rbl_domains =
rbl.mail-abuse.org/reject : dialups.mail-abuse.org/warn  Realtime Blocking List: will reject mail from hosts in this list. See for example http://www.mail-abuse.org/ for background.
host_accept_relay =
For these hosts, exim will relay mail without any further authentication. 127.0.0.1 has to be included if you want to send mail from your server. DON'T put in * if you do not want all the spammers on the internet to send their mails via your precious server! You could soon end up in a blocking list! You can put in something like 192.168.2.0/24 : 192.168.34.0/24 if you are in a secure intranet.
host_auth_accept_relay = *
Will accept relaying of mails from any host, that has been authenticated. For the authentication procedure see below
auth_always_advertise = false
Only advertise the need for authentication to clients that ask for it.

Transports Configurations. Here the transports are defined that are later used to actually deliver the mail. The transports beginning with ``address_'' and ``procmail_'' are default-entries and can be left unchanged.

local_delivery:
Responsible for delivering mail directed to the local users. This transport will direct mail to users with a local account to the appropriate mailboxes on the server (ie NOT to the Cyrus mailboxes). The entry in the config-file is the default.
cyrus_delivery:
This transport hands over mail for IMAP/POP3 users to the cyrdeliver-process, that will put them safely in the users' cyrus-mailboxes.
remote_smtp:
This transport is a default-entry. It actually sends the mail to remote hosts.

The Directors' Configuration specifies how to handle the addresses. Here ``order does matter'': the first director that produces a positive result will be used.

system_aliases:
Looks up aliases for addresses in the incoming mail. These aliases have to be specified in the file /etc/aliases. This setting changes addresses directed to users with a local system account and an entry in the alias-file.
cyrus_aliases:
Looks up aliases for addresses in the mysql-database that was set up for the administration and authentication with Web-cyradm. Addresses that direct to someuser@mydomain.org will be changed to point at the mailbox of the apropriate IMAP/POP3 user if he/she/it exists
cyrus_aliases_catch_all:
Needed for the ``catch all'' Accounts in Web-cyradmn, that recieve all mail directed at non existent email-addresses within one domain. Adresses where the local part doesn't exist but the domain is present are aliased to the ``catch all'' Account of this domain (if it was set up).
cyrus_fwd_accounts_aliases:
Needed for forwarding complete accounts. If forwarding of an account is set in Web-cyradm this director looks up in the database the local part of the mail (that was already changed by the cyrus_aliases director to something like xxx0004) and maps it to the appropriate e-mail address.
localuser:
Takes all the mail directed to someone with a local system account and hands them over to the local_delivery Transport. This mail goes to the mailboxes of the users with a local system account.
cyrus_user:
Takes all the rest of the mail and hands it over to the cyrus_delivery Transport that delivers it to the cyrus-mailboxes if they exist. If there are users who have two accounts (one local and one in Cyrus) with the same name (for example both are www0001) this configuration will put mail directed to these users only in the systems' mailbox. If you want to change this change the position of the two transports or better, don't give the Cyrus users the same names as local users.

The Routers Configuration handles the delivery of mail to the internet. Both routers lookup either names or IP-addresses and then hand the mails either to the remote_smtp transport for delivery to the internet or to the local_delivery transport.

The Authentication Configuration is needed for the authentication of hosts that the mailserver should relay mail for. Again: it is neccesary to limit relaying of mail only to accepted users to prevent the spreading of spam. The authentication allows ``roaming users'' to use the mailserver to send mail. Unluckily there are some mail-clients that don't support authentication (i.e. KMAIL from KDE 2.x), but that can't be helped.

plain:
Offers the PLAIN authentication method
login:
Offers the LOGIN authentication method.

Both authenticators hand the actual testing of the accounts to a PAM-file (/etc/pam.d/exim) that uses the libpam_mysql library to look up the accountname and password in the database, that was set up for the administration and authentication within Web-cyradm.

This PAM-module was produced by copying the imap-file produced for the authentication within Web-cyradm to the name exim: cp /etc/pam.d/imap /etc/pam.d/exim.

Now take a look at our configuration file. It really works so copy and paste should create a working /etc/exim/exim.conf if you don't forget to change all local settings to your needs.

3.1. Exim configuration file: /etc/exim/exim.conf

################################

#  MAIN CONFIGURATION SETTINGS  #

################################

 

primary_hostname = mail.mydomain.org

qualify_domain = mydomain.org

hide mysql_servers = database-server/database-name/database-user/this-users-password

local_domains = localhost:mydomain.org:theotherdomain.com

local_domains_include_host = true

local_domains_include_host_literals = true

#relay_domains = *

#relay_domains_include_local_mx = true

#never_users = root

host_lookup = *

headers_check_syntax

rbl_domains = rbl.mail-abuse.org/reject : dialups.mail-abuse.org/warn

host_accept_relay = 127.0.0.1 : 213.133.124.29

host_auth_accept_relay = *

# percent_hack_domains=*

trusted_users = mail

smtp_verify = true

gecos_pattern = ([,:]*)

gecos_name = $1

smtp_accept_queue_per_connection = 100

freeze_tell_mailmaster = true

received_header_text = "Received: \

         ${if def:sender_rcvhost {from ${sender_rcvhost}\n\t}\

         {${if def:sender_ident {from ${sender_ident} }}\

         ${if def:sender_helo_name {(helo=${sender_helo_name})\n\t}}}}\

         by ${primary_hostname} \

         ${if def:received_protocol {with ${received_protocol}}} \

         (Exim ${version_number} #${compile_number} (Debian))\n\t\

         id ${message_id}\

         ${if def:received_for {\n\tfor <$received_for>}}"

receiver_try_verify = true

#accept_8bitmime = true

#local_interfaces = 127.0.0.1

#queue_list_requires_admin = false

auth_always_advertise = false

end

  #################################

#  TRANSPORTS CONFIGURATION                    #

################################# #  ORDER DOES NOT MATTER                         #

#  Only one appropriate transport is called for each delivery.    #

################################

local_delivery:

  driver = appendfile

  group = mail

  mode = 0660

  mode_fail_narrower = false

  envelope_to_add = true

  return_path_add = true

  file = /var/spool/mail/${local_part}

 

cyrus_delivery:

   driver = lmtp

   command = "/usr/sbin/cyrdeliver -l ${local_part}"

   return_path_add

   user = cyrus

 

address_pipe:

  driver = pipe

  path = /usr/bin:/bin:/usr/local/bin

  return_output

 

address_file:

  driver = appendfile

  envelope_to_add = true

  return_path_add = true

 

address_directory:

  driver = appendfile

  no_from_hack

  prefix = ""

  suffix = ""

# maildir_format

address_reply:

  driver = autoreply

# This transport is used for procmail

procmail_pipe:

  driver = pipe

  command = "/usr/bin/procmail"

  return_path_add

  delivery_date_add

  envelope_to_add

# check_string = "From "

# escape_string = ">From "

  suffix = ""

 

remote_smtp:

  driver = smtp

 

end

####################################

#    DIRECTORS CONFIGURATION                  #

#    Specifies how local addresses are handled             #

####################################

#     ORDER DOES MATTER                         #

#  A local address is passed to each in turn until it is accepted.  #

######################################

 

real_local:

  prefix = real-

  driver = localuser

  transport = local_delivery

 

system_aliases:

  driver = aliasfile

  file_transport = address_file

  pipe_transport = address_pipe

  file = /etc/aliases

  search_type = lsearch

 

cyrus_aliases:

   driver = aliasfile

   query = select dest from virtual where alias='${quote_mysql:${expand:${local_part}@${domain}}}'

   search_type = mysql

 

cyrus_aliases_catch_all:

   driver = aliasfile

   query = select dest from virtual where alias='${quote_mysql:${expand:@${domain}}}'

   search_type = mysql

cyrus_fwd_accounts_aliases:

   driver = aliasfile

   query = select dest from virtual where alias='${quote_mysql:${local_part}}'

   search_type = mysql

userforward:

  driver = forwardfile

  file_transport = address_file

  pipe_transport = address_pipe

  reply_transport = address_reply

  no_verify

  check_ancestor

  check_local_user

  file = .forward

  modemask = 002

  filter

procmail:   driver = localuser

  transport = procmail_pipe

  require_files = ${local_part}:+${home}:+${home}/.procmailrc:+/usr/bin/procmail

  no_verify

   

localuser:

  driver = localuser

  transport = local_delivery

 

cyrus_user:

  driver = smartuser

  transport = cyrus_delivery

 

end

 

############################

#  ROUTERS CONFIGURATION                    #

#  Specifies how remote addresses are handled           #

############################

#   ORDER DOES MATTER                         #

# A remote address is passed to each in turn until it is accepted.  #

#############################

lookuphost:

  driver = lookuphost

  transport = remote_smtp

 

literal:

  driver = ipliteral

  transport = remote_smtp

 

end

 

#############################

#  RETRY CONFIGURATION                   #

##############################

# Domain            Error       Retries

# ---               ---       ----

 

*                 *           F,2h,15m; G,16h,2h,1.5; F,4d,8h

 

end

 

#############################

#  REWRITE CONFIGURATION                #

#############################

#*@domain.com    ${lookup{$1}lsearch{/etc/email-addresses}\

#                                               {$value}fail} frFs

 

end

 

###############################

#  AUTHENTICATION CONFIGURATION        #

################################

 

 plain:

   driver = plaintext

   public_name = PLAIN

   server_condition = "${if pam{$2:$3}{yes}{no}}"

   server_set_id = $2

 login:

   driver = plaintext

   public_name = LOGIN

   server_prompts = "Username:: : Password::"

   server_condition = "${if pam{$1:$2}{yes}{no}}"

   server_set_id = $1

# End of Exim configuration file

4. Information

Philip Hazel, Exim. The Mail Transfer Agent. Official Guide for Release 3. O'Reilly and Associates, Inc. 2001

http://www.exim.org

HOWTO: http://www.delouw.ch/linux/Postfix-Cyrus-Web-cyradm-HOWTO/html/index.html by Luc de Louw

http://www.web-cyradm.org

5. Author

Alexander Goeres, mailto: agoeres at lieblinx.net, July 2003, at home at lieblinxNET

6. About this document ...

This document was generated using the LaTeX2HTML translator Version 99.2beta8 (1.43)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.



agoeres@lieblinx.net