port [other options] wnroot images/powered.jpg" border="0" width="190" height="41" align="right" alt="WN home page" >

Version 2.5.0
[Previous] [Next] [Up] [Top] [Search] [Index]

Installation and Setup of WN


2.1 Installing the Software

Get the source file from http://hopf.math.northwestern.edu/ (U.S.) or http://www.wnserver.org/ (Europe) then uncompress it and untar it to make the WN source directory hierarchy. The file must be uncompressed with the GNU compression utility gzip(1) (or gunzip(1)). The resulting file wn.tar should be unpacked with the UNIX tar(1) utility using "tar -xvf wn.tar". The top level of the directory created by untarring this file contains several directories, including: wn, wndex, wnauth and docs.

2.1.1 Configuring WN

If your system supports perl, the quickest way to get your server configured is to run the perl program "configure" which is in the main source directory. Do this with the command:

perl configure

This program will ask you various questions, like what version of UNIX you are using and the path to the directory you want to be the wnroot of your data hierarchy.

Default answers are printed in square brackets [ ] so you can simply press return to enter that value. You can quit at any time by pressing Ctrl-C and nothing should be changed. If you want to try it once to see what the questions are, that is fine.

This program creates two files: config.h and Makefile which are customized based on the answers you gave. You may rerun this program as many times as you like. The first time you run the program the default values are those in the file config.h.dist. Subsequent times the default values for all question answers are taken from the most recent config.h you have produced (if it still exists in the top level directory).

An alternative to running this program is to copy the files Makefile.dist and config.h.dist to Makefile and config.h respectively and edit them manually. If you want to use some of the features which are not turned on by default like multiple IP interfaces, you will have to edit at least config.h. I recommend starting with the perl program and getting your server up and running. Then you can go back browse through config.h to see if there are things you want to change. If there are you will have to recompile but that takes only a few minutes.

Here are some of the questions you will be asked when you run configure. You will be given a list of supported operating systems and asked to pick the one you are using, e.g. SUNOS, SOLARIS2, AIX, LINUX, etc. You will be asked the complete path name of your data directory. You will also have to enter the names of the access and error log files you wish to use (they can be the same file). If you don't want logging or you want to use the UNIX syslogd(8) system utility (i.e. the -S option) then these should both be defined to be the empty string (i.e. a pair of double quotes with nothing between them like ""). If you specify the names of these log files then you must make sure that either these two files exist and are writable by the server or that they are files in a directory where the server has permission to create them.

Additional customizations in config.h are possible but should not be needed. These customizations require that you manually edit the config.h file. For example, there is a #define DEFAULT_URI line in the config.h file.

You may also customize the file Makefile in the top level directory. In particular you should do this if you wish to specify a C compiler other than the UNIX cc(1) utility (e.g. gcc) should be used for compiling. Also some systems require that special libraries for sockets, or whatever, be mentioned in the compile command. The configuration program attempts to do this, but I am working from user reports since I do not have access to most of the UNIX variations. If they are incorrect please let me know.

2.1.2 Building WN

In the top level directory do a make(1) to produce the server wnd, the stand-alone version wnsd and the utility wndex. This utility is used to produce index.cache files for use by the server. If the make proceeds without problem you should next do a "make install". This will strip the binaries and place them in the top level bin directory or whatever directory you specified when you ran the configure program.

If you specified a log file name or error log file name when you ran the configuration program or edited config.h you will need to make sure that these files exist and that they are writable by the user id under which the server will run. The best way to do this is create the files as root ("touch wn.log"), then change their ownership to the appropriate user ("chown nobody wn.log") and finally set the permissions appropriately ("chmod 644 wn.log"). An alternative is to create a directory in which these files will reside and make sure that the user nobody has permission to create files in this directory. Then the server will create the files with proper ownership and permissions.

2.2 Running the Server as a Stand-alone Daemon

You can now either run the server as a stand-alone daemon, the wnsd executable, or run under the UNIX inetd(8) system utility, the wnd executable. We first describe the stand-alone version. Run this with the command:

wnsd -p port [other options] wnroot

where "port" is the number of the port on which you wish the server to run. If this is a non-privileged port (i.e. > 1024) then wnsd can be run as an ordinary user. However, for privileged ports like 80 you must run the command above as root. If wnsd is run without the -p option it will use port 80 by default. If wnsd is run by root then when it starts up it will change its user id to the one set when running the configuration program or by editing the config.h file line containing #define USERID. Otherwise it will have all the permissions of the user who runs it.

The safest practice is to use the numeric UID of nobody for the USERID set in config.h (this is the default) and then start the server as root.

Note: on HPUX and perhaps other systems user nobody cannot be used. In this case just create a new user, say "www", with the fewest possible privileges and no shell.

The server needs to have root permissions to connect to a socket on a privileged port and listen for requests. But immediately after doing so it will change its user id to that of nobody and have minimal access permissions. In this situation the user nobody needs to have only read permission to your server data and should not own or have have write permission. In particular nobody should not have ownership or write access of the index.cache database file described in the chapter "Creating Your WN Data Hierarchy" of this guide.

2.3 Running the Server Under inetd(8)

The other way to run the server is to use it under the UNIX inetd(8) system utility. This is an efficient way to run the server if the load on it is relatively light (a few thousand hits per day) and the host on which it runs is used for other purposes. There are variations on how inetd(8) works from system to system so you may need to look at the man page for the UNIX inetd.conf(5) configuration file. Here's how it works under many systems (e.g. SunOS 4.1.3): Edit the file UNIX services(5) configuration file and create the line:

wnd 80/tcp

or replacing 80 by the port you wish to use. Then edit the file inetd.conf(5) and insert the line:

wnd stream tcp nowait nobody /path/wnd wnd

After the last wnd you can have optional arguments to turn on logging or use a different data directory. Some inetd(8) limit the number of arguments you may use so I prefer to use a small program in place of wnd here. My inetd.conf(5) line looks like:

wnd stream tcp nowait nobody /path/wn.rc wn.rc

and wn.rc contains only the two lines:

#!/bin/sh
exec /path/wnd -t 202 -L /path2/logfile wnroot

It is important to run wnd as nobody (the fifth field in the inetd.conf(5) line above) or some other user with no special access privileges. If you are using an inetd(8) with without the capability to set UID on startup (e.g., Ultrix), you should define the group ID and user ID in config.h so that the program is not running as root (look for the #define USERID and #define GROUPID and set the values appropriately). It should never be necessary to run wnd under inetd(8) as root and to do so would be a serious mistake for maintaining security. Every attempt has been made to make wnd as secure as possible, even if it is run as root, however, no program accessible to remote users on the Internet can be assumed perfectly secure. See the chapter "Security on the WN Server" in this guide.

After editing the inetd.conf(5) and services(5) files you should find the process id number of the inetd(8) process and use the UNIX kill(1) utility to reload the configuration using "kill -HUP <process_id>". This must be done as root. You find the number "<process_id>" by using the UNIX ps(1) utility or by looking at the contents of the file (which you specified when you ran the configure program) in which the server stores this number.

2.4 Your Hostname: What's in a Name?

If the fully qualified domain name of your server is abc.com you might like to have your server known as www.abc.com or some other "vanity" name. For most purposes this is simply a matter of properly setting up Domain Name Service (DNS) on your system so that the system responds to the desired name.

Note: To use multiple vanity names for different IP addresses on a single server see the chapter "Multi-homed or Virtual Servers on the WN Server" in this guide.

There are a few instances, however, where the WN server does use its own hostname. Ideally, in my opinion, the server should do nothing with its hostname and not even need to know it. This is not possible for two reasons.

First, the CGI/1.1 protocol requires the server to pass its hostname to CGI programs in an environmental variable whenever those programs are run. Secondly clients often implement redirection so that it cannot handle relative but only complete URLs. (This is a mistake in my view, but one we have to live with.) Thus when a server redirects to another local document it must supply its own hostname. These are the only places WN uses hostname.

For most cases then, WN only uses it hostname when a redirection is done. This happens in several circumstances. The most common is when a request is made for a directory any the trailing '/' is left off of the URL.

So how does WN know its hostname? When you run the configure program you are queried for the value you want or you have the option of using a system call at the time the server is run. This value is placed into the config.h header file and compiled into your server. In the file config.h the #define WN_HOSTNAME macro is set by default to the empty string. If this is not changed the server will get its name from the UNIX gethostbyaddr(3) system call. If this is set to another string that string will be used. If you are using WN as a multi-homed server then you need to set different names for the different IP addresses. This is done in the file wn/vhost.h which you edit to set up the correspondence between IP addresses and wnroot directories.

2.5 Testing Your Setup

After compiling and setting up the software you can test it on a sample directory provided with the distribution. To do this first make a symbolic link in your wnroot data directory to the docs directory in the source distribution. The command "ln -s /your/src/dir/docs docs" executed in the wnroot directory should do this. If your system does not support symbolic links you can copy this directory and its subdirectories to your data directory temporarily.

Now you are ready to test your server installation on this directory. Try it with your favorite HTTP client. The URL should be:

http://localhost/docs/index.html

2.6 Shutting Down Your Server

If your are running under UNIX inetd(8) system utility as described above then to shut down the server first remove or comment out the line you created in the UNIX inetd.conf(5) configuration file. Then you should again find the process id number of the inetd(8) process and run the UNIX kill(1) utility using "kill -HUP <process_id>" where "<process_id>" is the process id number of inetd(8) just as you did to start WN.

If you are running wnsd, the stand-alone version of WN, you should find the process id number of the running wnsd by using the UNIX ps(1) utility or by looking at the contents of the file (which you specified when you ran the configure program or by using the -q option) in which the server stores this number. Then you run the UNIX kill(1) utility using "kill <process_id>" where "<process_id>" is the process id number of wnsd. If you started the server as root you should be root to kill it.

2.7 Managing Log Files

There are two ways to log WN transactions: dedicated log files or using the UNIX syslogd(8) system utility. We first describe dedicated log files.

Normally when you use WN you will keep two log files. The first is a log of all "normal" transactions and the second records error conditions or items which might require your attention. For example, if the server cannot find a file which your index.wn file indicates should be served it will log an error. The error log file can be the same file used for the normal transaction log. In general the difference between the two is that the error log gets information about anything which might require attention of the maintainer while routine transactions and errors which are simply user errors tend to go to the regular log. The intent is that a conscientious maintainer should keep an eye on the error log but need not read the (much larger) log of regular transactions.

There are two ways to tell the server the names of these files. The first is by supplying the file names when you run the configure program and then compiling these into your server. And the second is by supplying the file names on the command line when you execute the server. This is done with the -L option and the -l option to specify the transaction and error log files respectively.

For example, executing the command:

wnsd -L /path2/logfile -l /path3/error.log wnroot

will cause the server to use "logfile" and "error.log" as the log file and error log respectively. Of course, it is necessary for the server to have write permission to these files and execute permission on the directory containing them.

A good way to achieve this if the server is running as nobody is to create the files yourself and change their ownership to the user nobody. This can be done, for example, with the commands:

touch logfile
/usr/etc/chown nobody logfile
chmod 600 logfile

executed as root in the directory where the log file is to reside. The first of these commands creates the file "logfile". The second makes nobody the owner and the third gives nobody (and no one else except root) permission to read and write this file. You might want to allow others to read, but not write to the log file, or security of the log file might not be a concern.

Thus a program executed by the UNIX crond(8) system utility to rotate log files might look like:

cd /path2
mv logfile logfile.old
touch logfile
chown nobody logfile
chmod 600 logfile
kill -HUP `/bin/cat /path/to/wn.pid`
chown maintainer logfile.old
chmod 600 logfile.old

where /path/to/wn.pid is a file containing the processes id of the server created by using the -q option or by specifying this filename when the configure program is run. If neither of these has been done the stand-alone server, wnsd, will print its process id on the UNIX stdout(3) stream when it is run. If you are using wnd under inetd(8) there is no need to send the -HUP signal as the server must close this file after each transaction.

If you are using a system that supports the logrotate program, it provides a good way to handle logs. Here is an excerpt from a typical logrotate.conf file.

/var/log/wnsd/error_log {
    daily
}
/var/log/wnsd/access_log {
    daily
    postrotate
        /usr/bin/killall -HUP wnsd
    endscript
}

This causes the logs to be rotated daily. The command /usr/bin/killall -HUP wnsd assumes that your system supports the killall command, in which case it finds the process id of the wnsd process and sends it the -HUP signal, as was done by the kill command. in the script above.

There are three formats which the server can use in writing its log files, each with three options concerning how much DNS lookup to do for the remote host. The two most common formats are "verbose" and "common log format". The verbose mode is essentially the common log format but with the user-agent, referrer, HTTP cookie, and virtual server nickname appended to the line for that transaction as well as better transaction error messages if necessary.

You can chose between verbose and common log formats by answering the relevant question when running the configure program before compilation (or by editing config.h).

To use the third format you need to use the -v command line option. When the server is invoked with the -v option it will write a log file in the format specified by the value of this option. The legal values for this option are "common", "verbose", and "ncsa". They cause the log file to be written in the so-called common log format, or WN's verbose format including user agent, referrer, X-Forwarded-For header, virtual server nickname, and cookies, or in the NCSA extended format which includes just referrer and user agent. When using verbose logging the nickname (enclosed in angle brackets) will be the last field of each log entry. If virtual hosting is not being used this field will be omitted.

More precisely a verbose log line begins with a normal "common" log format line and then adds the following:

<(pid/count) msg1: msg2> <user_agent> <referrer> <cookie> <X-forwarded-for> <nickname>

The punctuation characters, i.e., < > ( ) and :, will always be present in this order. The fields "msg1" and "msg2" may contain additional parentheses or colons. Hopefully none of the fields will contain the character '<' or the character '>', but "referrer", "cookie", "X-forwarded-for" and "nickname" are provided by the browser or the server maintainer so WN has no control over them.

The fields are as follows:

field description
pid Process id of the process serving the transaction.
count n if this is the nth transaction of this (keepalive) connection.
msg1 Description of transaction. May be sent to user.
msg2 Description of transaction. Information NOT sent to user.
user_agent From the HTTP user agent header.
referrer From the HTTP referer (sic) header.
cookie From the client's cookie header.
X-forwarded-for From the client's X-Forwarded-For header.
nickname Value assigned this virtual host by the maintainer (omitted if virtual hosting is not used).

The NCSA format will likely only be of interest if you want to use log processing tools which expect this format. If the -v option option is not specified the server will default to either the common log format or the WN verbose format depending on which was selected when the configure program was run. The utility wnv2c can convert verbose log files to log files in the shorter common log format.

The WN server does not send the UNIX stderr(3) stream output to the error log file, but leaves its default the terminal from which the server is invoked. This allows the maintainer to set it to a file of her choice, for example the error log, or leave it directed to the console window in which wnsd was invoked. To redirect it to a file called my.errs simply run wnsd with a command like "wnsd <options> 2>my.errs" if you are using a Borne-like shell like sh(1). The server itself sends very few things to stderr(3) -- only errors which it is impossible to put in the error log (like "Can't open error log file"). The real usefulness of redirecting stderr(3) comes when you are creating CGI/1.1 programs because their errors are typically sent to stderr(3) so you can easily view them rather than have them buried in a log file.

2.8 Trouble Shooting

If things are not working as they should here are some tips to help you isolate the problems.

If the compilation was successful you can check the server itself by executing it from the command line. If you use the command:

wnd wnroot

it should run and pause for input. Type the line:

GET /<ret>

and in response wnd should print the raw HTML of the index.html file in your top level directory (perhaps along with a message about not being able to open a log file). If instead you type:

GET /docs/overview.html<ret>

(and you still have the /docs subdirectory in your top level directory) the overview document should be sent to your screen. If this doesn't happen there should be an error message which may be helpful. Better error messages are placed in the log file so you may want run wnd again with the additional arguments "-L logfile" and then examine the contents of the log file. Or if you run "wnd -L /dev/tty" the log entries will be printed to your screen instead of being put in a file. If the server can't open a file, for example, the name of that file will be recorded in the log file. Check its permissions. Remember that all files that wnd serves must be world readable. More serious errors are put in a separate error log. So you might want to try the command "wnd -L file -l file2" and then type the GET requests described above.

If this succeeds you should run the server for real, either under inetd(8) or stand-alone. In order to use port 80 the server must be started by root. It will then switch to user nobody. It does this immediately after connecting to port 80, before it does anything else including opening its log file. If you get a message that the server cannot open its log file then either you have specified putting the log file in a directory where user nobody does not have permission to create files or you have specified an existing file which the server does not have permission to write.

After starting the server a useful test is to use the UNIX telnet(1) utility to connect to your server at port on which you are running. You should get a connection message and a pause for input. If you get a "Connection refused" message and you are running under inetd(8), it is likely there is a problem with your inetd(8) setup or for some reason your system can't find or can't execute the wnd binary. If you are using wnsd this message means that wnsd is not in fact running.

If you still have problems feel free to ask questions on the WN list server. There are many helpful people there. But it is a good idea to try the steps above first and to include the relevant log file messages with your request.


WN version 2.5.0
Copyright © 1998-2005 John Franks <john@math.northwestern.edu>
licensed under the GNU Free Documentation License
Last modified: Sat June 18 2005
[Previous] [Next] [Up] [Top] [Search] [Index]