Mar 012006

Mailman – a mailing list manager

Mailman is a mailing list manager. This article will demonstrate how I set up Mailman and converted some mailing lists from Majordomo. I’ll be using FreeBSD 6.0-STABLE, Postfix 2.2.7, and MailMan 2.17 but you will probably find these instructions useful no matter that operating system and version you are planning to use. Mailman has a web component that can be used for subscribing, administration, and archives. I’ll be showing how I configured Apache to work with Mailman. With this solution, I’m making the following assumptions
  • All mail for your list goes to a specific domain. In my case, I do it this way so that I can easily change the mail server to another host should the need arise. It also simplifies the solution in that all mail for that host goes to Mailman, not to a user.
  • Postfix is your mail server, and you want to use virtual domains.
  • You will give unique names to each mailing list. You will not have and Instead, you will have and Again, this simplifies the solution.


Installation is a no-brainer. But if you are using anything other than sendmail as your mail server, you’ll need to tell Mailman about it. The make options command shows you a lot of things you can tweak. I recommend leaving everything as the default value except for setting the right value for MAIL_GID. Since I’m using Postfix, I’ll use the following command for installation:
cd /usr/ports/mail/mailman
make MAIL_GID=mailman install clean
That will install mailman and clean up the working files when it is done.

16 April 2006

When it came time to upgrade Mailman at at later date, I found this worked for me:
export MAIL_GID=mailman
portupgrade mailman
NOTE: after reinstalling mailman, you need to restart it:
/usr/local/etc/rc.d/ start
In later versions of Mailman, the command is
/usr/local/etc/rc.d/mailman start

NOTE the missing .sh This point has stumped me more than once. I’d send a message. Nothing happened. Starting up the mailman queue processing helps.


This isn’t the first time I have set up Mailman. I know I played with it twice before, the latest of which I think was in 2003. At the time, I thought the documentation wasn’t very clear in some crucial aspects. In particular, while they may document things well, they don’t provide enough practical examples to demonstrate how to use a particular feature. I hope things will go smoother this time. Be sure to read /usr/local/share/doc/mailman/FreeBSD-post-install-notes. I started by setting up I’m not going to describe how to set up the DNS. That is outside the scope of this article and I have several articles about DNS. Similarly, I won’t tell you how to set up a virtual server in Apache, but you can read something about that. However, the virtual host for this:
<VirtualHost *>
    DocumentRoot    /path/to/www/
    ScriptAlias /mailman   "/usr/local/mailman/cgi-bin"
    Alias       /pipermail "/usr/local/mailman/archives/public"
    ErrorLog        /path/to/www/log/
    CustomLog       /path/to/www/log/ combined
I think the most important document to read is /usr/local/share/doc/mailman/mailman-install.txt. You can also read that document online in HTML form. From that document, I performed these steps.
  1. From Step 4, I ran bin/check_perms. It found nothing wrong.
  2. I’m using Postfix, so I followed “6.1 Using the Postfix mail server” closely. Specifically, I made sure these items were in /usr/local/etc/postfix/
    recipient_delimiter = +
    unknown_local_recipient_reject_code = 550
    transport_maps = hash:/usr/local/etc/postfix-config/transport
    mailman_destination_recipient_limit = 1
    Combined with the above, I added the following to /usr/local/etc/postfix-config/transport (NOTE: you can use any file name you want; just be consistent with it.): mailman:
    Remember to process that file first:
    postmap /usr/local/etc/postfix-config/transport
    That will create the database file Postfix will use. I also let Postfix know that it should accept mail for by adding this entry to /usr/local/etc/postfix/
    relay_domains =
    If you already have a relay_domains entry, add to it. Do not replace. And I added this to /usr/local/etc/postfix/
    mailman unix  -       n       n       -       -       pipe
          flags=FR user=mailman:mailman
          argv=/usr/local/mailman/ ${nexthop} ${user}
    You’ll see a reference to above. You need to download that manually and install it to the indicated directory. You can get that from I grabbed the one for Mailman 2.1 version and renamed the file accordingly. I changed some items within the file:
    #! /usr/local/bin/python
    # Configuration variables - Change these for your site if necessary.
    MailmanHome = "/usr/local/mailman"; # Mailman home directory.
    MailmanOwner = "";
    # End of configuration variables.
    The items I changed are in bold.
  3. And to integrate Postfix and Mailman, I followed “6.1.1 Integrating Postfix and Mailman”.
    • I added this to /usr/local/mailman/Mailman/
      MTA = 'Postfix'
      I found I didn’t need the following entries at all:
      Those last two entries deal with virtual hosts. But given the script I’m using (, perhaps those items are no longer required.
    • I checked the values of POSTFIX_ALIAS_CMD and POSTFIX_MAP_CMD in /usr/local/mailman/Mailman/
    • As root, I issued these commands to generate the aliases:
      cd /usr/local/mailman
    • Followed by these commands to make sure the files are owned by mailman:
      cd /usr/local/mailman/data
      chown mailman aliases aliases.db
      chmod g+w aliases aliases.db
    • I told Postfix about the aliases by adding this to /usr/local/etc/postfix/
      You should add the above directive to any existing alias_maps = directive.
  4. You’ll need to restart Postfix and Apache. Check for errors
  5. Create a site-wide mailing list. Following step 8 of the mailman-install.txt, I did this (see later in this step for a better method):
    bin/newlist mailman
    bin/config_list -i data/sitelist.cfg mailman
    The list creation email that you receive will have the wrong hostname in the URLs. Ignore that point. In a latter step, we’ll fix that URL. You can avoid the fixing step if you specify the email host and web host on the command line:
    bin/newlist \ freebsddiary-announce

    NOTE: I’ve split the above into two lines.

  6. Set up the cronjob for mailman:
    cd /usr/local/mailman/cron
    crontab -u mailman
  7. Start the queue processing:
    cd /usr/local/mailman
    bin/mailmanctl start
  8. If we didn’t specify the mail host and web host on the command line, we need to fix the URL for this list:
    bin/withlist -l -r fix_url freebsddiary-announce
    With the above we change the URL for the list freebsddiary-announce by setting it to Ignore the incorrect URL in the list correction email. The above command fixes that.
Now you should be able to browse to your mailman interface. Like I can:

Creating the first list

I will now create the freebsddiary-announce mailing list:
cd /usr/local/mailman
bin/newlist freebsddiary-announce
Shortly thereafter, you should get an email with a list of all the things you need to know.

Problems I encountered

This section outlines some of the problems I encountered and the solution.

relay access denied

Symptoms: messages to the list bounce with:
<>: host[] said: 554 <>: Relay access denied (in reply to RCPT TO command)
I was missing an entry from relay_domains in

no such file or directory

Symptoms: messages to the list bounce with:
<>: Command died with status 127: "/usr/local/mailman/". Command output: env: python: No such file or directory
The first line of the script was wrong. See above for my changes to this file.

command died with status 1

Symptoms: messages to the list bounce with:
<>: Command died with status 1: "/usr/local/mailman/"
Solution: chmod +x /usr/local/mailman/

Command died with status 1

Symptoms: messages to the list bounce with:
<>: Command died with status 1: "/usr/local/mailman/". Command output: TO ACCESS THE MAILING LIST SYSTEM: Start your web browser on That web page will help you subscribe or unsubscribe, and will give you directions on how to post to each mailing list.
Solution: Your list does not exist. Spell it correctly. In this case, I’m missing a n from announce.

command died with status 2

Symptoms: messages to the list bounce with:
<>: Command died with status 2: "/usr/local/mailman/". Command output: Group mismatch error. Mailman expected the mail wrapper script to be executed as group "mail", but the system's mail server executed the mail script as group "mailman". Try tweaking the mail server to run the script as group "mail", or re-run configure, providing the command line option --with-mail-gid=mailman'.
Solution: reinstall mailman using the instruction shown at the start of this article. Key point: MAIL_GID setting is incorrect.

Problem with mailman archives

I encountered one problem with mailman archives. It was reported by Mark Linimon who was unable to view the archives for the BSDCan Announce mailing list. If you clicked on bsdcan-announce Archives you would be presented with:

You don't have permission to access /pipermail/bsdcan-announce/ on this server.

Apache/1.3.34 Server at Port 80

Looking at the server logs for that website, I saw:

(13)Permission denied: access to /pipermail/bsdcan-announce/ failed because search permissions are missing on a component of the path

Googling led me to suspect symlinks were the cause of the problem. Looking at the mailman directory structure supported this theory. I was to be proven wrong. The cause of the problem was directory permissions. I show you what I did wrong just to document what I did wrong. 🙂 I show you the correct solution at the end of this section.

Here is what I found in that directory:

$ ls -l
total 0
lrwxr-xr-x 1 root mailman 51 Mar 1 07:17 bsdcan-announce -> /usr/local/mailman/archives/private/bsdcan-announce

I added one set of symlinks:

<Location /pipermail>
    Options     Indexes FollowSymLinks

And I restarted tested the configuration and restarted Apache:

$ sudo apachectl configtest
Syntax OK
$ sudo apachectl graceful
/usr/local/sbin/apachectl graceful: httpd gracefully restarted

The problem persisted. OK, what about another symlink?

<Location /pipermail/bsdcan-announce>
    Options     Indexes FollowSymLinks

The correct solution

Another configtest and graceful indicated I was wrong. It was then that I started to look at the symlink destination: /usr/local/mailman/archives/private/:

[dan@havoc:/usr/local/mailman/archives] $ ls -l
total 4
drwxrws---  30 root  mailman  1024 Apr 14 12:05 private
drwxrwsr-x   2 root  mailman   512 Apr 14 12:05 public
Ahhh! There’s the problem. Apache, running as user www, cannot access the archives that are found in private. A quick chmod to test the theory:
chmod o=rx private
Success! Now I can view the BSDCan announce list archives properly. I went back and removed the <Location…> directives from the virtual host, retested the configuration, and did a graceful on Apache. I browsed to the URL again to confirm the FollowSymLinks directive was not required. All as well.

Adding more domains

The above uses only one domain ( I hope to add others later. That will be in another article. Enjoy.

A word about backups

I’m now backing up /usr/local/mailman. The empty files are about 30MB. No sense not backing up everything! And, of course, I’m using Bacula.

  One Response to “Mailman – a mailing list manager”