Here's a way to integrate mailman with Exim4 that will automatically
play nice with mailman's virtual domains support and VERP. It does not
require dedicating domain(s) to mailman.

Configure your Mailman (in /etc/mailman/mm_cfg.py) with:

MTA = 'Postfix'
POSTFIX_ALIAS_CMD = '/bin/true'
POSTFIX_MAP_CMD = 'chgrp Debian-exim'

and list all your Mailman domains in "POSTFIX_STYLE_VIRTUAL_DOMAINS":

POSTFIX_STYLE_VIRTUAL_DOMAINS = [ 'example.com', 'example.org' ]

Please note that the chgrp command above will not work when creating a
list in the web interface: the user www-data will not be allowed to do
this. You can circumvent this problem by creating new lists with the
'newlist' command line command or using instead:
POSTFIX_MAP_CMD = 'chmod o+r'
This will allow local users (with shell access to the list server) to
see the list of all Mailman mailing lists, but not much more.

If you have created lists before making those changes to mm_cfg.py
(and you are not going to create others before running the system in
production), you need to run /var/lib/mailman/bin/genaliases once; it
will be done automatically every time you create / delete a mailing
list in the future.

And yes, the "Postfix" there is on purpose, it should not be replaced
by "exim4". It causes mailman to (among others) create a list of
mailman lists, including what virtual domain they should be in. That
is the information that is used here; the rest is ignored.

Put this in your exim4 main configuration (if you use a split config,
for example /etc/exim4/conf.d/main/04_local_mailman_macros)

---------------------- BEGIN EXIM4 MAIN   ----------------------------
# Home dir for your Mailman installation -- aka Mailman's prefix
# directory.
MAILMAN_HOME=/var/lib/mailman
MAILMAN_WRAP=MAILMAN_HOME/mail/mailman

# User and group for Mailman, should match your --with-mail-gid
# switch to Mailman's configure script.
MAILMAN_USER=list
MAILMAN_GROUP=daemon

# Where to store messages sent to mailman-loop - used if the
# mailman-owner addressbounces.
MAILMAN_LOOP=MAILMAN_HOME/data/owner-bounces.mbox
----------------------  END EXIM4 MAIN    ----------------------------

Put this in your exim4 router configuration (if you use a split
config, then for example /etc/exim4/conf.d/router/970_local_mailman)

---------------------- BEGIN EXIM4 ROUTER ----------------------------
# Messages get sent out with
# envelope from "mailman-bounces@virtual_domain"
# But mailman doesn't put such addresses
# in the aliases. Recognise these here.
mailman_workaround:
  debug_print = "R: mailman_workaround for $local_part@$domain"
  domains = +local_domains
  require_files = MAILMAN_HOME/lists/$local_part/config.pck
  driver = accept
  local_parts = mailman
  local_part_suffix_optional
  local_part_suffix = -bounces : -bounces+* : \
           -confirm+* : -join : -leave : \
           -subscribe : -unsubscribe : \
           -owner : -request : -admin
  transport = mailman_transport
  group = MAILMAN_GROUP

# We need to handle the mailman-loop separately from the other addresses
# since the loop action is not handled by the wrapper.
mailman_loop_router:
  debug_print = "R: mailman_loop for $local_part@$domain"
  domains = +local_domains
  require_files = MAILMAN_HOME/lists/$local_part/config.pck
  driver = accept
  local_parts = mailman
  transport = mailman_loop_transport
  local_part_suffix = -loop
  group = MAILMAN_GROUP

# Mailman lists
mailman_router:
  debug_print = "R: mailman_router for $local_part@$domain"
  domains = +local_domains
  condition = ${lookup{$local_part@$domain}lsearch{MAILMAN_HOME/data/virtual-mailman}{1}{0}}
  require_files = MAILMAN_HOME/lists/$local_part/config.pck
  driver = accept
  local_part_suffix_optional
  local_part_suffix = -bounces : -bounces+* : \
                      -confirm+* : -join : -leave : \
                      -subscribe : -unsubscribe : \
                      -owner : -request : -admin
  transport = mailman_transport
  group = MAILMAN_GROUP
----------------------  END EXIM4 ROUTER  ----------------------------

Put this in your exim4 transport configuration (if you use a split
config, then for example /etc/exim4/conf.d/transport/40_local_mailman)

---------------------- BEGIN EXIM4 TRANSPORT -------------------------
mailman_transport:
  debug_print = "T: mailman_transport for $local_part@$domain"
  driver = pipe
  command = MAILMAN_WRAP \
            '${if def:local_part_suffix \
                  {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
                  {post}}' \
            $local_part
  current_directory = MAILMAN_HOME
  home_directory = MAILMAN_HOME
  user = MAILMAN_USER
  group = MAILMAN_GROUP
  freeze_exec_fail = true

mailman_loop_transport:
  driver = appendfile
  file = MAILMAN_LOOP
  delivery_date_add
  envelope_to_add
  return_path_add
  user = MAILMAN_USER
  group = MAILMAN_GROUP
----------------------  END EXIM4 TRANSPORT  -------------------------

You are done!

 -- Lionel Elie Mamane <lmamane@debian.org>, Fri, 20 Mar 2009 09:27:39 +0100
