FreeBSD 4.9, Qmail, Mailman

I’m writing this article to provide a complete, updated guide to install Mailman using Qmail as the MTA and FreeBSD 4.9.  I first became familiar with Qmail and FreeBSD in dec 2002.  I originally wanted *just* a backup mail server.   When I was trying to figure this out, I didn’t find a current article in one place to reference.   Open source software is very stable, flexible however at times a novice *nix admin really has to hunt to get all the answers. 

First of all this is my personal step-by-step process of building my FreeBSD 4.9 server. Its not without many hours of *trying* to shortcut and not really understand the step by step instructions provided by great resources like or I highly recommend anyone trying to do FreeBSD or Qmail to buy books to truely get help.  Especially if your a *windows person* and are accustomed to having setup, next, next finish types of installs.    I’ve bought a few BSD books and the The Qmail Handbook.  These are priceless resources.  One of my goals is to 100% understand how to build and support this type of build.  My original goal was to build a backup mail server, I’ve achieved this.  now its going to understand mailman listserv software.  Truly take time to support those like Dave Sill, and the FreeBSD group.  This example has only been tested with one domain,  please let me know if there are problems.

Install Apache
cd /usr/ports/www/apache13-modssl
make && make install

Upload netqmail, daemontools, ucspi-tcp
ftp – netqmail-1.05.tar.gz,daemontools-0.76.tar.gz,ucspi-tcp-0.88.tar.gz
At this time you probably want to become root, if you’re not already.

    mkdir -p /usr/local/src
    mv netqmail-1.05.tar.gz ucspi-tcp-0.88.tar.gz /usr/local/src
    mkdir -p /package
    mv daemontools-0.76.tar.gz /package
    chmod 1755 /package

Now you can unpack the packages.

    cd /usr/local/src
    gunzip netqmail-1.05.tar.gz
    tar xpf netqmail-1.05.tar
    cd netqmail-1.05
    ./  # watch for errors here
    cd ..
    gunzip ucspi-tcp-0.88.tar.gz
    tar xpf ucspi-tcp-0.88.tar
    rm *.tar      # optional, unless space is very tight
    cd /package
    gunzip daemontools-0.76.tar.gz
    tar xpf daemontools-0.76.tar
    rm *.tar      # optional, again

There should now be directories called /usr/local/src/netqmail-1.05, /usr/local/src/ucspi-tcp-0.88, and /package/admin/daemontools-0.76.

Create users and groups
The easiest way to create the necessary users and groups is to create a little script file to do it for you. In the source directory you’ll find a file called INSTALL.ids. It contains the command lines for many platforms, so copying the file to another name and editing that is quick and easy.

    cd /usr/local/src/netqmail-1.05/netqmail-1.05
    ee IDS, paste the following lines below

    pw groupadd nofiles
    pw useradd qmaild -g nofiles -d /var/qmail -s /nonexistent
    pw useradd alias -g nofiles -d /var/qmail/alias -s /nonexistent
    pw useradd qmaill -g nofiles -d /var/qmail -s /nonexistent
    pw useradd qmailp -g nofiles -d /var/qmail -s /nonexistent
    pw groupadd qmail
    pw useradd qmailq -g qmail -d /var/qmail -s /nonexistent
    pw useradd qmailr -g qmail -d /var/qmail -s /nonexistent
    pw useradd qmails -g qmail -d /var/qmail -s /nonexistent

Then to run it, either use chmod to make it executable or run it with sh:
First method:

    chmod 700 IDS

When the script finishes, all of your users and groups will be created and you can go on to the next section. But what do you do if your system isn’t listed in INSTALL.ids? You’ll have to create them manually. Start by using your favorite editor and editing /etc/group. You need to add the following two lines to the end of the file:


Next, using vipw (most systems have it, if not you’ll need to use your editor again but this time on /etc/passwd) add these lines to the end of the file:


Do the build
Now you can start building qmail. Change to the /usr/local/src/netqmail-1.05/netqmail-1.05 directory and let’s get started:

    cd /usr/local/src/netqmail-1.05/netqmail-1.05

In the Verify Build Environment section, you located your C compiler. If it’s not called cc or the directory it resides in isn’t in your PATH environment variable, you’ll need to edit conf-cc and conf-ld. Say your compiler is gcc, and it’s in your PATH. Simply edit conf-cc and conf-ld and replace “cc” with “gcc”.

Now type the following:

    make setup check

After the build is complete, you’ll need to do your post installation configuration. A couple of scripts are provided to make this job a lot easier. For example, if your domain is and the hostname of your computer is dolphin, your config-fast line would look like this:


Qmail setup is completed

Install ucspi-tcp
Earlier, you unpacked the qmail, ucspi-tcp, and daemontools tarballs. Now change to the ucspi-tcp directory:

    cd /usr/local/src/ucspi-tcp-0.88
    patch < /usr/local/src/netqmail-1.05/other-patches/ucspi-tcp-0.88.errno.patch
    make setup check

Install daemontools
Change to the daemontools build directory:

    cd /package/admin/daemontools-0.76/src
    patch < /usr/local/src/netqmail-1.05/other-patches/daemontools-0.76.errno.patch
    cd ..


Supervise scripts creation


ee /var/qmail/rc


# Using stdout for logging
# Using control/defaultdelivery from qmail-local to deliver messages by default

exec env – PATH=”/var/qmail/bin:$PATH”
qmail-start “`cat /var/qmail/control/defaultdelivery`”


ee /var/qmail/bin/qmailctl

Copy from

Create Supervise Script Directories

mkdir -p /var/qmail/supervise/qmail-send/log
mkdir -p /var/qmail/supervise/qmail-smtpd/log

Qmail-smtpd Run

ee /var/qmail/supervise/qmail-smtpd/run


QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`
MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
LOCAL=`head -1 /var/qmail/control/me`

if [ -z “$QMAILDUID” -o -z “$NOFILESGID” -o -z “$MAXSMTPD” -o -z “$LOCAL” ]; then
    echo /var/qmail/supervise/qmail-smtpd/run
    exit 1

if [ ! -f /var/qmail/control/rcpthosts ]; then
    echo “No /var/qmail/control/rcpthosts!”
    echo “Refusing to start SMTP listener because it’ll create an open relay”
    exit 1

exec /usr/local/bin/softlimit -m 2000000
    /usr/local/bin/tcpserver -v -R -l “$LOCAL” -x /etc/tcp.smtp.cdb -c “$MAXSMTPD”
        -u “$QMAILDUID” -g “$NOFILESGID” 0 smtp /var/qmail/bin/qmail-smtpd 2>&1

Qmail-smtpd run file

ee /var/qmail/supervise/qmail-smtpd/log/run

exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/smtpd


Qmail-send run file

ee /var/qmail/supervise/qmail-send/run

exec /var/qmail/rc

Qmail-send log run file

ee /var/qmail/supervise/qmail-send/log/run

exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail

chmod 755 /var/qmail/rc
chmod 755 /var/qmail/bin/qmailctl
chmod 755 /var/qmail/supervise/qmail-send/run
chmod 755 /var/qmail/supervise/qmail-send/log/run
chmod 755 /var/qmail/supervise/qmail-smtpd/run
chmod 755 /var/qmail/supervise/qmail-smtpd/log/run

echo ./Maildir/ >/var/qmail/control/defaultdelivery
ln -s /var/qmail/supervise/qmail-send /var/qmail/supervise/qmail-smtpd /service
ln -s /var/qmail/bin/qmailctl /usr/bin

mkdir -p /var/log/qmail/smtpd
chown qmaill /var/log/qmail /var/log/qmail/smtpd

echo 20 > /var/qmail/control/concurrencyincoming
chmod 644 /var/qmail/control/concurrencyincoming

mv /usr/lib/sendmail /usr/lib/sendmail.old
mv /usr/sbin/sendmail /usr/sbin/sendmail.old

chmod 0 /usr/lib/sendmail.old /usr/sbin/sendmail.old

ln -s /var/qmail/bin/sendmail /usr/lib
ln -s /var/qmail/bin/sendmail /usr/sbin

ln -s .qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon
chmod 644 /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon

echo ‘127.:allow,RELAYCLIENT=””‘ >>/etc/tcp.smtp
echo ‘192.:allow,RELAYCLIENT=””‘ >>/etc/tcp.smtp
qmailctl cdb

ee /home/scs/downloads/

Verify your local qmail alias files



This is what my /var/qmail/alias looks like before installing Mailman
lrwxr-xr-x  1 root  qmail  17 May  2 18:55 .qmail-mailer-daemon -> .qmail-postmaster
-rw-r–r–  1 root  qmail   3 May  5 01:21 .qmail-postmaster
-rw-r–r–  1 root  qmail   3 May  5 01:20 .qmail-root

here is what my control files look like in Qmail
[root@lists:/var/qmail/control]# ls -l

-rw-r–r– 1 root qmail 3 May 15 08:42 concurrencyincoming
-rw-r–r– 1 root qmail 11 May 15 08:42 defaultdelivery
-rw-r–r– 1 root qmail 10 May 15 08:25 defaultdomain
-rw-r–r– 1 root qmail 26 May 15 10:17 locals
-rw-r–r– 1 root qmail 16 May 15 08:25 me
-rw-r–r– 1 root qmail 10 May 15 08:25 plusdomain
-rw-r–r– 1 root qmail 26 May 15 10:17 rcpthosts

ee /var/qmail/control/locals

ee /var/qmail/control/me

ee /var/qmail/control/rcpthosts

Install Mailman from the ports
cd /usr/ports/mail/mailman
ee Makefile
change this line from
–with-mail-gid=${MAIL_GID} –with-cgi-gid=${CGI_GID}
Change to
–with-mail-gid=nofiles –with-cgi-gid=www //this might be apache also
make && make install

//The reason I change it to root is the README.QMAIL file that is in /usr/ports/mail/mailman/work/mailman-2.1.4/README.QMAIL
//I’ve not tested running as mailman as “The Qmail Handbook example shows”
//This might already be done if you installed Mailman from the ports.

cd /usr/local/mailman
chown -R root * 

//Add this to the bottom of this file — /usr/local/mailman/Mailman/
//Per the README.QMAIL file that is in /usr/ports/mail/mailman/work/mailman-2.1.4/README.QMAIL

If the check_perms script reports errors, rerun it using the -f option to fix the errors.
# bin/check_perms -f
//Configure your Web server to allow execution of CGI scripts in /usr/local/mailman/cgi-bin. If you are running Apache, it should be sufficient to add the following directive to the Apache //configuration file, httpd.conf:
ScriptAlias /mailman/ “/usr/local/mailman/cgi-bin/”

Copy the Mailman, Python, and GNU logos to a location accessible to the Web server. For example, if the directory in which Apache looks for icons is /var/www/icons, the following command should do: 

cp /usr/local/mailman/icons/* /usr/local/www/icons

Edit /usr/local/mailman/Mailman/ and add a line that points the variable IMAGE_LOGOS points at the proper base URL for the logos you’ve just copied into place. MTA_ALIASES_STYLE=’qmail’

Point your Web server at the public mailing list archives. Using Apache, the following lines added to httpd.conf should do:
Alias /pipermail/ “/usr/local/mailman/archives/public/”

  Options FollowSymLinks

Restart Apache. I use apachectl restart, which should work for most Apache installations, but you might want to use the appropriate init script.
# apachectl restart
/usr/sbin/apachectl restart: httpd restarted

Mailman relies on a number of cron jobs to provide much of its functionality, so the next step is to install the mailman user’s crontab entries. The Mailman distribution contains a prebuilt crontab file, /usr/local/mailman/cron/, which can be installed with the following command:
# crontab /usr/local/mailman/cron/ -u mailman

Start Mailman’s queue runner daemon:
# bin/mailmanctl start
Starting Mailman’s master qrunner.

 To ensure that Mailman starts automatically when the system reboots, add its initialization script to your init script system. For simplicity’s sake, I added an invocation of the script to rc.local — the Mailman INSTALL file lists other means of integrating the script into system startup scripts. Here are the lines I added to rc.local:

//This also should put something in /usr/local/etc/rc.d/
//this is what the rc file looks like that was put by the ports
//I only post this for reference, you shouldn’t have to put the file
//in the /usr/local/etc/rc.d

# mailman    This shell script starts and stops GNU Mailman.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place – Suite 330, Boston, MA 02111-1307, USA.
# Copy this file to /etc/init.d/ (or /etc/rc.d/init.d/ depending on
# your system) and activate it as such:
# On Debian, type “update-rc.d mailman defaults”
# On RedHat, and derivatives, install with “chkconfig –add mailman”
# chkconfig: 2345 98 12
# description: Mailman is the GNU Mailing List Manager, a program that
#              manages electronic mail discussion groups.  For more
#              on GNU Mailman see
# processname: mailmanctl
# config: /usr/local/mailman/Mailman/
# pidfile: /usr/local/mailman/data/


case “$1” in
    #rm -f $MAILMANHOME/locks/*
    $PYTHON $MAILMANCTL -s -q start && echo -n ‘ mailman’

    $PYTHON $MAILMANCTL -q stop && echo -n ‘ mailman’

    $PYTHON $MAILMANCTL -q restart
    echo “Usage: `basename $0` {start|stop|restart}” >&2
    exit 64

exit 0

//put this empty file in the /usr/local/mailman directory
touch /usr/local/mailman/.qmail-owner

//Create a list called mailman by using the newlist command

# bin/newlist mailman
Enter the email of the person running the list:
Initial mailman password:

## mailman mailing list
mailman:              “|/usr/local/mailman/mail/mailman post mailman”
mailman-admin:        “|/usr/local/mailman/mail/mailman admin mailman”
mailman-bounces:      “|/usr/local/mailman/mail/mailman bounces mailman”
mailman-confirm:      “|/usr/local/mailman/mail/mailman confirm mailman”
mailman-join:         “|/usr/local/mailman/mail/mailman join mailman”
mailman-leave:        “|/usr/local/mailman/mail/mailman leave mailman”
mailman-owner:        “|/usr/local/mailman/mail/mailman owner mailman”
mailman-request:      “|/usr/local/mailman/mail/mailman request mailman”
mailman-subscribe:    “|/usr/local/mailman/mail/mailman subscribe mailman”
mailman-unsubscribe:  “|/usr/local/mailman/mail/mailman unsubscribe mailman”

Hit enter to notify mailman owner…
‘Be sure to add the listed aliases to /var/qmail/mail/aliases or wherever the aliases file lives on your system, ‘This puts the files in /var/qmail/alias, notice the /usr/local/mailman/mail/mailman line
‘in the The Qmail Handbook example it says wrapper.  According the

//Create a sample list called mailman by using the newlist command
# bin/newlist pop-fans3
Enter the email of the person running the list:
Initial pop-fans3 password:

## mailman mailing list
mailman:              “|/usr/local/mailman/mail/mailman post pop-fans3”
mailman-admin:        “|/usr/local/mailman/mail/mailman admin pop-fans3”
mailman-bounces:      “|/usr/local/mailman/mail/mailman bounces pop-fans3”
mailman-confirm:      “|/usr/local/mailman/mail/mailman confirm pop-fans3”
mailman-join:         “|/usr/local/mailman/mail/mailman join pop-fans3”
mailman-leave:        “|/usr/local/mailman/mail/mailman leave pop-fans3”
mailman-owner:        “|/usr/local/mailman/mail/mailman owner pop-fans3”
mailman-request:      “|/usr/local/mailman/mail/mailman request pop-fans3”
mailman-subscribe:    “|/usr/local/mailman/mail/mailman subscribe pop-fans3”
mailman-unsubscribe:  “|/usr/local/mailman/mail/mailman unsubscribe pop-fans3”

Hit enter to notify mailman owner…
//Be sure to add the listed aliases to /var/qmail/mail/aliases or wherever the aliases file lives on your system

echo ‘|preline /usr/local/mailman/mail/mailman post pop-fans3’ > ~alias/.qmail-pop-fans3
echo ‘|preline /usr/local/mailman/mail/mailman mailowner pop-fans3’ > ~alias/.qmail-pop-fans3-admin
echo ‘|preline /usr/local/mailman/mail/mailman mailcmd pop-fans3’ > ~alias/.qmail-pop-fans3-request
echo ‘&pop-fans3-admin’ > ~alias/.qmail-pop-fans3-owner
echo ‘&pop-fans3-admin’ > ~alias/.qmail-owner-pop-fans3

chmod 644 ~alias/.qmail-pop-fans3
chmod 644 ~alias/.qmail-pop-fans3-admin
chmod 644 ~alias/.qmail-pop-fans3-request
chmod 644 ~alias/.qmail-pop-fans3-owner
chmod 644 ~alias/.qmail-owner-pop-fans3

# su – mailman
$ bin/mmsitepass newpass
Password changed.
Your going to want to chose something besides newpass..


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s