467 lines
16 KiB
Plaintext
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. :-)
|