Majordomo - Virtually hosted mailing lists for virtual servers
Majordomo is a suite of programs written in Perl to help automate the management of mailing lists. This document describes how to setup Majordomo on a virtual server and use it to manage mailing lists under virtually hosted domains.
Many people like to use Majordomo for the management of their mailing lists, but find that setting it up to manage lists for virtual hosts is too complex or confusing. This document describes what steps are necessary to create virtually hosted mailing lists using Majordomo.
In this document we call the set of programs that runs a mailing list 'Majordomo' with an upper-case 'M' and the program in this suite that handles mail requests 'majordomo' with a lower-case 'm'.
We have a virtually hosted domain (which we call vhost1.com) on our server (which we call server) and we want to set up a recipe mailing list for the exchange of popular cooking recipes using the vhost1.com domain.
We assume that the domain vhost1.com already has a DNS record pointing to this virtual server and that sendmail has been configured to accept mail for the domain (using the ~/etc/local-host-names mechanism or the Cw lines in ~/etc/sendmail.cf).
Throughout this document we will point out the steps that need to be done for first-timers as well as steps for those who simply want to add an additional mailing list to a virtually hosted domain.
To install Majordomo on your virtual server, at your shell prompt, type:
server:~ $ vinstall majordomo
The only thing you need to know during installation is your hostname which you may discover by typing hostname:
server:~ $ hostname
server.com
The default hostname that the Majordomo installation program suggests is usually correct. Once Majordomo has been installed, we're ready to create a virtually hosted mailing list by following these four steps:
First we must create some files and directories that Majordomo needs to be able to handle our new mailing list for this virtual host (if you already have Majordomo mailing lists for this virtual host, you may skip to step 2):
Necessary if you want to keep an archive of your messages. If you do not wish to keep an archive of messages sent to the recipe mailing list, skip this directory. This is an optional directory, but we will use it in this example.
All mailing list information (for all mailing lists under this virtual host) is stored in this directory. This directory is not optional.
All Majordomo administrative actions are logged here. This is an important log to keep for security purposes; you should periodically review the contents of this file. This file is not optional.
Necessary if you want to do digests for your mailing list. A digest is a collection of many messages over a period of time compiled into one single message. You may use Majordomo to create weekly or monthly digests of the messages sent to the recipe mailing list. Digest subscribers will receive this periodic digest message instead of each message sent to the list. This is an optional directory and we will not use it in this example.
Contains information for Majordomo to work correctly. In this configuration file we tell Majordomo what the name of our virtual host is, where our home directory is located, where our Lists directory is located, and other such things. This file is not optional.
We suggest placing these files in the root directory (~/www/vhosts/vhost1) of the virtual host for added security and portability (i.e., if you ever decide to move the host to another server, etc.).
When we originally set up our virtual host, we wanted an area for files we didn't want to be publicly available over the world wide web so we created a 'www' directory in the root of the virtual host and made that our DocumentRoot in our Apache httpd.conf file:
<VirtualHost www.vhost1.com vhost1.com>
ServerName www.vhost1.com
ServerAdmin webmaster@vhost1.com
DocumentRoot /usr/local/etc/httpd/vhosts/vhost1/www
TransferLog logs/vhost1.com/access_log
...
</VirtualHost>
Everything in our virtual host root directory (~/www/vhosts/vhost1) that does not lie under our Apache document root directory (~/www/vhosts/vhost1/www) is not accessible via the web. The directory root of our virtual host looks something like this:
server:~/www/vhosts/vhost1 $ ls -lF
total 1
drwxr-xr-x 3 server vuser 512 Apr 25 22:08:24 2001 www/
Let's create the files that Majordomo needs to run a mailing list. We'll create two directories Archive and Lists, create a file called Log, and copy the system majordomo.cf file to this directory:
server:~/www/vhosts/vhost1 $ mkdir Archive Lists
server:~/www/vhosts/vhost1 $ touch Log
server:~/www/vhosts/vhost1 $ cp -p ~/usr/local/majordomo/majordomo.cf .
server:~/www/vhosts/vhost1 $ ls -lF
total 25
drwxr-xr-x 2 server vuser 512 Aug 23 08:35 Archive/
drwxr-xr-x 2 server vuser 512 Aug 23 08:35 Lists/
-rw-r--r-- 1 server vuser 0 Aug 23 08:35 Log
-rw-r--r-- 1 server vuser 10460 Aug 20 17:26 majordomo.cf
drwxr-xr-x 5 server vuser 1024 Feb 20 2001 www/
To finish this step we need to edit this new majordomo.cf file and make the following changes using our favorite editor (emacs, vi, pico, ee, etc.). Note that your line numbers may vary slightly depending on the version of Majordomo you're using and other modifications.
line 9:
old config file: $whereami = "server.com";
---
new config file: $whereami = "vhost1.com";
line 27 (add this line):
old config file: (empty line)
---
new config file: $myhomedir = "/www/vhosts/vhost1";
new config file: (empty line)
line 31:
old config file: $listdir = "$homedir/Lists";
---
new config file: $listdir = "$myhomedir/Lists";
line 39:
old config file: $digest_work_dir = "$homedir/Digests";
---
new config file: $digest_work_dir = "$myhomedir/Digests";
line 43:
old config file: $log = "$homedir/Log";
---
new config file: $log = "$myhomedir/Log";
This step allows the world (or just members of our mailing list) to send mail to our virtual host. By adding entries in our ~/etc/virtmaps file our server knows to translate virtual host aliases to real server aliases found in ~/etc/aliases (which aliases we add in step 3).
Let's get right into it by changing directories to our ~/etc directory:
server:~/www/vhosts/vhost1 $ cd ~/etc
server:~/etc $
Open up ~/etc/virtmaps in your favorite editor and prepare to append some new lines to the bottom of the file.
## essential majordomo aliases
majordomo@vhost1.com vhost1~majordomo
majordomo-owner@vhost1.com vhost1~majordomo-owner
owner-majordomo@vhost1.com vhost1~owner-majordomo
Let's add the mappings for our recipe mailing list. The following lines will need to be added for each mailing list on this virtual host. In this example we are only creating one mailing list called recipe, but we could add many more lists just as easily.
## vhost1.com: recipe list
recipe@vhost1.com vhost1~recipe
recipe-going-out@vhost1.com vhost1~recipe-going-out
recipe-request@vhost1.com vhost1~recipe-request
recipe-owner@vhost1.com vhost1~recipe-owner
owner-recipe@vhost1.com vhost1~owner-recipe
If you're setting up a moderated list, you'll also need:
recipe-approval@vhost1.com vhost1~recipe-approval
(thanks to Miomir Besarabic <miomir-at-besarabic.com> for pointing this out).
Save and close the virtmaps file; be sure to run vnewvirtmaps when you're done. We're ready to add our new aliases now.
This step takes the messages that are forwarded by the mappings in our ~/etc/virtmaps file and forwards them to actual Majordomo commands.
Open ~/etc/aliases in your favorite editor and prepare to append some new lines to the bottom of the file.
## vhost1.com lists
vhost1~majordomo: "|/usr/local/majordomo/wrapper majordomo \
-C /www/vhosts/vhost1/majordomo.cf"
vhost1~majordomo-owner: vhost1~owner-majordomo
vhost1~owner-majordomo: mylogin
Let's add the necessary lines for our new mailing list. There are five (5) aliases in total and three of the aliases wrap.
## vhost1.com: recipe list
vhost1~recipe: "|/usr/local/majordomo/wrapper resend -l recipe \
-C /www/vhosts/vhost1/majordomo.cf vhost1~recipe-going-out, null"
vhost1~recipe-going-out: :include:/www/vhosts/vhost1/Lists/recipe,
"|/usr/local/majordomo/wrapper archive2.pl -a -m \
-f /www/vhosts/vhost1/Archive/recipe.archive"
vhost1~recipe-request: "|/usr/local/majordomo/wrapper majordomo -l recipe \
-C /www/vhosts/vhost1/majordomo.cf"
vhost1~recipe-owner: vhost1~owner-recipe
vhost1~owner-recipe: mylogin
For moderated lists you'll also need:
vhost1~recipe-approval: moderator@somewhere.tld
Notice that the left-side of these aliases match the right side of the virtual host alias mappings we did in step 2 for this mailing list. We'll explain in detail what each line is doing:
Depending on the options we specify, resend allows us to clean up or strip out email headers before they're sent to the list, catch errors before they're posted to the list, make sure that only members of the list may post, and other useful things (see the man page for resend).
The -l (ell) option tells the resend program that we're sending mail using configuration options for the recipe mailing list. The -C option for resend is just like the -C option for majordomo: it tells resend to use an alternative configuration file for its behavior.
The next piece of this alias is the name of our real outgoing alias, in this case 'vhost1~recipe-going-out'. Resend uses this list to determine who to send mail to.
The trailing ', null' at the end is a sendmail trick that hides the name of our real outgoing alias list. The reason it's important to hide this outgoing alias is so that spammers (and list members) don't bypass our resend wrapper and mail directly to the list alias. In order for 'null' to work you'll need to add another alias in your aliases file like this:
null: /dev/null
which will simply put the message in the system bit bucket (oblivion).
If you don't want to archive your mailing list, I would omit the portion that calls archive2.pl and would have this line instead for your outgoing alias:
vhost1~recipe-going-out: :include:/www/vhosts/vhost1/Lists/recipe
subscribe recipe
With the 'vhost1~recipe-request' alias users can simply send a message to 'recipe-request@vhost1.com' with the following line:
subscribe
and majordomo will understand the request as if it were sent with the 'recipe' mailing list information included.
These five lines will handle all the recipe mailing list posts and administrative actions.
The last thing we need to do before we can start sending recipes to our friends is to create the actual list and list configuration file (and a few other little files).
Change directories to the Lists directory we created in our first step:
server:~/etc $ cd ~/www/vhosts/vhost1/Lists
and create the mailing list and an information file so people who may wish to subscribe can get some information about the list before actually subscribing:
server:~/www/vhosts/vhost1/Lists $ touch recipe
server:~/www/vhosts/vhost1/Lists $ cat > recipe.info
This is the recipe mailing list for vhost1.com. If you have a
favorite recipe you would like to share or request, subscribe to
this group by sending an email to:
recipe-request@vhost1.com
with the word 'subscribe' in the BODY of the message.
^D
server:~/www/vhosts/vhost1/Lists $
(That is, type in the mailing list information, then hit a control-D to signify end-of-file.)
Now let's create a new file with your password in it. The password adds a little extra security so that only those who know the password may make administrative changes (as we're about to do):
server:~/www/vhosts/vhost1/Lists $ cat > recipe.passwd
SEKRIT_PASSWERD
^D
server:~/www/vhosts/vhost1/Lists $
majordomo is now ready to accept your commands via email. First we need to create the recipe configuration file. This configuration file is distinct from the majordomo.cf file we created earlier and contains specific information about this list such as approval passwords, who may post to the email list, and who may view information about the list and so on.
To create a new configuration file when none exists, simply send an email message to 'recipe-request@vhost1.com' with the following Majordomo command in the body of the message (Majordomo ignores subject lines when processing commands):
writeconfig SEKRIT_PASSWERD
Notice that we could have sent an email message to 'majordomo@vhost1.com' with the following body:
writeconfig recipe SEKRIT_PASSWERD
and the effect would have been the same; remember that sending mail to 'recipe-request' is the same as sending mail to the 'majordomo' alias but with the -l recipe command-line option enabled (review your aliases file if you still don't understand this convenience alias).
In a short while, you'll receive an email message with a copy of the newly created configuration file for the recipe mailing list:
--
>>>> writeconfig SEKRIT_PASSWERD
wrote new config for list recipe
>>>> --
END OF COMMANDS
That's all you have to do to create a new configuration file. If a configuration file already exists, the 'writeconfig PASSWORD' command will do nothing unless you've upgraded versions of Majordomo, in which case it will add in new configuration options (if any) and leave your existing settings alone.
Now let's edit our configuration file to suit our needs. There are two ways to edit Majordomo list configuration files:
If you (as the Majordomo administrator who will handle the rare Majordomo errors) are also going to be the recipe mailing list administrator (who handles list bounces and other list confirmation actions), then you may simply edit this file by hand.
However, if your are going to let someone else administer the list, you'll want to learn how to edit the list configuration file over email. Read on.
First we need to ask Majordomo for a copy of our newly created configuration file so we can edit it. Send an email message to 'recipe-request@vhost1.com' with the following Majordomo command in the body:
config SEKRIT_PASSWERD
Shortly you'll receive as a reply a copy of the configuration file, which should look something like this:
--
>>>> config SEKRIT_PASSWERD
# The configuration file for a majordomo mailing list.
# Comments start with the first # on a line, and continue to the end
# of the line. There is no way to escape the # character. The file
# uses either a key = value for simple (i.e. a single) values, or uses
# a here document
# key << END
# value 1
# value 2
# [ more values 1 per line]
# END
# for installing multiple values in array types. Note that the here
...
We're going to change some values in this message and send it back to majordomo for processing. Go ahead and 'reply' to the message in your email program, making sure to include the text from the original message, but do not include the indenting marks ('> ' is a popular indenting mark) in your reply. Then make these changes:
Line 61:
old config file: admin_passwd = recipe.admin
---
new config file: admin_passwd = SEKRIT_ADMIN_PASSWERD
Line 87:
old config file: approve_passwd = recipe.pass
---
new config file: approve_passwd = SEKRIT_APPROVE_PASSWERD
Line 183:
old config file: index_access = open
---
new config file: index_access = list
Line 277:
old config file: purge_received = no
---
new config file: purge_received = yes
Line 325:
old config file: subject_prefix =
---
new config file: subject_prefix = [$LIST]
Line 380:
old config file: which_access = open
---
new config file: which_access = list
388c388,390
old config file: who_access = open
---
new config file: who_access = list
Once you have made these changes, add the string 'EOF' at the bottom of the configuration file to tell majordomo not to try to process your email signature as a majordomo command. Remember to strip out any email indenting marks as majordomo will not do that for you automatically (and will not be able to read your new configuration file).
The top of your message should look like this (with no lines above the line beginning with 'newconfig'):
newconfig recipe SEKRIT_PASSWERD
# The configuration file for a majordomo mailing list.
# Comments start with the first # on a line, and continue to the end
Make sure there are no '>>>>>' or stray comments that your email client may have inserted automatically. Send the message to majordomo. If all went well, you should receive an email reply shortly confirming that your changes were accepted:
--
>>>> newconfig recipe SEKRIT_PASSWERD
New config for list recipe accepted.
If you do not receive this message but another message indicating why majordomo did not accept your new configuration file, make the appropriate changes and resend your message.
Now you can check everything out by subscribing yourself to your new recipe mailing list. Send an email to 'recipe-request@vhost1.com' and put 'subscribe' in the body of the message. In a few moments you'll receive a confirmation notice asking you to authenticate yourself (the authentication prevents people subscribing other people without their knowledge). Once you've authenticated, majordomo will let you send and receive messages at 'recipe@vhost1.com'.
After subscribing, your email address will be found in the file <~/www/vhosts/vhost1/Lists/recipe>. If you want to quietly add many people to your list, just add their names to this file. Otherwise, encourage all your friends to send an email message to 'recipe-request@vhost1.com' just as you have done and subscribe themselves to the 'recipe@vhost1.com' mailing list.
majordomo(1), resend(1), The Majordomo FAQ (included with your Majordomo distribution), The Majordomo INSTALL document (ditto), The Majordomo NEWLIST document (ditto, ditto).
Scott Wiersdorf <scott@perlcode.org>
Copyright (c) 2001 Scott Wiersdorf. This document may not be duplicated in any form without prior written consent of the author or his employer.