Howto: qmail and mailman
Last updated 9 August 2023
I'm one of those people who like the qmail way of doing things. I'm also on of those people who like mailman. Both is simple, clearly defined and is understandable. I had a few issues with getting them to play nice together though.
The setup I'll be assuming in this howto is that used by Gentoo, specifically net-mail/mailman-2.1.5 where installation is into /usr/local/mailman. The contrib binaries are also installed into the bin directory. Other than that it is a standard install as far as I know.
I found it relatively problematic to get all the correct mails delivered to mailman the way it was described in the sparse documentation that I did find. In this document I'm hoping to clear up some things and help administrators to quickly, and effectively set up their qmail and mailman installations.
We will only be affected by a few users, those of qmail (clearly described in Life With QMail) and then the mailman user, which in my case has uid and gid 280, and is also part of the cron group (in order to be able to run cron jobs). The following should describe the users involved:
uid=280(mailman) gid=280(mailman) groups=280(mailman),16(cron) uid=200(alias) gid=200(nofiles) groups=200(nofiles)
The basic qmail setup
qmail is set up to deliver to ./.maildir/ by default, smtp for localhost, qmail-send delivers local mail and forwards all other mail via belrog.lan. locals and rcpthosts only contains pug.lan. This works absolutely fabiously.
qmail is a breeze to set up, I recommend a document Life With QMail. Everything about qmail is explained clearly and should allow you to get your mail system up to scratch in about half an hour. I should make an ammendment here: It's a breeze to set up if you are using a proper distro like Debian or Gentoo, on distro's like SuSE it's a bitch to get everything to work. There are also various patches that the debian and gentoo packages takes care off (whilst most of these are not required I highly recommend some of them - like the QMAILQUEUE patch). You may want to consider netqmail which is qmail with a few patches added.
I can also recommend courier-imap for pop3/imap. It's setup is easy and effective.
Adding mailman to the picture
Configuring mailman in itself was a pain in the backside. Here is a quick list of commands to run:
These basically install the crontab, set up the mailman password (for the web interface), create the base mailman mailing list and start the mailman daemon. Type these commands excactly as above, enter the password when prompted and enter your mail address (I used postmaster, the reasoning is that whoever postmaster goes to is probably the person in charge of the mailman setup anyway. The last line is gentoo specific and is only there to add mailman to the default runlevel.
Configuring the basic mailman aliases
By default only mail sent to firstname.lastname@example.org will get delivered, and then qmail will attempt to deliver the mail to ~mailman/.maildir/, which is not what we want. For this reason we need to create some aliases, and we need to change the way in which mail is delivered to mailman.
When mail is delivered to mailman, we should execute ~mailman/mail/mailman with two parameters, the first is the command, which can be one of:
For each of these we need to create a .qmail file in ~mailman. We also need to pass the message through preline first in order to make sure that we have a valid From: field in the message. The following script achieves what we want:
#! /bin/bash echo "|preline /usr/local/mailman/mail/mailman post mailman" > ~mailman/.qmail for i in admin owner bounces confirm join leave subscribe unsubscribe request do echo "|preline /usr/local/mailman/mail/mailman $i mailman" > ~mailman/.qmail-$i done ln -s ~mailman/.qmail-bounces ~mailman/.qmail-bounces-default
This is relatively obvious, mailman@ should go to post, the remainder all need to go to their appropriate places. The symbolic link is in order for VERP to work properly if enabled.
After these you should be able to subscribe to the mailman mailing list, send mail to it and receive again. Play around.
Last touches to mailman
Only one more thing remains to be done for mailman and that is to create a .qmail-default file for all other lists. The content of this file should be:
|preline /usr/bin/python /usr/local/mailman/bin/qmail-to-mailman.py
And one needs to edit the bin/qmail-to-mailman.py file slightly in order to get things working. There is 3 config variables need the top of the file which you need to edit. Mine looks like:
# Configuration variables - Change these for your site if necessary. MailmanHome = "/usr/local/mailman"; # Mailman home directory. MailmanVar = "/usr/local/mailman"; # Mailman directory for mutable data. MailmanOwner = "email@example.com"; # Postmaster and abuse mail recepient. # End of configuration variables.
This script will look at the to part of the mail (using the LOCAL environment variable as supplied by qmail-local). It then proceeds to execute the mailman program with the appropriate parameters. It automatically bounces any messages to invalid addresses.
It however contains a bug. It cannot handle VERP by default, it basically checks for "-bounces$". I therefor wrote a patch that fixes this problem by also adding an action for -bounces[-+].*$:
Adding mailing lists
This is achieved by doing:
Simply fill in the details as requested and you are done with the mailman side. This can also be done via the web interface.
In order to get qmail to play with we only need to add a single entry to the users assign file /var/qmail/users/assign. This line needs to match listname*@... and deliver it to the mailman user with the appropriate LOCAL environment variable set. A line such as:
achieves this. Your list should now be working correctly after you have run qmail-newu as root.
Just worked for me, I did not have any issues other than having had to restart apache after installing mailman. It basically uses /mailman/* to admin mailman and /pipermail/* for archives. All administration, including adding lists (except for the entry to be added to /var/qmail/users/assign.
VERP stands for Variable Envelope Return Path. It ensures that each message that gets sent out has a different return path (where to send bounces to). This means that the address to which a message bounces can be used to determine the address the message was sent to. To see why this is usefull, consider the situation where I subscribe firstname.lastname@example.org to a list email@example.com, I then make firstname.lastname@example.org forward to email@example.com. Should the message then bounce when attempting to deliver to fred it is not always possible from the bounce to determine that the message was orriginally sent out to firstname.lastname@example.org. It also means that we don't need to parse any email addresses since we can simply look at the address that the message bounced to and it is thus simple to find the quilty address (It means admins like me won't have to send out a few thousand individual messages when there is one user where the above holds in order to determine which address to nuke from the list). An additional advantage is that it allows us to send bounces off to mailman and the admin don't have to see a bounce in his life.
Whilst Mailman can still do VERP without help from the MTA getting the MTA to perform VERP is much more efficient. Thus I recommend following the instructions below in order to VERP every single message without (much) additional overhead.
To configure VERP to work with qmail we need a single file from https://sourceforge.net/tracker/?func=detail&atid=300103&aid=645513&group_id=103. On the page you should find a download link for Qmail.py. Store this file in ~mailman/Mailman/MTA. To actually make use of this module it is required to edit ~/mailman/Mailman/mm_cfg.py and add the following lines
As you can see, the lines are devided into two blocks. The upper block is required config, the bottom few is optional, but is required to actually activate VERP
This concludes everything I know about integrating qmail and mailman, and making it use VERP. I hope it was usefull, if welcome any comments, suggestions and/or corrections.