Pubcookie Home > Documentation 
 
Pubcookie Homepage Pubcookie 3.0.0
Login Server Installation Guide
Component:  Pubcookie Login Server
Audience:  All
Modified:  May 15, 2004
 

Included on this page:

Introduction

The Pubcookie login server has two primary functions: to authenticate users and to issue authentication tokens (granting cookies) consumed by Pubcookie-enabled target application servers. Authentication occurs either by verifying user-provided credentials via a backend authentication service (Kerberos, LDAP, etc.) or by checking a token that was created on a previous visit to the login server. Example code to interface to an authentication system is provided.

Implementation

The Pubcookie login server consists of two primary components: a CGI program and a keyserver.

The Pubcookie login server uses the CGI program to handle all HTTP requests. This CGI program, hereafter referred to as "the login cgi" or index.cgi, is compiled from C and is the central Pubcookie component. The login cgi displays the web page where users are asked to enter authentication credentials as well as other web pages that display error messages.

The Pubcookie login server uses the keyserver to generate, distribute, and manage DES keys for application servers.

Due to the important nature of the Pubcookie login server, the only other services that should be run on the same system are those which receive an equally high level of scrutiny for security. As deployed at the University of Washington, the Pubcookie login server is powered by the Apache web server software. Other web server software which supports CGI and SSL should also work, but this supposition has not been tested.

Authentication Services

The login cgi is designed to support different authentication feature sets by abstracting them into login "flavors". However, only one login flavor is currently provided: the "basic" login flavor. The basic login flavor supports username/password single-sign-on authentication and a simple pluggable interface to backend authentication services called "verifiers." Pubcookie currently ships with several verifiers for the basic login flavor:

  • "kerberos_v5": check username/password against a Kerberos 5 KDC.
  • "ldap": check username/password against an LDAP server.
  • "shadow": check username/password against /etc/shadow.
  • "alwaystrue": allow any username/password combination to authenticate.

You can choose which verifiers to build at compile time and then decide at run-time which verifier is used by the basic login flavor by setting the "basic_verifier" configuration variable (see run-time configuration). Some verifiers allow or require further configuration; see the section referring to each verifier for details.

Apache Configuration

Choosing the location of your login page

Depending on your deployment environment, you may choose to install the login server in a number of configurations. Two general models are presented here, along with the necessary Apache configuration directives for each.

Specifying the login server URL as a directory

For a clean looking URL for your login server, you can install the login cgi as the default file in a directory. For example, the University of Washington uses the server's root directory, resulting in https://weblogin.washington.edu/ as the login server URL. This address is easy for users to identify in a browser's address field.

The default binary filename for the login cgi, index.cgi, is a common name for a cgi program that will be executed when a directory's URL is requested. The DirectoryIndex directive tells Apache how to handle requests to directories. See the mod_dir documentation for more information on its use. When a request is made for a directory, Apache will choose the first file it finds in the DirectoryIndex list. This can be your login cgi.

For example, you might use the follow DirectoryIndex directive:

DirectoryIndex index.html index.cgi

If this is the configuration you choose, make sure there isn't an index.html file in the same directory as the index.cgi binary.

Explicit specification of login cgi

The login cgi does not depend on its own filename. Therefore, it can be deployed as index.cgi, login.cgi, or any other filename handled as a cgi script. It can also be put in any subdirectory you wish. Thus, it really depends on what you want users to see and how you want to configure things in Apache.

To avoid conflict or confusion with the server's main page, you might deploy a login server at https://www.example.edu/cgi-bin/login.cgi or maybe https://www.example.edu/login where /login is mapped to the login cgi (index.cgi or whatever you rename it to).

Note: in order to configure applications servers, other system administrators will need to know the URL of your login server.

Apache configuration directive you might have to tweak

Apache needs to know how to identify and handle cgi scripts. Some distributions of Apache will have the cgi handler disabled, you will want to make sure the following line is in your httpd.conf and not commented out.

AddHandler cgi-script .cgi

Build & Install the Login Server Components

Compiling the source code has been made easier with autoconf. (Thanks Jon Miner, University of Wisconsin!)

To build a barebones login server, run:

$ ./configure --enable-login --disable-apache
$ make

This will build the login cgi and its "alwaystrue" verifier, as well as the keyserver and keyclient binaries. It also prepares for installation using the default installation directory prefix, henceforth called {PUBCOOKIE_DIR}, of /usr/local/pubcookie.

To build other verifiers (e.g. "kerberos_v5", "ldap", or "shadow") along with the other base components, look at the configure options and re-run the configure script accordingly:

$ ./configure --help

To install the login server components into the installation directory, run:

$ make install

Now you can view the results by listing the contents of {PUBCOOKIE_DIR}.

$ ls /usr/local/pubcookie
keyclient  keys  keyserver  login  login_templates  login_templates.default

Setup Run-time Pubcookie Config File

The login cgi and keyserver share a simple configuration file: the Pubcookie config file. Most run-time configuration can be set up via this file, which is located at {PUBCOOKIE_DIR}/config. The format is one attribute-value pair per line.

A sample config file appropriate for a login server is provided as a starting point. You might consider copying it to {PUBCOOKIE_DIR}/config and edit it there, e.g.:

$ cp doc/config.login.sample /usr/local/pubcookie/config

Refer to the config documentation to setup your configuration file. Some of the more notable variables are:

debug
An integer. A non-zero value enables debug logging. The higher the number, the more debugging output that is generated.
login_host
The hostname of login server (e.g. weblogin.example.edu)
login_uri
The complete URI of the login cgi (e.g. https://weblogin.example.edu)
enterprise_domain
The domain under which all hosts will live. Must be at least a second level domain (e.g. example.edu).
basic_verifier
The verifier to use for the "basic" login flavor.
keymgt_uri
The location of the "keyserver" CGI. See the Key Management section.

The following configuration variables are crucial, as they determine the keypair used to sign and verify "login" cookies and more importantly to authenticate your keyserver's identity. In most cases, they should refer to the same files that your web server uses for SSL.

ssl_key_file
The location of the SSL key.
ssl_cert_file
The location of the SSL certificate.

The following configuration variables define which Certificate Authority (CA) is trusted by your keyserver. If your institution uses a single CA without any intermediate certificates, set ssl_ca_file to the full path to the CA's root certificate. If your institution uses multiple CAs or intermediate certificates, you'll need a directory (ssl_ca_path) containing those certificates named via their OpenSSL hashes. At least one of ssl_ca_file and ssl_ca_path must be specified.

ssl_ca_file
The location of a single CA.
ssl_ca_path
A directory containing files named after their OpenSSL hash.

Again, see config.html for a full list of configuration variables and their descriptions.

Key Management & Setup

{PUBCOOKIE_DIR}/keys is the location of the keystore used by the login cgi. The login cgi makes use of several different keys.

Reuse SSL keypairs for the "login" cookie and keyserver

The login cgi uses a keypair to sign and verify the "login" cookie that maintains a user's single sign-on session with the login server. These files are kept exclusively on the login server and are also used by the keyserver. We recommend that you reuse your existing private key and SSL server certificate, rather than generating a new keypair. The login cgi will automatically do so if you set ssl_cert_file and ssl_key_file correctly. If this works for your keyserver, it is probably the optimal solution.

Generate granting keypair for authentication assertions

Next, a "granting" keypair is needed to secure authentication assertions sent from login server to application servers, as represented by a "granting" cookie. The key is kept exclusively on the login server; the certificate must be distributed to every application server. We've historically recommend that you generate a new keypair for this purpose, although you could reuse you SSL keypair here too.

$ openssl req -new -x509 -nodes \
    -out /usr/local/pubcookie/keys/pubcookie_granting.cert \
    -newkey rsa:1024 -keyout /usr/local/pubcookie/keys/pubcookie_granting.key

If you want to place these files in a different location (than {PUBCOOKIE_DIR}/keys/pubcookie_granting.{key,cert}), you'll need to set the granting_cert_file and granting_key_file variables in your config file.

Keyserver Setup

The keyserver binary you build earlier is a program that generates and maintains DES keys for participating servers to use to encrypt cookie contents. Unfortunately, due to subtleties in the key usage constraints, keyserver is unable to run as a cgi script underneath a login server. Instead, we recommend that keyserver be run from inetd.

Add a line like the following to the login server's /etc/inetd.conf:

2222    stream  tcp     nowait  root    /usr/local/pubcookie/keyserver keyserver

where /usr/local/pubcookie/keyserver is where the keyserver binary is installed. Make sure that your pubcookie/config file is correctly configured.

If you are using xinetd, you should create a file named keyserver in /etc/xinetd.d with the following contents:

# description: pubcookie keyserver
service keyserver
{
	type			= UNLISTED
	protocol		= tcp
	port			= 2222
	disable			= no
	socket_type		= stream
	wait			= no
	user			= root
	group			= tty
	server			= /usr/local/pubcookie/keyserver
}

After adding this line to inetd.conf (or file to xinetd), restart inetd (or xinetd).

Run Keyclient for the Login Server

Generate a DES key for the login server with keyclient

Now run keyclient to generate a DES key for the login server:

% /usr/local/pubcookie/keyclient

This will cause the keyserver program to generate a new DES key for the login server to use to provide confidentiality for the login cookies.

Generating DES keys for the application servers with keyclient

When the time comes, generating DES keys for application servers is very similar. You configure the keyclient on the application server ahead of time, making sure the keyclient's certicate (probably the server's SSL certificate) is signed by the same CA trusted by your keyserer's CA configuration. Refer to the application server documentation for specifics.

Install & Test Login CGI (index.cgi)

Once your run-time config file is set up and you've succeeded in using keyclient to generate a DES key for your login server, you can deploy the login cgi by copying it into your production directory from which Apache will serve requests. (See Apache Configuration above for some discussion of this topic.) For example:

% cp index.cgi /var/www/html

You don't need to set up an application server to test the login cgi; simply open your login URL in a browser and it should ask you to log in using whichever verifier you've configured. This direct approach to your login cgi is known as a "pinit" or "Pubcookie init" since it establishes a single sign-on session without authenticating you to any applications.

Login Page Templates

The login cgi serves up pages based on a set of HTML templates. By default, these templates reside in {PUBCOOKIE_DIR}/login_templates, but the location can be set by changing template_root in your config file. Generic templates are installed by default in {PUBCOOKIE_DIR}/login_templates.default. They should be copied to {PUBCOOKIE_DIR}/login_templates and they will serve as a starting point for further localization.

Note: For reference and comparison purposes, copies of CMU and Washington's login templates (of some vintage) are provided in this source distribution. See src/login_templates.cmu and src/login_templates.uw, respectively. Note: the syntax for variable substitution within the templates changed during the development of version 3.0.0. The UWash and CMU templates may be in the older format.

The name of each template file can be set via the {PUBCOOKIE_DIR}/config file. The name for each config variable is tmpl_{default_file_name}, and they are located relative to the template_root. (For example, the attribute that controls the name of the login page is tmpl_login.)

Template Files (incomplete)

We are in the process of reworking the template files to make them more user-friendly. The list below will be updated as work progresses.

login
The Login HTML page.
    Paramters
  1. Login Server URL
  2. The reason for the redirect (pulled from the login_* snippets)
  3. Hidden fields maintaining state
  4. GetCred Hidden fields
login_bad_auth
The error displayed when the authentication failed.
login_cache_creds_wrong
The error displayed when the single-signon credential is not the type that the application is requesting. (Rarely seen.)
login_nolcookie
The error displayed when the user doesn't have or has an invalid login cookie
login_reauth
The error displayed when the application has requested that the user reauthenticate.
status
The status page displaying the time remaining on the login.
    Parameters
  1. Refresh header
  2. User name
  3. Time remaining.

The "ok_browsers" File

The {PUBCOOKIE_DIR}/ok_browsers file contains a list of acceptable browsers. The idea behind ok_browsers is to block browsers that either have a known security flaw (i.e. don't forget cookies when they should) or don't work with Pubcookie. The ok_browsers file is optional.

Note: At the University of Washington, we've so far been too chicken to really use the 'ok_browsers' functionality to block browsers that we know don't work. Our ok_browsers file has a single line: "Mozilla". This pattern matches most of the browsers we support and/or encounter; mainly MS Internet Explorer, Netscape, and Mozilla. Proceed according to your own policy.

Logout Configuration

The login cgi automatically handles logout requests from applications. This functionality is built in; no configuration is necessary on the login server. Through additional configuration you can create a separate logout URL on your login server and also tailor some of the logout text for your favoriate applications.

Note: Pubcookie 3.0 does not support "global" logout: logout of all applications, all cookies, all at once. Rather, it supports per-application logout, plus the ability to logout of the login server, all separately. Therefore, users must still be educated and warned to exit their browser in order to get logged out of everything at once.

Configuring a Logout URI

If you want to provide a URL where users can go directly to clear their single sign-on session (pubcookie login cookie), it can be created with the logout_prog config variable and a Unix symbolic link. Here's an example.

Suppose the login cgi has been installed in the web server's root directory (e.g. https://weblogin.example.edu) and you want to create a logout URI of "/logout/" just below that (e.g. https://weblogin.example.edu/logout/). First, you would want to create the subdirectory and symbolic link to your login cgi:

$ cd /var/www/html
$ ls
index.cgi     images/
$ mkdir logout
$ cd logout
$ ln -s ../index.cgi index.cgi

Now any request to /logout/ on the server will map to your login cgi. (editor: Is there a better way to do this in httpd.conf instead?) All that's left is adding the appropriate logout_prog variable to your Pubcookie config file:

logout_prog: /logout/index.cgi
Customizing Logout Responses For Special Apps

The login cgi builds logout response pages from several templates. One template, logout_app, which is the most specific to each application, can be overridden on a per-application basis, as configured and identified by the originating server name and application id. It requires one app_logout_string config file variable for each application, where the server name and id are tacked on using dashes. For example:

# custom logout msgs
app_logout_string-appserver.example.edu-testapp: <font size="+1">Testapp logout worked just fine.</font>
app_logout_string-webmail.example.edu-webmail: <font size="+1">Webmail Logout Successful!</font>

Note: Since the login cgi reads the config file and its HTML templates on each request, there's no need to recompile the login cgi in order to modify response text.

Upgrading

Upgrading from pre-3.0 pubcookie
  • Maintaining DES key compatibility from hashed IP addresses

    If you have an exisiting pubcookie installation using a shared DES key with hashed IP addresses, you can upgrade your login server without generating new keys on every application server.

    On the login server, in the .../pubcookie/keys/ directory, make a copy of the master DES key (before hashing it to any IP address) for each application server, named with the full hostname of the server.

    For example, create .../pubcookie/keys/oldappserver.example.edu containing the original DES keyfile.

    The login server will use this key to encrypt data going to that application server, and the application server can continue to use it's key (XOR'd with it's IP address) to decrypt the data.

    During the application server's next scheduled downtime, you can create a new unique DES key for that application, as in the Key Management & Setup section above.

Advanced Configuration

Redundant login servers
Redundant application hosts

Sites frequently want several hosts configured identically to provide redundancy (either for performance or stability). In this section, we're assuming that you have a set of machines with an identical SSL certificate and key on them.

For instance, an institution might have 15 webmail servers named webmail1.example.edu through webmail15.example.edu with 15 unique IP addresses. All of them are equipped with a webmail.example.edu certificate and are behind a Cisco Load Director which controls the IP address for webmail.example.edu.

Use keyclient on webmail1.example.edu to generate a webmail.example.edu DES key. Use keyclient -d on all other webmail machines (webmail2.example.edu, etc.) to download an identical application key to the remaining servers.

Security Considerations

Login server security

Don't run anything else on it: anyone who can add content to the login server can steal all cookies.

Application server security
Handling secrets
Other stuff

Old Tools That Might Be Handy for Debugging

pbc_create creates a pubcookie cookie, convenient for creating cookies ad hoc. Arguments come in via stdin and the cookie is put out on stdout. Args are space delimited, and in order: user appsrvid appid type creds serial crypt_file cert_key_file. Anything too big is just truncated, no support for defaults or anything like that. See src for details.

pbc_verify decrypts/verifies/displays pubcookie cookies, convenient for 'unbundling' a cookie and seeing what's inside. The arguments come in on the command line, the cookie comes in on stdid, and the contents are dumped to stdout. The required argument is cookie_type and the optional arguments are encryption_key and cert_file.

As an example you can use these two programs to do things like:

# echo "willey appsrvid appid 1 2 23 \
    /usr/local/pubcookie/c_key /usr/local/pubcookie/test.key" | \
    ./pbc_create | \
    ./pbc_verify 1 /usr/local/pubcookie/c_key /usr/local/pubcookie/test.cert

and get something like

user: willey
version: a5
type: 1
creds: 2
serial: 23
appsrvid: appsrvid
appid: appid
create_ts: 1006986719
last_ts: 1006986719


[Pubcookie Home Page]
Copyright © 2002-2008 University of Washington
UW Technology Services
Pubcookie Contact Info
Modified: May 15, 2004