NetBSD/gnu/dist/postfix/LMTP_README

467 lines
16 KiB
Plaintext

[This file still needs to be updated - some information is obsolete]
1 - Postfix LMTP support
========================
LMTP stands for Local Mail Transfer Protocol, and is detailed in
RFC2033. Postfix uses this protocol to communicate with the final
delivery agent, which may run on the local host or a remote host.
This protocol opens up interesting possibilities: one Postfix front
end machine can drive multiple mailbox back end machines over LMTP.
As the mail load increases, you add more Postfix front end systems
and more LMTP mailbox back end systems. This is the model that I
had in mind when I began drafting the design for Postfix - a scalable
architecture that allows you to keep adding SMTP servers and mailbox
servers painlessly.
Such a distributed architecture needs glue to keep things together.
You can use a networked database LDAP or mysql to share the user
database among the front end and back end systems. Use a replicated
database so that no machine becomes a single point of failure for
the entire mail infrastructure.
Postfix LMTP support is based on a modified version of the Postfix
SMTP client. The initial version was by Philip A. Prindeville of
Mirapoint, Inc., USA. This code was modified further by Amos Gouaux
of University of Texas at Dallas, Richardson, USA, who also revised
much of the documentation. Wietse Venema reduced the code to its
present shape.
2 - Overview
============
Most of the examples in this document involve the CMU Cyrus IMAP/POP
server, available from:
http://asg.web.cmu.edu/cyrus/
While certainly not the only application that could make use of
LMTP, it tends to be the most discussed. These examples are based
on the forthcoming Cyrus 2.0.10, at least at the time of writing.
The 2.x branch of Cyrus places greater emphasis on LMTP delivery
than the previous releases. Those using older releases of Cyrus
can find a discussion in the appendix of this document.
There are a variety of ways LMTP delivery can be configured in
Postfix. The two basic flavors are delivery over UNIX-domain
sockets and delivery over TCP sockets.
o Connections over UNIX-domain sockets limit delivery to LMTP
servers running on the same machine.
o Connections over TCP sockets allow you to deliver to LMTP
servers across a local network.
The precise syntax for UNIX-domain and TCP connection endpoints is
given in the lmtp(8) manual page. Examples are also given in the
text below.
Both socket flavors can be specified in either the Postfix main.cf
file (see section 5) or in a Postfix transport map (section 6).
What is the best approach for you depends upon the arrangement of
your servers and the desired level of parallelization.
Please be sure to study this entire document as there are trade-offs
in convenience and in performance with these different approaches.
3 - LMTP over UNIX-domain sockets
=================================
A UNIX-domain socket is specified as the socket type ("unix") and
a name in the local file system:
unix:/path/name
The "/path/name" part should be the name of a socket created by
the LMTP server on the local machine. See the specific examples
later in this document.
NOTE:
If you run the lmtp client chrooted, the interpretation of the
/path/name is relative to the Postfix queue directory (typically,
/var/spool/postfix).
By default, the Postfix LMTP client does not run chrooted.
With LMTP delivery to the local machine there is no good reason
to run the Postfix LMTP client chrooted.
4 - LMTP over TCP sockets
=========================
A TCP destination is specified as the socket type ("inet"), the
destination hostname and the TCP port:
inet:hostname:port
The "inet:" part can be omitted, as it is the default socket type.
The destination port can be omitted as well. Currently the default
TCP port number for this type of connection is 24, but this can be
customized in the "/etc/services" file. Specific examples are
given later in this document.
NOTE:
With connections over TCP sockets, later Cyrus LMTP server
implementations insist on SASL-style authentication. This means
that Postfix must be built with SASL support (see SASL_README).
The examples below show how to enable this in the Postfix LMTP
client.
Some Cyrus LMTP server implementations do not allow SASL-style
authentication via plaintext passwords. You will have to jump
some extra hoops in order to enable MD5 password support, or
you will have to wait until this restriction is relaxed.
5 - Configuring LMTP using main.cf configuration
================================================
This is the simplest LMTP configuration.
5.1 - Delivery mechanisms
-------------------------
Postfix main.cf supports three mechanisms to deliver mail over
LMTP. Each method can use UNIX-domain or TCP sockets as described
in a later section.
main.cf mechanism 1
-------------------
mailbox_transport = lmtp:unix:/path/name (UNIX-domain socket example)
mailbox_transport = lmtp:hostname:port (TCP socket example)
Mail that resolves as local (domain is listed in $mydestination)
is given to the Postfix local delivery agent. The Postfix local
delivery agent expands aliases and .forward files, and delegates
mailbox delivery to the LMTP server.
main.cf mechanism 2
-------------------
local_transport = lmtp:unix:/path/name (UNIX-domain socket example)
local_transport = lmtp:hostname:port (TCP socket example)
Mail that resolves as local (domain is listed in $mydestination)
is directly given to the LMTP server. The mail is not processed
by the Postfix local delivery agent; therefore aliases and .forward
files are not processed.
main.cf mechanism 3
-------------------
fallback_transport = lmtp:unix:/path/name (UNIX-domain socket example)
fallback_transport = lmtp:hostname:port (TCP socket example)
Mail that resolves as local (domain is listed in $mydestination)
is given to the Postfix local delivery agent. The Postfix local
delivery agent processes aliases and .forward files, and delivers
to /var[/spool]/mail/$user for users that have a UNIX account.
Mail for other local users is delegated to the LMTP server.
5.2 - Examples
--------------
5.2.1 - LMTP over UNIX-domain sockets
-------------------------------------
To utilize UNIX-domain sockets for the communication between
Postfix and Cyrus, the corresponding configuration files should
look something like this:
/etc/cyrus.conf:
SERVICES {
...
lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
...
}
/etc/postfix/main.cf:
mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
In this case, the Postfix local delivery agent expands aliases
and .forward files, and delegates mailbox delivery to the Cyrus
lmtpd server via the socket "/var/imap/socket/lmtp".
5.2.2 - LMTP over TCP sockets
-----------------------------
For this example, suppose the following files are configured
thusly:
/etc/cyrus.conf:
SERVICES {
...
lmtp cmd="lmtpd" listen="127.0.0.1:lmtp" prefork=0
...
}
/etc/services:
lmtp 24/tcp
/etc/postfix/main.cf:
mailbox_transport = lmtp:localhost
lmtp_sasl_auth_enable = yes
lmtp_sasl_password_maps = hash:/etc/postfix/lmtp_sasl_pass
/etc/postfix/master.cf:
lmtp unix - - n - - lmtp
/etc/postfix/lmtp_sasl_pass:
localhost.my.domain username:password
Instead of "hash", use the map type of your choice. Some systems
use "dbm" instead. Use "postconf -m" to find out what map types
are supported.
With the above settings, the Postfix local delivery agent expands
aliases and .forward files, and delegates mailbox delivery to the
the Cyrus LMTP server. Postfix makes a connection to port 24 on
the local host, subsequently transmitting the message to the lmtpd
server managed by the Cyrus master process.
6 - Configuring LMTP using transport map configuration
======================================================
This approach is quite similar to specifying the LMTP service in
the Postfix main.cf configuration file. However, now we will use
a transport map to route mail to the appropriate LMTP server,
instead of depending on delegation by the Postfix local delivery
agent.
Why might this approach be useful? This could be handy if you wish
to route mail for multiple domains to their respective mail retrieval
(IMAP/POP) server. Example:
/etc/postfix/transport:
domain1.name lmtp1:unix:/path/name
domain2.name lmtp2:lmtp2host
/etc/postfix/master.cf:
lmtp1 unix - - n - - lmtp
lmtp2 unix - - n - - lmtp
/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport
For details of the Cyrus LMTP server configuration, see section 5.
Instead of "hash", use the map type of your choice. Some systems use
"dbm" instead. Use "postconf -m" to find out what map types are
supported.
7 - Performance considerations
==============================
Hopefully the preceding discussion has seemed pretty straight
forward. Now things get interesting. After reading the following
you will see that there are more factors to consider when setting
up LMTP services.
8 - Single instance message store
=================================
Presently this topic is more pertinent to sites running Cyrus, but
may be a factor with other applications as well.
Since 1.6.22, Cyrus has had the feature that if a message containing
multiple recipients is received via the LMTP protocol, and all
these recipients were on the same Cyrus partition, only one instance
of this message would be written to the file system. The other
recipients would then see a hard link of this single instance.
Depending on your user base, this can be considerable motivation
to using LMTP.
However, there is a catch: the Postfix local delivery agent is
designed to deliver one recipient at a time, which in most cases
is more than adequate. So, if you wish to support single instance
message store delivery, you will have to use a virtual table to
map these users to the appropriate LMTP destination (at the time
of writing, the Postfix transport table supports only per-domain
routing, and not per-recipient routing).
While the simplest thing to do would be to list the entire domain
in the transport map for LMTP delivery, this by-passes alias
expansion for otherwise local addresses (see section 5.1, delivery
mechanism 2). If the site is to run software via aliases, like
most Mailing List Management (MLM) software, a more complex solution
is required. A virtual table should do the trick.
As an example, suppose we wanted to support single instance message
store delivery for the hosted (not local) domain "example.org".
The configuration files for this domain could look something like
this:
/etc/postfix/virtual:
mlist@example.org mlist@localhost
/etc/postfix/transport:
example.org lmtp:unix:/var/imap/socket/lmtp
/etc/postfix/aliases:
mlist: "|/path/to/mlm/software"
/etc/postfix/master.cf:
lmtp unix - - n - - lmtp
/etc/postfix/main.cf:
mydestination = localhost, $myhostname, $mydomain
virtual_maps = hash:/etc/postfix/virtual
transport_maps = hash:/etc/postfix/transport
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
/etc/cyrus.conf:
SERVICES {
...
lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=1
...
}
Breaking things down, we begin with the address "mlist@example.org",
which represents a mailing list. By placing an entry in the virtual
map to direct this mail to "mlist@localhost", we can override the
transport map that would by default route all "@example.org" mail
to a LMTP server via a UNIX-domain socket.
To summarize, all mail that is to be processed by an alias entry
must first be diverted with a virtual table entry so that it does
not fall into the more general routing established by the transport
table.
9 - Improving connection caching performance
============================================
After delivering a message via LMTP, Postfix will keep the connection
open for a while, so that it can be reused for a subsequent delivery.
This reduces overhead of LMTP servers that create one process per
connection.
For LMTP connection caching to work, the Postfix LMTP client should
not switch destination hosts. This is no problem when you run only
one LMTP server. However, if you run multiple LMTP servers, this
can be an issue.
You can prevent the LMTP client from switching between servers by
configuring a separate LMTP delivery transport for each LMTP server:
/etc/postfix/master.cf:
lmtp1 unix - - n - - lmtp
lmtp2 unix - - n - - lmtp
. . . . . . . .
Configure transport table entries such that the lmtp1 mail delivery
transport is used for all deliveries to the LMTP server #1, the
mail lmtp2 transport for the LMTP server #2, and so on.
/etc/postfix/transport:
foo.com lmtp1:lmtp1host
bar.com lmtp2:lmtp2host
10 - Appendix: Older Cyrus versions
===================================
First of all, if you are using a Cyrus 2.x version prior to 2.0.10,
it would be good to upgrade. The previous 2.x releases were beta
releases, and numerous bug fixes and enhancements have been
incorporated into the 2.0.10 release.
Further back, 1.6.24 was the last pre-2.x production release.
(Actually, there was a 1.6.25-BETA, but it is uncertain whether this
will be released officially as CMU is now focusing support on the 2.x
branch.) The following discussion touches on how to configure the
Postfix LMTP facilities with Cyrus 1.6.24.
One of the significant differences between Cyrus 1.x and 2.x is the
inclusion of the "master" process in 2.x. This "master" process is
responsible for running the various components of Cyrus, such as
imapd, pop3d, and lmtpd. Prior to 2.x, these services were managed
by inetd, the Internet services daemon.
To utilize LMTP delivery with Cyrus 1.6.24, the first thing to do is
configure inetd. This involves the following file edits:
/etc/services:
lmtp 24/tcp
/etc/inetd.conf:
lmtp stream tcp nowait cyrus /usr/sbin/tcpd /usr/cyrus/bin/deliver -e -l
/etc/hosts.allow:
deliver : localhost : ALLOW
deliver : ALL@ALL : DENY
The "/usr/sbin/tcpd" is from the tcp_wrappers package, which is
discussed in the example "LMTP over TCP sockets, using hosts.allow."
It is important that you wrap this LMTP port to protect it from
unauthorized access.
On some systems, tcpd is built into inetd, so you do not have to
specify tcpd in the inetd.conf file. Instead of tcpd/inetd, xinetd
can do a similar job of logging and access control.
Now comes the Postfix configuration. Basically, the Cyrus 2.x
discussions regarding LMTP delivery over TCP are also applicable to
Cyrus 1.x, with the exception of the "/etc/cyrus.conf" file. A
typical Postfix configuration might look like this:
/etc/postfix/master.cf:
lmtp unix - - n - - lmtp
/etc/postfix/main.cf:
mailbox_transport = lmtp
It is also possible to use the transport map to route mail to your
Cyrus 1.6.24 LMTP server:
/etc/postfix/transport:
domain1.name lmtp1:lmtp1host
domain2.name lmtp2:lmtp2host
/etc/postfix/master.cf:
lmtp1 unix - - n - - lmtp
lmtp2 unix - - n - - lmtp
/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport
If you have read the discussion covering the Cyrus 2.x installation,
you will notice the one significant difference with the Postfix
configuration is the lack of mention of the UNIX-domain sockets.
That is because delivery over UNIX-domain sockets is new with Cyrus
2.x, yet another reason to upgrade. :-)