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
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:
set up the mailing list administrative files for the virtual host
set up the virtual user table or ``virtmaps'' entries
set up the aliases for our list
create the mailing list
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.).
One reason we would not want to put these things in the root of the virtual host is if we did not trust the owner of the virtual host to put the correct information in the Majordomo configuration files. For example, a malicious subhost could tell Majordomo to save the messages archive in ~/etc/passwd, which would effectively clobber our server's password file.
We would not give our subusers their own majordomo.cf file for the same reasons we would not give them their own cgi-bin or ability to execute their own cgi scripts: their scripts run at the same privilege and file system view as our own server scripts.
If you trust your users to leave these files alone, or access the configuration files using methods you prescribe, you will probably be fine leaving these files in the root of the virtual host. If you don't have any subusers who have virtual hosted domains on your server, you're also safe.
If you are at all uncomfortable with another user deciding where files will be saved on your server, make another directory somewhere (maybe under ~/usr/local/majordomo/vhosts) and use that hierarchy for the remainder of this document.
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 firstname.lastname@example.org 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/
If you did not originally set up your virtual host this way and your virtual host root is the same as your Apache document root, you may either create a 'www' directory (or 'htdocs' or 'web', etc.), copy all your web documents there, and change your Apache document root or follow the suggestion in Note 1 above and create your Majordomo files in another directory hierarchy elsewhere on your server.
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.
You may skip this section if Majordomo is already configured for this virtual host. If this is your first Majordomo installation for this virtual host, you will need to do this section.
We need to add some essential Majordomo mappings:
## essential majordomo aliases email@example.com vhost1~majordomo firstname.lastname@example.org vhost1~majordomo-owner email@example.com vhost1~owner-majordomo
These mappings direct mail sent to 'firstname.lastname@example.org' to a locally defined alias (which we will add in step 3) called 'vhost1~majordomo'.
We use a tilde (~) to separate our hostname from the alias; you may wish to use a different character (or no character at all).
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 email@example.com vhost1~recipe firstname.lastname@example.org vhost1~recipe-going-out email@example.com vhost1~recipe-request firstname.lastname@example.org vhost1~recipe-owner email@example.com vhost1~owner-recipe
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.
You may skip this section if Majordomo is already configured for this virtual host. If this is your first Majordomo installation for this virtual host, you will need to do this section.
Add the following four lines (the second line is long and wraps around to the second line. You may continue long lines on another line if you indent the wrapping lines. Portions enclosed by quotes must have a backslash '\' if you decide to wrap your alias lines):
## 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
Notice left-side alias matches the right-side alias of the virtmaps we added earlier. The first line after the comment (which wraps with the '\' and continues with the -C option) is the main Majordomo virtual host alias. When this alias receives an email message it sends the email message to the majordomo program (majordomo is actually called by wrapper which sets special environment variables for majordomo to run properly). The -C option tells majordomo to use an alternative configuration file named /www/vhosts/vhost1/majordomo.cf which we finished editing in the first step.
The next line ('majordomo-owner') is there for historical reasons and usually isn't necessary. The last line is the 'owner-majordomo' alias for this virtual host. You should replace mylogin with the username or email address of the person you want to handle non-automated Majordomo responses and errors. This person is known as the ``Majordomo owner'' or ``Majordomo administrator'' and is responsible for setting up new lists for this virtual host and other administrative tasks. This person is currently you since you're setting up Majordomo.
These three aliases are necessary for basic Majordomo administration for the entire virtual host (e.g., if you had multiple lists for this virtual host).
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
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:
Line 1: The first line after the comment is the main mailing list alias. Mail sent to this address will be sent to every member on the mailing list. Many people typically put a simple :include:/path/list here which is fine for most purposes, until a spammer or other unwanted outsider uses your mailing list for free advertising.
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:
which will simply put the message in the system bit bucket (oblivion).
Line 2: The next line is our mailing list. The portion beginning with ':include:/...' is the actual path to the mailing list. The next portion after the comma beginning with ``|/usr/local/majordomo...'' is Majordomo's archive program. This program will receive a copy of the message sent to the mailing list and append the message to a file called recipe.archive in our Archive directory we created earlier. The -a option indicates to archive2.pl to simply append the message to the archive and the -m option causes archive2.pl to create a monthly rotating archive. You may view the first 20 lines of of the archive2.pl program for other options (archive2.pl is located in ~/usr/local/majordomo).
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:
Line 3: This line ('vhost1~recipe-request') is a ``convenience'' alias. Sending mail to this alias has the same effect as sending mail to the main Majordomo alias with the recipe mailing list already specified. Most majordomo commands (instructions you wish majordomo to carry out for you) are sent in the body of the email message. For example, to subscribe to a mailing list, you would send an email message to 'firstname.lastname@example.org' with the following line in the body:
With the 'vhost1~recipe-request' alias users can simply send a message to 'email@example.com' with the following line:
and majordomo will understand the request as if it were sent with the 'recipe' mailing list information included.
Line 4: This is an historic alias that is not required but some older 'netizens' may send mail to it. Many people leave this alias out.
Line 5: This is the owner of this particular mailing list. In our example, we again use mylogin which should be replaced by the local username or email address of the person who will be administering this particular list. Majordomo separates the main Majordomo administrator from each list administrator. You may specify a separate person for this role if you like. This person will be in charge of list bounces and other list-specific duties such as approving subscribers (if needed) or receiving notification of list actions.
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:
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 'firstname.lastname@example.org' with the following Majordomo command in the body of the message (Majordomo ignores subject lines when processing commands):
Notice that we could have sent an email message to 'email@example.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:
telnet/ssh to the server and edit ~/www/vhosts/vhost1/Lists/recipe.config
request a copy to be sent via email to us so we can edit it in our email client and send it back
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 'firstname.lastname@example.org' with the following Majordomo command in the body:
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:
This is the administrative password for the list; if someone else besides you (the Majordomo administrator) will be managing this list, this will be their password. This password may be used to change the list configuration file and any other kinds of list administration commands that require a password.
Line 61: old config file: admin_passwd = recipe.admin --- new config file: admin_passwd = SEKRIT_ADMIN_PASSWERD
Majordomo allows you to have a third person as the list moderator, if you wish, separate from the Majordomo administrator and list administrator. This password is for the list moderator (if any).
Line 87: old config file: approve_passwd = recipe.pass --- new config file: approve_passwd = SEKRIT_APPROVE_PASSWERD
index_access tells majordomo who is allowed to access the archive index and other file indices. By changing this to 'list' we tell majordomo that only members of the list may have access to the index.
Line 183: old config file: index_access = open --- new config file: index_access = list
purge_received tells majordomo to strip out 'Received' headers from messages that list members post to the list. This gives an added degree of privacy for your list members, but may make troubleshooting difficult when there are problems.
Line 277: old config file: purge_received = no --- new config file: purge_received = yes
subject_prefix tells majordomo to add this string to the front of all subject lines posted to the mailing list. This is a good feature for people who subscribe to many mailing lists to be able to readily see where the message is coming from. You may set this to whatever value you like, though majordomo provides a couple of useful variables (e.g, $LIST, $SENDER, etc.)
Line 325: old config file: subject_prefix = --- new config file: subject_prefix = [$LIST]
which_access tells majordomo who may send a 'which' command. The 'which' command is described in the majordomo man page.
Line 380: old config file: which_access = open --- new config file: which_access = list
who_access tells majordomo who may send a 'who' command. The 'who' command is described in the majordomo man page.
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 'email@example.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 'firstname.lastname@example.org'.
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 'email@example.com' just as you have done and subscribe themselves to the 'firstname.lastname@example.org' mailing list.
resend(1), The Majordomo FAQ (included with your
Majordomo distribution), The Majordomo INSTALL document (ditto),
The Majordomo NEWLIST document (ditto, ditto).
Scott Wiersdorf <email@example.com>
Copyright (c) 2001 Scott Wiersdorf. This document may not be duplicated in any form without prior written consent of the author or his employer.