Mailman/MTA

Near the top of the exim4.conf file, there are several macros related to Mailman. These define system-specific settings/locations used by the router(s) and transport(s) in the rest of the configuration file. For a Debian/Ubuntu Mailman package, the following macro's are accurate:
 # Mailman
 MAILMAN_HOME = /usr/lib/mailman
 MAILMAN_LISTS_HOME = /var/lib/mailman
 MAILMAN_WRAP = MAILMAN_HOME/mail/mailman
 MAILMAN_UID = list
 MAILMAN_GID = list
There's a domain list that contains a list of all domains that can "contain" mailing lists, i.e. the domains for which the Mailman router(s) should run. This list is also used as part of the "local domains" list, the list for which this mail server accepts mail and handles it locally.
 domainlist mailman_domains = lists.wikimedia.org
 domainlist local_domains = +system_domains : +mailman_domains
==== Main configuration ====
Several tweaks have been made to the main configuration to make Mailman delivery go smooth.
In case of high load / lots of incoming connections, mail from the local host (including Mailman) and other Wikimedia servers are given preference:
 smtp_reserve_hosts = <; 127.0.0.1 ; ::1 ; +wikimedia_nets
For big mailing lists, Mailman needs to send a lot of recipients per mail / connection. Per default, Exim only queues mails that have > 10 recipients, to be delivered by a subsequent queue runner, which can cause significant delays. The default Mailman limit is 500 recipients per connection, so make Exim accept that:
 smtp_accept_queue_per_connection = 500
Allow Exim to do 50 deliveries to remote hosts in parallel (this means 50 processes):
 remote_max_parallel = 50
==== Routers ====
In Exim, the routers determine if a certain e-mail address is accepted for delivery or mail transport, and how it's going to be handled (routed). For Mailman, the following list router accepts a recipient that:
* has a domain in the domain list mailman_domains
* has a Mailman configuration file matching the local part (i.e. the mailing list exists)
Certain postfixes of the localpart, e.g. "-bounces" are accepted as well.
When the router accepts the recipient address, it's set up for delivery using the list transport (see below).
# Mailman list handling. Test the mailing list address without suffix
# first, as a mailing list like wikifi-admin is a valid list name.
list:
 driver = accept
 domains = +mailman_domains
 require_files = MAILMAN_LISTS_HOME/lists/$local_part/config.pck
 transport = list
list_suffix:
 driver = accept
 domains = +mailman_domains
 require_files = MAILMAN_LISTS_HOME/lists/$local_part/config.pck
 local_part_suffix = -bounces : -bounces+* : \
 -confirm+* : -join : -leave : \
 -owner : -request : -admin : \
 -subscribe : -unsubscribe
 transport = list
If the conditions for this router fail (i.e. the router is not run) then the no_more makes sure that no subsequent routers will be tried (in the current configuration there are none that might accept), and the recipient address is failed.
==== Transports ====
An Exim transport configures a way of transporting a message, e.g. over the network (SMTP), to a file (MBOX/Maildir/etc) or using a pipe to a process. The following transport sets up delivery to Mailman:
# Mailman pipe transport
list:
 driver = pipe
 command = MAILMAN_WRAP \
 '${if def:local_part_suffix \
 {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
 {post}}' \
 $local_part
 current_directory = MAILMAN_LISTS_HOME
 home_directory = MAILMAN_LISTS_HOME
 user = MAILMAN_UID
 group = MAILMAN_GID
For content scanning, temporary mbox files are written to /var/spool/exim4/scan, and deleted after scanning. Similarly, Exim keeps "hints" databases in /var/spool/exim4/db, which are non-essential caches. To improve performance somewhat, these directory is mounted as a tmpfs filesystem, using the following line in /etc/fstab:
 tmpfs /var/spool/exim4/scan tmpfs defaults 0 0
 tmpfs /var/spool/exim4/db tmpfs defaults 0 0
==== Mailing list privacy protection ====
It has happened in the past that by hitting on the Reply All button in one's e-mail client, private info from an internal list leaked to a public mailing list because it was listed in the CC list, and the imprudent sender did not notice. In order to try to catch these incidents, a little filter has been implemented.
# If the To: or CC: of a message body matches an item in a list of private mailing list addresses, and
# the list of recipients as known by the mailing list server contains a Wikimedia mailing list that's not a private mailing lists, then
# the message is bounced with the message Message rejected for privacy protection: The list of recipients contains both private and public lists.
It's possible to circumvent this restriction by sending to the private list as a BCC, Blind Carbon Copy.
This filter is implemented using an Exim system filter:
# Exim filter
# Mailing list privacy protection
if foranyaddress $h_To:,$h_Cc: ( $thisaddress matches "\\N^(internal-l|private-l)@(lists\.|mail\.)?wiki[mp]edia\.org$\\N" ) then
 if foranyaddress $recipients ( $thisaddress matches "\\N@lists\.wikimedia\.org$\\N" and $thisaddress does not match "\\N^(internal-l|private-l)@\\N" ) then
 fail text "Message rejected for privacy protection: The list of recipients contains both private and public mailing lists"
 endif
endif
This filter is enabled in the configuration file using
 system_filter = CONFDIR/system_filter
==== Address header rewriting ====
It turned out that, after the migration, many users kept sending mails to both the old and the new mailing list addresses, thereby causing duplicate messages. To reduce this, Exim has been configured to rewrite the old mailing list addresses to the new ones in the To: and CC: headers, using the following option on the list transport:
list:
 ...
 # Rewrite body headers of old mailing list addresses to new ones
 headers_rewrite = \N^.*@(mail\.)?wiki[mp]edia\.org$\N "${if exists{MAILMAN_LISTS_HOME/lists/$local_part/config.pck}{$local_part@lists.wikimedia.org}fail}" ct