Mailman

From QmailToaster
Revision as of 08:19, 4 April 2024 by Ebroch (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Back

Some folks like myself may prefer a more user-friendly and robust List Management package for their toaster than what ezmlm-toaster provides. Mailman, the GNU Mailing List Manager is a full featured, widely used and well supported List Manager which can be used in place of, or along side of ezmlm-toaster. (Running both together shouldn't be a problem that I can think of as long as domain and list names are kept separate, but it has not been tested yet, so don't try it on a production machine without testing it first -ES).

This page documents how to install and configure Mailman on your QMail-Toaster. The procedure has been done on CentOS v5.3 through v6.5. I don't expect that the process will vary much for other supported distros. If you have installed Mailman on another QMail-Toaster distro/release, please make note of it here.

You can refer to Mailman's Site Administrator Documentation for additional details, but you shouldn't need to. This page refers to the pertinent parts. Be aware that the Site Administrator Documentation contains a lot of information that is not applicable to the QMail-Toaster. Everything you need to know for a QMT implementation is, or at least should be, contained here. If something's missing, please be sure to add it!

We'll be using a single subdomain for Lists in our configuration, referred to as lists.mydomain.com in the examples. This is because Mailman is implemented as the catchall account for a domain (the domain's .qmail-default action). This would conflict with and become broken by qmailadmin's catchall functionality if they shared the same domain. Having a separate subdomain also saves having to create a mailman email account as well as various list aliases for each list on the site, since the qmail-to-mailman.py program is smart enough to sort things out without them.

Emails addressed to a list will be in the form of mylist@lists.mydomain.com. If you prefer to have list addresses share the same primary domain as your regular email addresses (e.g. mylist@mydomain.com), see Using primary domain for list messages at the bottom of this page for an easy way to do that.


Install Mailman

The stock CentOS Mailman package unfortunately wasn't configured with vchkpw in the list of mail-gid groups. This prohibits it from running as-is on a QMT host. So to begin, you need to install a mailman package that includes this change.

If you're running QMT on CentOS 6 (or CentOS 5 with the new packages), you're in luck. There's a mailman package already built for you, so you can simply

 # yum install mailman

to install the mailman package.

If you're running the legacy *-toaster packages on CentOS 5, there is a mailman package in the qmailtoaster-plus repository with the change already made for you. If you have the qmailtoaster-plus.repo package installed, you can simply

 # yum --enablerepo=qtp-CentOS install mailman

to install the mailman package.

If you prefer rolling your own rpm, you can download and install the source rpm, modify the spec file to include vchkpw in the mailgroup parameter, then rebuild the binary rpm. Once you have done the build, you can enter the following command:

 # rpm -ivh mailman-2.1.9.*.i386.rpm

The rpm spec file has a bit of difficulty with the way the makefile works, so to resolve any troubles you should run:

 # /usr/lib/mailman/bin/check_perms -f

to be on the safe side.

Set up DNS

If you don't have a wildcard DNS record for your domain, you'll need to create a DNS record for lists.mydomain.com which resolves to your server. It can be a type A record, or a CNAME (alias) record.

You should also set up an MX record for lists.mydomain.com, the same as you have for mydomain.com. This isn't necessary if you make the configuration changes at the bottom of this page that allow mail to be sent to mydomain.com instead of the lists.mydomain.com subdomain. Allowing mail to be sent to either domain is a nice touch though, and will eliminate any problem when users send email to the wrong domain.

If you enter:

 # host lists.mydomain.com

and it resolves to your toaster, you should be all set.


Set up apache

Edit Configuration

 # vi /etc/httpd/conf.d/mailman.conf

Uncomment the last line, and on the same line change www.example.com to lists.mydomain.com.

Restart apache

Enter the following command:

 # service httpd restart

Test apache

You should now be able to go to http://lists.mydomain.com/mailman in a web browser, and see the Welcome! page for lists.mydomain.com Mailing Lists. There is nothing more to do at this page yet, so let's move on.


Review Mailman site defaults

Follow the directions at the Mailman Installation Manual: Step 7 - Review your site defaults. Substitute $prefix with /usr/lib/mailman.

Add any site-specific (non-Default) settings you like to /etc/mailman/mm_cfg.py, which is a symlink to the actual file. Do not modify the Defaults.py file, as it will be replaced when you upgrade. The mm_cfg.py file will remain intact after an upgrade, so your changes there will be preserved.

Check to be sure that DEFAULT_URL_HOST and DEFAULT_EMAIL_HOST are appropriate for your server.

Use "MTA = None", as we'll be using the qmail-to-mailman.py module, which handles all that for us.

Here is a sample of additional optional settings that I have used:

ALLOW_SITE_ADMIN_COOKIES = Yes
ARCHIVER_OBSCURES_EMAILADDRS = No
DEFAULT_ADMIN_NOTIFY_MCHANGES = Yes
DEFAULT_ARCHIVE_PRIVATE = 1
DEFAULT_ARCHIVE_VOLUME_FREQUENCY = 0
DEFAULT_DIGEST_VOLUME_FREQUENCY = 4
DEFAULT_REPLY_GOES_TO_LIST = 1
DEFAULT_SEND_REMINDERS = No
DEFAULT_SUBSCRIBE_POLICY = 3
OWNERS_CAN_ENABLE_PERSONALIZATION = Yes
VERP_CONFIRMATIONS = Yes 
VERP_DELIVERY_INTERVAL = 1
VERP_PERSONALIZED_DELIVERIES = Yes


Set up outbound mail

Local Host Delivery

If you are using the same server as Mailman (localhost) for outbound mail, you're all set, since localhost (127.) is allowed to relay as specified in your tcp.smtp file.

If you're using VERP (recommended), you might want to visit this Howto and follow the directions for VERP at the bottom of the page. This method of VERP encoding is said to be much more efficient than having Mailman do it. To my knowledge this hasn't been tested with QMT, so if you use this module, please update your findings here.

Remote Host (Relay) Delivery

If you want to use a different host for outbound messages, add the following to your mm_cfg.py file:

 SMTPHOST = 'relay.mydomain.com'
 SMTPPORT = 0                     # default from smtplib

You also need to either configure the relay.mydomain.com host to allow the Mailman host to relay, or configure the Mailman host to authenticate via SMTP_AUTH and the ASMTPDirect module, as described here. The second method is preferred.

If you use ASMTPDirect and the relay server is capable of TLS (recommended, so the password is not sent in the clear, and all traffic is encrypted), you should add the following line to the ASMTPDirect.py file, just before the self.__conn.login line:

 self.__conn.starttls()

This will initiate a TLS (secure) connection. In general, it's always good practice to use TLS where it's available.

Here's what the ASMTPDirect.py code should look like after you've changed it:

 self.__conn.connect(mm_cfg.SMTPHOST, mm_cfg.SMTPPORT)
 if mm_cfg.SMTP_TLS:
     self.__conn.starttls()
 if mm_cfg.SMTP_AUTH:
     self.__conn.login(mm_cfg.SMTP_USERNAME, mm_cfg.SMTP_PASSWORD)
 self.__numsessions = mm_cfg.SMTP_MAX_SESSIONS_PER_CONNECTION

One last thing. Some smtp servers have a problem with smtplib.py's way of authenticating. Namely, it tries AUTH_CRAM_MD5 first if it's advertised, and if it fails, no others are tried. I've created a bug report on this (http://bugs.python.org/issue6683), and Gerhard assures me that he will have it fixed in python 2.7 and 3.2. In the meantime, try applying the following patch to /usr/lib/python2.4/smtplib.py:

558c558
-         preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
+         preferred_auths = [AUTH_LOGIN, AUTH_PLAIN, AUTH_CRAM_MD5]

This fixed the problem for me. Don't neglect to rename the corresponding .pyc and .pyo files so this change is actually used. And be sure to use TLS with this patch, otherwise the password would be sent in clear text.


Set up inbound mail

Set up qmail-to-mailman.py

Enter the following command:

 # cp /usr/share/doc/mailman-2.1.*/contrib/qmail-to-mailman.py /usr/lib/mailman/Mailman/MTA/.

Then you need to edit /usr/lib/mailman/Mailman/MTA/qmail-to-mailman.py. Modify the following variables:

 MailmanHome = "/usr/lib/mailman"; # Mailman home directory.
 MailmanVar = "/var/lib/mailman"; # Mailman directory for mutable data.

These values may differ if your distro isn't CentOS/Fedora.

Also change the MailmanOwner variable to your site owner's email address.


***** PLEASE NOTE (Mailman Owner addressing issue) *****

By default, your qmail-to-mailman.py file may list your MailmanOwner email address as that of postmaster within your "lists" sub-domain. When used with QMT, this will likely result in a looping delivery error when email is sent to mailman-owner@<your lists's sub-domain>, such as this:

Hi. This is the qmail-send program at [mail server FQDN]. I'm afraid I wasn't able to deliver your message to the following addresses. This is a permanent error; I've given up. Sorry it didn't work out.

<postmaster@lists.[your domain].com>: This message is looping: it already has my Delivered-To line. (#5.4.6)

To correct this, simply change the MailmanOwner address to one outside of your lists sub-domain. This will result in normal delivery with no errors.


The stock program doesn't handle VERP and subscription related requests (I filed bug report: https://bugs.launchpad.net/mailman/+bug/412293), so if you're going to use VERP (recommended) or you just want subscription related emails to work, you should apply the following patch:

@@ -77,10 +77,15 @@
     type = "post"
     types = (("-admin$", "bounces"),
              ("-bounces$", "bounces"),
+             ("-bounces[-+].*$", "bounces"),
+             ("-confirm$", "confirm"),
+             ("-confirm[-+].*$", "confirm"),
              ("-join$", "join"),
              ("-leave$", "leave"),
              ("-owner$", "owner"),
-             ("-request$", "request"))
+             ("-request$", "request"),
+             ("-subscribe$", "subscribe"),
+             ("-unsubscribe$", "unsubscribe"))
     for i in types:
         if re.search(i[0],local):

In order for qmail-to-mailman.py to pass the message on to vpopmail instead of local delivery, you must apply this patch to it as well (this patch came from here):

@@ -66,2 +66,3 @@
     local = string.lower(local)
-    local = re.sub("^mailman-","",local)
+    user = os.environ["USER"]
+    local = re.sub("^" + user + "-","",local) 

When your changes are complete, save the file.

Create virtual domain for lists

Enter the following command:

 # /home/vpopmail/bin/vadddomain lists.mydomain.com

Configure mailman delivery

Enter the following commands:

 # echo "|/var/qmail/bin/preline /usr/bin/python /usr/lib/mailman/Mailman/MTA/qmail-to-mailman.py" \
 >                      >/home/vpopmail/domains/lists.mydomain.com/.qmail-default
 # chown vpopmail:vchkpw /home/vpopmail/domains/lists.mydomain.com/.qmail-default

Set up site-wide mailing list

Every Mailman installation needs a "site-wide" mailing list. This is the one that password reminders will appear to come from, and it is required for proper Mailman operation.

Create the site-wide mailing list

Enter the following command:

 # /usr/lib/mailman/bin/newlist mailman

If you see any messages about editing /etc/aliases and running newaliases, then you don't have MTA = None in your configuration. That's ok. Just add the MTA = None to your mm_cfg.py file, and ignore the messages.

Configure the site-wide mailing list

There is a convenient template for a generic site list in /etc/mailman/sitelist.cfg which can help you with this. You should review the configuration options in the template. Any options not named in the sitelist.cfg file won't be changed.

When you're satisfied with the settings, the template should be applied to your site list by entering:

 # /usr/lib/mailman/bin/config_list -i /etc/mailman/sitelist.cfg mailman

Review site-wide list configuration

After applying the sitelist.cfg options, you should review the site list's configuration via the admin pages at http://lists.mydomain.com/mailman/admin/mailman/. Be sure to change descriptions where appropriate.

You should be sure to visit the Membership Management->Mass Subscription page and subscribe yourself to the site list while you're there.


Configure Mailman server

Set up cron

The stock crontab.in file in the Mailman package is meant for the system crontab, but we'll be installing it in mailman's private crontab, so we need to remove the mailman user from each rule.

Edit /usr/lib/mailman/cron/crontab.in, removing the " mailman" parameter from each rule. In vi, you can use one command to change them all:

 :1,$ s/mailman \/usr//

Or you may want to simply edit each line manually. There are only 6 or 7 of them, depending on the version.

Save your changes, and you're almost done with this step.

The comments in the crontab.in file indicate that it is refreshed by the init script each time mailman starts. That doesn't appear to happen, so you'll need to update cron manually by entering the following command:

 # crontab -u mailman /usr/lib/mailman/cron/crontab.in

Start Mailman

Enter the following commands:

 # chkconfig mailman on
 # service mailman start

Set a Site Password

You should probably set a site password. See the Mailman Installation Manual: Step 12 - Create the site password for details. Once again, substitute $prefix with /usr/lib/mailman.


Congratulations, your Mailman List Server should now be up and running!


Create a List

Follow the directions at the Mailman Installation Manual: Step 13 - Create your first mailing list to create a list.

Using primary domain for list messages

If you'd like to be able to send list emails to mylist@mydomain.com instead of mylist@lists.mydomain.com, this can be done in a few simple steps after you've created your list.

  1. Check that the DEFAULT_EMAIL_HOST value in /etc/mailman/mm_cfg.py reflects the short name.
  2. Check that the Host name this list prefers setting in the General Options Section of the administration web page reflects the short name as well.
  3. Use qmailadmin to create a forward from mylist@mydomain.com to mylist@lists.mydomain.com. This handles all of the post messages.
  4. Issue the following command to pass the list command messages to mailman:
 # cp -p /home/vpopmail/domains/lists.mydomain.com/.qmail-default \
 >       /home/vpopmail/domains/mydomain.com/.qmail-mylist-default

That's all there is to it!


Troubleshooting

See the Mailman Installation Manual: Step 14 - Troubleshooting for solutions to some common problems.


Running with a Separate Web Host

In order to run the web portion of mailman on a separate host, some parts of the package need to be available to the web server. There are many ways to accomplish this. Generally speaking, some parts are installed directly on the web host, while others are shared via NFS. These are the steps I've taken to accomplish this.

Configure Mailman Host

  • edit /etc/exports file with directories to export:
     /etc/mailman        ip.of.web.host(rw,sync)
     /usr/lib/mailman    ip.of.web.host(rw,sync)
     /var/lib/mailman    ip.of.web.host(rw,sync)
     /var/lock/mailman   ip.of.web.host(rw,sync)
     /var/spool/mailman  ip.of.web.host(rw,sync)
  • start portmap, nfs services:
     # service portmap restart
     # service nfs restart
  • make sure services are running after reboot:
     # chkconfig portmap on
     # chkconfig nfs on

Install on the Web Host

  • mailman group and user
     # groupadd -g 41 mailman
     # useradd -s /sbin/nologin -c "GNU Mailing List Manager" \
     > -d /usr/lib/mailman -u 41 -g 41 -M -r mailman
  • create /var/log/mailman directory
     # mkdir -m 2775 /var/log/mailman
     # chgrp mailman /var/log/mailman
  • create /var/lock/mailman directory
     # mkdir -m 2775 /var/lock/mailman
     # chgrp mailman /var/lock/mailman
  • scp the following files from the mailman host to the web host:
     # /etc/httpd/conf.d/mailman.conf
     # /etc/logrotate.d/mailman
  • edit /etc/logrotate.d/mailman as such:
     /var/log/mailman/error {
         missingok
         sharedscripts
         endscript
     }
  • edit /etc/auto.master to enable suid on the mounts:
     /net    -hosts suid
     #+auto.master
  • restart services and be sure they run after reboot:
     # service autofs restart
     # service portmap restart
     # service nfs restart
     # chkconfig autofs on
     # chkconfig portmap on
     # chkconfig nfs on
  • create symlinks for mount points:
     # ln -s ../net/<mailman-host>/etc/mailman /etc/.
     # ln -s ../../net/<mailman-host>/usr/lib/mailman /usr/lib/.
     # ln -s ../../net/<mailman-host>/var/lib/mailman /var/lib/.
     # ln -s ../../net/<mailman-host>/var/lock/mailman /var/lock/.
     # ln -s ../../net/<mailman-host>/var/spool/mailman /var/spool/.
  • copy icons to web directory:
     # cp -p /usr/lib/mailman/icons/* /var/www/icons/.

That's it in a nutshell. Be sure that <mailman-host> resolves to an address that is reachable (putting it in /etc/hosts is reasonable), and that your firewalls aren't blocking nfs. The autofs package should handle mounting automatically when the needed files are referenced.