WN home page

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

Limiting Access to Your WN Hierarchy


There are two ways to limit access to your hierarchy. You can restrict access by hostname or IP address and you can restrict access to users whose name and password are in a file on your server (authentication). You can, of course, do both. To restrict access to an entire hierarchy you must restrict access to each of its subdirectories.

Warning: If access to a directory is restricted by either of the ways described here the restrictions affect only that one directory and not its subdirectories.

10.1 Access Control Files: Limiting Access by Hostname or IP Address

If you have opted to limit access to your server in this way you do so by setting the value of the Accessfile= in the index file for a directory. In the directory directive part of an index file, a line like:

Accessfile=~/dir/.access

specifies that the the access control file wnroot/dir/.access contains restrictions on what sites are allowed to access this directory. The Accessfile= directive takes the value of a path to a file in different forms. If the path begins with a '/' or with '~/' then it is relative to the WN hierarchy root, and otherwise it is relative to the directory containing the index file in which the directive occurs. In particular the access file must be located within your WN hierarchy.

Warning: If the Attributes=serveall directive is used in a directory with restricted access be sure the access file is not serveable. You can do this by giving it a name starting with '.' or ending with '~', or better, put it in a directory from which nothing is served.

Also note that limiting access to this directory does not limit access to subdirectories. The Accessfile= line must occur in the index file of each directory you want restricted. Of course, they can all refer to the same file. To use the same file for several directories be sure to use the "Accessfile=~/dir/.access" form of the directive so the line can be the same for every index file.

This will limit access to the server to those clients with an IP address or subnet address listed (and not excluded) in the file .access listed in the Accessfile= directive.

If a recursive title search or keyword search is requested and some directories have restricted access only those directories which have the same access file as the directory where the search started will be searched. In fact the path must be the same in the Accessfile= directive for both directories (and must necessarily be of the form "Accessfile=~/dir/.access" or "Accessfile=/dir/.access" rather than "Accessfile=.access").

There are three possible formats for lines in the access file. First you may list the domain names of the machines using wild cards provided the machines all have proper PTR DNS resource record. For example the line:

dogbert.widget.com

allows access to one host. To allow access to all machines in the widget.com domain, use the line:

*.widget.com

Note that this will not allow access to a machine called widget.com if it exists. One would need to add in the line widget.com to allow it access.

You can also allow access by IP address and, in general, this is somewhat more secure than using the hostnames. There are two line formats for IP addresses. The first is to explicitly list an IP address like 129.111.222.123 or a subnet address like 129.111.222. or 129.111.. In case a subnet address is listed it must end with a period like:

129.111.222.

or

132.123.

but complete IP addresses like 129.111.222.123 should not end with a period. If a subnet address is listed any client with an IP address beginning with that subnet address will be allowed access.

The second format for IP address restriction uses a net address, net mask pair with the two parts separated by a '/'. For example:

129.111.222.0/255.255.255.0

The presence of the '/' indicates to the server that this format is being used. The part before the '/' is the "net address" and the part after is the "net mask". The server will then take the IP address of the remote client, do a logical "and" of each of its four parts with the corresponding four parts of the net mask (255.255.255.0 in this example) and check that the four results agree with the four parts of the net address (129.111.222.0). So the access file line above will match (and allow access to) precisely those machines with IP address of the form 129.111.222.x because the 'x" part is "anded" with 0 and hence becomes 0, while the first three parts are "anded" with 255 and hence unchanged, so they must equal 129, 111, and 222 respectively.

Note that if you have #define NO_DNS_HOSTNAMES in the config.h file you must use one of the IP address formats above and not the format using a domain name. This is because #define NO_DNS_HOSTNAMES causes WN never to convert IP addresses to hostnames.

You can also exclude IP addresses or domain names by prefixing them with an '!', so if the access file contained only the lines:

!speedy.acns.nwu.edu
*

Access would be permitted to every machine except speedy (the * matches, and allows access to, anything). Likewise:

!129.111.
!129.222.0.0/255.255.0.0
*

would allow access to everyone except those on subnet 129.111 or on subnet 129.222. In general prefixing a line (in any of the three formats) with '!' causes immediate denial of access to any matching host. The first matching line (with or without leading '!') for a host is the one which takes effect. Once a match is found access will be granted (or denied if a '!' is present) and no subsequent lines in the access file will be considered.

A line in an access file cannot exceed 255 characters in length and every line must end with a newline (some editors don't guarantee this and the last line of a file may not have a newline). A blank line at the end is fine. If these conditions are not met an error of type "Access file line overflow" will be generated.

10.1.1 Privileged Sites

You may also designate "privileged sites" in your access files. If you list a site in an access file with a '+' prefix like:

+hopf.math.nwu.edu
+123.123.123.1
+111.111.111.0/255.255.255.0

then requests from that site will be exempt from any password requirements (as described below). In other words, no username/password pair will be required for requests from these sites, even if they are required from other sites.

Obviously the '+' and '!' prefixes for access file lines are mutually exclusive.

10.1.2 Customized Error Messages

It is possible to specify a URL referring to a customized document intended as an error message when access is denied. The easiest way to do this is to place the line:

Access-denied-URL=http://host/dir/foo.html

or the line:

Access-denied-URL=/dir/foo.html

at the beginning of the access file. When this is done and a request is denied because of failure to meet the restrictions in that access file, the browser will be redirected to the URL "http://host/dir/foo.html" or "/dir/foo.html". Access-denied-URL= is also a legal directory directive which may be placed in an index file.

10.2 Limiting Access by Password Authentication

You can also maintain a password file (or files) on your system and restrict access to those users who can supply a valid user name and password. This is the so-called "Basic" authentication described in the HTTP/1.1 protocol.

Warning: I would strongly advise against using basic authentication described here to protect sensitive information on a server which runs on system on which untrusted users have accounts.

Notice that if none of the options -t, -T and -u are used then a user with his own home page can make a symbolic link to any file readable by the server and that document will be served. This is true even if the linked to document is in a password protected directory with limited access or is outside the server data hierarchy.

The use of basic authentication with WN involves two additional programs which can be found in the /bin directory of the distribution. The first of these is wn_mkpasswd which is a perl utility for creating and altering password files. It should be run the first time with the command:

wn_mkpasswd -n filename

This prompts you for a username and password and then creates a password file called "filename" with that entry. On subsequent uses the -n argument should be omitted so that entries will be added to the existing file instead of starting a new one (the -n is for "new"). If a subsequent entry is made with the same user name the entry for that user will be replaced. If the "filename" argument is omitted then the default name of wnpasswd is used. There is another optional argument which may be used with this program. The command:

wn_mkpasswd -D filename

causes a UNIX NDBM database to be created or used instead of a simple flat file. This is may be useful if you have a very large number of password entries. Depending on your system, the database may reside in the two files filename.dir and filename.pag, or in a single file filename.db. The -n option has no effect when combined with the -D option. To create a new database you must remove or rename the .pag and .dir or .db files. To remove a single entry from a password file use the command "wn_mkpasswd -d filename" or "wn_mkpasswd -D filename" for an NDBM database.

Note: To enable the NDBM features of wnauth you will have to uncomment the lines in wnauth/Makefile starting with #DBMFLAG and #DBMLIB and recompile the wnauth program by running the UNIX make(1) utility in the /wnauth directory.

Once you have created your password file and made sure that it is readable by the user id under which the server will run, you are ready to set up the WN authentication module, called wnauth. This is done on a per directory basis by three entries in directory record of the index file. Entries like:

Authorization-realm=myrealm@host.domain
Authorization-module=~/cgi-bin/wnauth "~/dir/wnpasswd"
Authorization-type=basic

in the directory record specify that the authentication module wnauth is being used to check user's passwords and that it should consult the password file "wnpasswd" in wnroot/dir/. If instead of the password file "wnpasswd" you are using a NDBM database "wnpasswd.dir" and "wnpasswd.pag" created with "wn_mkpasswd -D" as described above (or created some other way), then you should use the line:

Authorization-module=~/cgi-bin/wnauth -D "~/dir/wnpasswd"

The password file can also be specified with the -P option as in:

Authorization-module=~/cgi-bin/wnauth -P wnpasswd

The name of the password file can be given in three different formats: beginning with a '/ meaning it is relative to the system root, beginning with '~/' indicating it is relative to the WN hierarchy root, or something else indicating it is relative to the directory containing this index file. If you use the '~/...' form it is a good idea to put the file name in double quotes as shown above to prevent the shell from trying to interpret the '~'.

Warning: If the Attributes=serveall directory directive is used in a directory with access restricted by password, be sure the password file is not serveable. You can do this by giving it a name starting with '.' or ending with '~', or better, put it in a directory from which nothing is served.

Note that if you designate a privileged site in your access control file then any users from that site will not be requested to supply a user name and password.

For security reasons when you use wnauth or any Authorization-Module= you are required to use either the -t or -T option or the -a or -A option when the server is run and to have the index.cache file in the protected directory owned by the trusted user or group. This is to guard against counterfeit authentication modules. Note that the four command line arguments -a, -A, -t and -T all take a numeric argument. Thus the command should be "./wnsd -t 203" and not "./wnsd -t joe" if user joe has user id 203.

The Authorization-Realm= line is to notify the client that for any document on this server with the same realm as this one, the same username/password combination will be valid, so the client need not ask the user for a username and password, but can reuse the one supplied for the first document with this realm. For security reasons it is a good idea to put your host and domain name in the realm. This may at least discourage attempts at other sites to forge your realm in order to collect user passwords. Your users should also be warned never to enter their password if the realm displayed when they are prompted for a password contains a different hostname than the one in the URL they are trying to access.

If you use different realms on the same server you should be aware that popular browsers are somewhat cavalier in their treatment of realms. In particular once a username/password pair has been accepted a browser might well continue to use it on the same site without checking the realm until authentication fails. This practice of trying to guess the username/password is more efficient if the guess is correct and most of the time it is.

Also note that password protecting a directory does not protect its subdirectories. The three "Authorization" lines must occur in the index file of each directory you want to protect. Of course, these lines can all be identical for different directories if you use the:

Authorization-module=~/cgi-bin/wnauth ~/dir/wnpasswd

form to specify locations relative to your WN root.

There is also support for a "group" file with authentication. This feature is invoked by using the -g and -G options with the wnauth authentication module. The line:

Authorization-module=wnauth -g grpname -G foo -P wnpasswd

means to use the group name "grpname" and the group file "foo". The group file is a file in the format of a UNIX group(5) configuration file. That is, it has lines of the form:

grpname:*:99:user1,user3,user5

where the fields are separated by colons, the first field is a group name, and the fourth field is a comma separated list of user names. wnauth will ignore the second and third fields. If the line above is in the file foo and wnauth is invoked as above then a user will be granted access provided the supplied password matches that in the wnpasswd file and the user's username is in the list after the second ':' in the line starting with the group name. Thus, in this example users user1, user3, and user5 will be given access if they provide valid passwords and other users will not.

The format of a group file used by Apache is also supported. This format has lines of the form:

grpname: user1 user3 user5

which is the group name, a single colon and a space separated list of user names.

It is possible to specify a custom error message to be sent when password authentication fails because of an incorrect password or username as in:

Auth-denied-file=~/dir/foo.html

This specifies that any request for a document in this directory which is denied because of an authorization module restriction results in the file ~/dir/foo.html being sent instead. A default value for all directories can be set by uncommenting the #define AUTH_DENIED_FILE" line in config.h and recompiling. Note that this is not a URL but the name of a file whose content is to be sent as error text when authentication is denied. If the file name starts with '~/' as above it is assumed to be relative to the WN root directory. Otherwise it is assumed to be a path relative to the directory containing the index file.

The "Basic" authentication scheme is flawed in that it involves the transmission of essentially unencoded passwords over the network. It is relatively easy for unscrupulous people to obtain "sniffer" software which allows eavesdropping on all local network traffic. This means, in particular, that it is possible to intercept passwords.

This particular problem is remedied by the HTTP/1.1 Digest Authentication scheme. Digest authentication is supported experimentally by WN, but has the rather severe drawback that no publicly available clients currently support it. It is experimental, because I have no client to test it and hence it has barely been tested.


WN version 2.0.3
Copyright © 1998 John Franks <john@math.nwu.edu>
licensed under the OpenContent Public License
last-modified: Fri, 09 Oct 1998 18:18:09 GMT
[Previous] [Next] [Up] [Top] [Search] [Index]