Size: 1794
Comment:
|
Size: 7801
Comment: Added example for transport table with dedicated service
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
#pragma page-filename DEV/versions/3604513 | #pragma page-filename DEV/versions/7602192 |
Line 15: | Line 15: |
accept (perhaps unless the sender address is forbidden to post to all | accept (perhaps unless the sender address is forbidden to post to all |
Line 18: | Line 18: |
accept if the sender has permissions to post to the list, otherwise reject. This is the last chance to give a list specific response to an MTA that is |
accept if the sender has permissions to post to the list, otherwise reject. This is the last chance to give a list specific response to an MTA that is |
Line 22: | Line 22: |
reject null senders here if appropriate. Rejecting a null sender at RCPT TO | reject null senders here if appropriate. Rejecting a null sender at RCPT TO |
Line 26: | Line 26: |
Check the data, reject if inappropriate for a specific list (but this is likely to cause a bounce from our MTA). Because we've decided to trust the sender, we should be OK to bounce a message here, unless the list is an |
Check the data, reject if inappropriate for a specific list (but this is likely to cause a bounce from our MTA). Because we've decided to trust the sender, we should be OK to bounce a message here, unless the list is an |
Line 32: | Line 32: |
I believe MM3's architecture can easily support this, and I've been working with Ian on the mailing list to sketch out a design. I think we should do this for MM3. Ian also describes a useful set of enhanced error codes: {{{ X.1.1 Bad destination mailbox address X.2.4 Mailing list expansion problem X.5.3 Too many recipients X.7.2 Mailing list expansion prohibited The sender is not authorized to send a message to the intended mailing list. X is 4 for a temporary error, 5 for a permanent error. }}} For details see: * [[http://www.faqs.org/rfcs/rfc1893.html|RFC 1893 - Enhanced Mail System Status Codes]] * [[http://www.faqs.org/rfcs/rfc2034.html|RFC 2034 - SMTP Service Extension for Returning Enhanced Error Codes]] == LTMP with various MTAs == Here is detailed information about how Mailman should integrate with the various MTAs using LMTP. === Postfix === Postfix uses the Postfix {{{lmtp}}} client to transport messages to a LMTP server. The defaults for this client are configured in {{{master.cf}}}: {{{ 1. ========================================================================== 1. service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) 1. ========================================================================== ... lmtp unix - - - - - lmtp ... }}} ==== Transporting messages to mailman LMTP server ==== Create a {{{transport}}}(5) type table e.g. {{{/etc/postfix/mailman_lists}}} and add each mailman mailing list address on a single line as key to the left hand side of the transport table. For each key specify the destination of the LMTP server as value. {{{{#!wiki warning Always specify mail addresses as FQDN mail addresses. If not the trivial-rewrite agent might "fix" an imcomplete mail address adding {{{$myorigin}}}, which might result in a wrong destination. }}}} {{{{#!wiki caution A destination consists of the service name, the hostname or IP address and the (optional) port each separated by a colon. If the optional LMTP port is omitted the Postfix {{{lmtp}}} client will use {{{$lmtp_tcp_port}}} (default: 24). }}}} Here's an example of {{{/etc/postfix/mailman_lists}}}: {{{ 1. key value mailman@example.org lmtp:localhost mailman-admin@example.org lmtp:localhost mailman-bounces@example.org lmtp:localhost mailman-confirm@example.org lmtp:localhost mailman-join@example.org lmtp:localhost mailman-leave@example.org lmtp:localhost mailman-owner@example.org lmtp:localhost mailman-request@example.org lmtp:localhost mailman-subscribe@example.org lmtp:localhost mailman-unsubscribe@example.org lmtp:localhost }}} Once all entries have been added to the {{{/etc/postfix/mailman_lists}}} file use the Postfix {{{postmap}}} command to create a database: {{{ # postmap /etc/postfix/mailman_lists }}} Then add the database to the list of {{{$transport_maps}}} in Postfix' {{{main.cf}}} configuration file: {{{ transport_maps: ... hash:/etc/postfix/mailman_lists ... }}} Once Postfix has been reloaded the new settings will take effect. ==== A dedicated list server ==== For a dedicated list server e.g. ''list.example.com'' simply add the hostname as key to a transport map and specify the mailman LMTP server as destination: {{{ 1. key value list.example.org lmtp:localhost }}} Be aware though that Postfix has no knowledge of valid recipients in the destination's (sub)domain (here: list.example.org) if you specify the list server as noted above. Postfix will accept and transport any message destined for ''list.example.org'' to the mailman LMTP server and it will be the LMTP servers task to reject messages for invalid or non-existing recipients. There are two ways to prevent putting such load on the mailman LMTP server. First specify each valid recipient address in a transport table as shown in the initial example. Alternatively use the {{{reject_unverified_recipient}}} option and let the Postfix {{{verify}}}(8) daemon find out if the recipient address exists. This way Postfix will reject messages to non-exsisting recipients during the SMTP session with the client that attempts to deliver the message. See {{{ADDRESS_VERIFICATION_README}}} for details on implementing the reject_unverified_recipient option. ==== A dedicated lmtp client ==== There may be situations where a dedicated lmtp client, that differs in its configuration from the default lmtp client settings, is required. To create such a client add a new service (here: ''mailman'') to the Postfix {{{master.cf}}} configuration file and add the configuration options which should override the default lmtp client behaviour: {{{ 1. ========================================================================== 1. service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) 1. ========================================================================== ... mailman unix - - - - - lmtp -o lmtp_send_xforward_command=yes -o disable_dns_lookups=yes ... }}} Then specify the new service in the transport table e.g. {{{/etc/postfix/mailman_lists:}}} {{{ 1. key value mailman@example.org lmtp:mailman mailman-admin@example.org lmtp:mailman mailman-bounces@example.org lmtp:mailman mailman-confirm@example.org lmtp:mailman }}} === Exim === === Sendmail === |
LMTP in Mailman
RFC 2033, Local Mail Transport Protocol (LMTP) provides Mailman with a unique opportunity to provide a better user experience when accepting initial postings. Two improvements in the process are available with LMTP.
First, we can eliminate most of the integration cruft we currently have with supporting multiple MTAs for incoming mail. Most of the major SMTP servers support LMTP delivery, so by providing an LMTP server in Mailman, the hope is that we can avoid all the crufty MTA-specific alias hackery.
Second, and perhaps more importantly, we can support better anti-backscatter and anti-spam defenses for messages sent to the mailing lists, by rejecting messages in the SMTP dialog instead of having to make the determination way later and sending a bounce message. Ian Eiloart describes what is possible:
on connect: accept the connection HELO/EHLO: reject if the sending MTA isn't known MAIL FROM: accept (perhaps unless the sender address is forbidden to post to all lists). RCPT TO: accept if the sender has permissions to post to the list, otherwise reject. This is the last chance to give a list specific response to an MTA that is engaged in a callout. DATA: reject null senders here if appropriate. Rejecting a null sender at RCPT TO or earlier might break callouts. ............. . Check the data, reject if inappropriate for a specific list (but this is likely to cause a bounce from our MTA). Because we've decided to trust the sender, we should be OK to bounce a message here, unless the list is an open list.
I believe MM3's architecture can easily support this, and I've been working with Ian on the mailing list to sketch out a design. I think we should do this for MM3.
Ian also describes a useful set of enhanced error codes:
X.1.1 Bad destination mailbox address X.2.4 Mailing list expansion problem X.5.3 Too many recipients X.7.2 Mailing list expansion prohibited The sender is not authorized to send a message to the intended mailing list. X is 4 for a temporary error, 5 for a permanent error.
For details see:
LTMP with various MTAs
Here is detailed information about how Mailman should integrate with the various MTAs using LMTP.
Postfix
Postfix uses the Postfix lmtp client to transport messages to a LMTP server. The defaults for this client are configured in master.cf:
1. ========================================================================== 1. service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) 1. ========================================================================== ... lmtp unix - - - - - lmtp ...
Transporting messages to mailman LMTP server
Create a transport(5) type table e.g. /etc/postfix/mailman_lists and add each mailman mailing list address on a single line as key to the left hand side of the transport table. For each key specify the destination of the LMTP server as value.
Always specify mail addresses as FQDN mail addresses. If not the trivial-rewrite agent might "fix" an imcomplete mail address adding $myorigin, which might result in a wrong destination.
A destination consists of the service name, the hostname or IP address and the (optional) port each separated by a colon. If the optional LMTP port is omitted the Postfix lmtp client will use $lmtp_tcp_port (default: 24).
Here's an example of /etc/postfix/mailman_lists:
1. key value mailman@example.org lmtp:localhost mailman-admin@example.org lmtp:localhost mailman-bounces@example.org lmtp:localhost mailman-confirm@example.org lmtp:localhost mailman-join@example.org lmtp:localhost mailman-leave@example.org lmtp:localhost mailman-owner@example.org lmtp:localhost mailman-request@example.org lmtp:localhost mailman-subscribe@example.org lmtp:localhost mailman-unsubscribe@example.org lmtp:localhost
Once all entries have been added to the /etc/postfix/mailman_lists file use the Postfix postmap command to create a database:
# postmap /etc/postfix/mailman_lists
Then add the database to the list of $transport_maps in Postfix' main.cf configuration file:
transport_maps: ... hash:/etc/postfix/mailman_lists ...
Once Postfix has been reloaded the new settings will take effect.
A dedicated list server
For a dedicated list server e.g. list.example.com simply add the hostname as key to a transport map and specify the mailman LMTP server as destination:
1. key value list.example.org lmtp:localhost
Be aware though that Postfix has no knowledge of valid recipients in the destination's (sub)domain (here: list.example.org) if you specify the list server as noted above. Postfix will accept and transport any message destined for list.example.org to the mailman LMTP server and it will be the LMTP servers task to reject messages for invalid or non-existing recipients.
There are two ways to prevent putting such load on the mailman LMTP server. First specify each valid recipient address in a transport table as shown in the initial example. Alternatively use the reject_unverified_recipient option and let the Postfix verify(8) daemon find out if the recipient address exists. This way Postfix will reject messages to non-exsisting recipients during the SMTP session with the client that attempts to deliver the message. See ADDRESS_VERIFICATION_README for details on implementing the reject_unverified_recipient option.
A dedicated lmtp client
There may be situations where a dedicated lmtp client, that differs in its configuration from the default lmtp client settings, is required.
To create such a client add a new service (here: mailman) to the Postfix master.cf configuration file and add the configuration options which should override the default lmtp client behaviour:
1. ========================================================================== 1. service type private unpriv chroot wakeup maxproc command + args # (yes) (yes) (yes) (never) (100) 1. ========================================================================== ... mailman unix - - - - - lmtp -o lmtp_send_xforward_command=yes -o disable_dns_lookups=yes ...
Then specify the new service in the transport table e.g. /etc/postfix/mailman_lists:
1. key value mailman@example.org lmtp:mailman mailman-admin@example.org lmtp:mailman mailman-bounces@example.org lmtp:mailman mailman-confirm@example.org lmtp:mailman
Exim
Sendmail
Comments
William Mead has been working on LMTP code for me. He's produced implementations for version 3.0 and for version 2.2, with these tests applied after RCPT TO in the LMTP conversation:
1. message will be rejected if the list name is not known.
2. message will be accepted if the sender matches "accept_these_nonmembers".
3. message will be accepted if "generic_nonmember_action" is not reject.
4. message will be accepted if the sender is a list member.
5. if we get this far, the message will be rejected - the sender is a non-member of a closed list.
We could also reject other members if they're moderated, for example. However, we've adopted the view that it is relatively safe to generate a bounce message for someone who is a member of the list.
William has completely reimplemented the SMTPD code in Python, to support ENHANCEDSTATUSCODES, because the LMTP RFC requires that - even though the examples in the RFC don't show them being used! However, the code doesn't implement PIPELINING - also required by LMTP - because the underlying ASYNCHAT/ASYNCORE architecture doesn't seem to support it. We discovered that advertising PIPELINING causes the test smtp client to fail, but we've not even thought about how to fix that - LMTP clients which are re-implementations of SMTP clients might just live with the fact that PIPELINING isn't advertised.
William's code is at https://code.launchpad.net/~wilunix
The LMTP queue runner allows us to run Mailman on a server that's unrelated to the main MTA. With an Exim MTA, you could use a recipient callout to verify that the sender is permitted to post to the list, before accepting the message for deliver. This means that rejecting an unwanted message should not create collateral spam.