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
.
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.
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.
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 usernobody
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.
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.
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.
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
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.
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.
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.