National Center for Supercomputing Applications MyProxy Credential Management Service University of Illinois at Urbana-Champaign

[Valid HTML 4.01]
[Valid CSS]
[Valid Atom 1.0]

(OSI Certified)

Integrating Apache and MyProxy: mod_authn_myproxy

Download the module for Apache 2.2: mod_authn_myproxy.c

mod_authn_myproxy is an Apache 2.2 module that allows clients to authenticate against a MyProxy server. After a successful authentication, a delegation is retrieved and stored on the web server. CGI scripts and other web applications can make use of this delegation to perform operations on the client's behalf.

The client's MyProxy username and passphrase are passed in using HTTP basic authentication, which is supported in all browsers. Basic authentication sends the username and passphrase to the server for verification — so it is essential that connections to the web server be secured (e.g. with SSL/TLS or IPsec).

Usage scenario

In this scenario, a user would like to see the processes currently running on a a particular Grid machine. The process information can be obtained by logging into the machine and running ps, but the user would like to view the information from his web browser. A developer has used mod_authn_myproxy to write a CGI script, get-processes, that will obtain the process list and format it for the user.

  1. The user visits a web page and chooses the target machine.
  2. The form is submitted to the get-processes CGI script.
  3. The user is prompted for authentication information; he enters his MyProxy username and password.
  4. The web server contacts the MyProxy server; the MyProxy server verifies the username and passphrase.
  5. The web server receives a delegation for the user from the MyProxy server; it caches the delegation locally.
  6. The web server sets the appropriate environment variables (most sigificantly, X509_USER_PROXY) and starts the get-processes CGI script.
  7. The get-processes CGI script spawns gsissh -n -l user target ps.
  8. gsissh examines the X509_USER_PROXY environment variable and then uses the delegation to authenticate to the target machine.
  9. The get-processes CGI script parses and formats the ps output.
  10. The script finishes, the connection is closed, and the output is returned to the user.

Module installation

The Globus binary distribution includes shared libraries with unusable libtool configuration files. The path names in the configuration files point to the original build environment — not to the installed location. Globus bug 709 documents the issue (see also bugs 174 and 94).

A workaround is to omit the -l myproxy_... argument to apxs. Then, add the line LoadFile /path/to/myproxy.so in httpd.conf.

If you try this alternate method, please report your results on the myproxy-user mailing list so others can benefit from your experience.

Currently, only Apache 2.2 is supported. The Apache 2.0 API is significantly different than the 1.3 API, and the AAA framework was revised between version 2.0 and 2.2.

The Apache server must have been compiled with DSO support.

Additionally, the Globus Toolkit MyProxy packages must be installed on the server. See the MyProxy install documentation for instructions. We strongly recommend installing a Globus Toolkit source distribution.

Once you have a functional Globus environment and a working Apache server, download the module.

mod_authn_myproxy is compiled and installed with apxs, the Apache extension tool. apxs handles the Apache-specific part of the build and installation process.

To compile and install for the flavor gcc32dbg:

GLOBUS_FLAVOR=gcc32dbg
apxs -c -i -I ${GLOBUS_LOCATION}/include/${GLOBUS_FLAVOR} \
      -L ${GLOBUS_LOCATION}/lib -l myproxy_${GLOBUS_FLAVOR} \
      mod_authn_myproxy.c

To enable debugging, specify the -Wc,-g and -Wc,-O0 flags.

Configuration

You must have a Globus environment before starting Apache. See the documentation on the PassEnv directive.

mod_authn_myproxy uses the Apache 2.2 AAA system. Before continuing, read the Apache 2.2 authentication overview. mod_authn_myproxy acts as a provider for the Basic authentication system. (Digest authentication is not and will not be supported; the module must know the user's plaintext passphrase in order to authenticate to MyProxy.)

Server-wide configuration

LoadModule

To request that Apache load mod_authn_myproxy, add a LoadModule directive to the server configuration:

LoadModule authn_myproxy_module modules/mod_authn_myproxy.so

MyProxyCacheDir

Next, choose a cache directory. This directory will hold delegated credentials and the database mapping usernames to credential files. This directory must:

  • be owned by the web server user
  • have permissions set to 0700 (user read/write/execute only)
  • be located on a filesystem that supports atomic rename()
  • be dedicated to storing mod_authn_myproxy state (i.e. contain no other files or directories)

Set the directory using the MyProxyCacheDir directive:

MyProxyCacheDir /home/www-dev/myproxy-tmp

PassEnv

Apache should be started within a Globus environment. mod_authn_myproxy depends on several Globus modules for certificate parsing and gridmap support. The apachectl script is often used to start and stop the web server. The script will source a file called envvars. One approach is to modify the envvars script to export GLOBUS_LOCATION and then source $GLOBUS_LOCATION/etc/globus-user-env.sh. The globus-user-env.sh script, when sourced, sets up an appropriate environment.

Some repackaged versions of Apache do not use apachectl to start up the web server. You may have to modify other scripts to customize the environment. For example, in Fedora Core 5, modify /etc/init.d/httpd.

You should also instruct Apache to pass a subset of your Globus environment to CGI scripts. At the bare minimum, you should pass the GLOBUS_LOCATION variable. You may also need to pass other variables.

As of version 4.0.2, the following environment variables may be modified by the Globus scripts:

  • globus-user-env.sh may modify:
    • GLOBUS_PATH
    • PATH
    • MANPATH
    • LD_LIBRARY_PATH
    • DYLD_LIBRARY_PATH
    • LIBPATH
    • SHLIB_PATH
    • SASL_PATH
    • LD_LIBRARYN32_PATH
    • LD_LIBRARY64_PATH
  • globus-devel-env.sh may modify:
    • CP
    • CLASSPATH

To pass one more environment variables, use the PassEnv directive:

PassEnv GLOBUS_LOCATION
PassEnv LD_LIBRARY_PATH SASL_PATH

Several other similar directives are available, and these directives can be used in other contexts. See the mod_env documentation for additional information.

Local configuration

These directives can be set on a per-directory, per-location, and per-file basis. If the AllowOverride directive allows overriding AuthConfig directives, they can be set in a .htaccess file.

To enable MyProxy authentication, first configure mod_authn_myproxy.

MyProxyServer

Sets the MyProxy server.

This directive is required.

MyProxyServer cedar.ncsa.uiuc.edu

See also MyProxyPort.

MyProxyPort

Sets the MyProxy port.

This directive is optional. It defaults to 7512.

MyProxyPort 5621

MyProxySetLogname

Sets the environment variable LOGNAME to the MyProxy username.

This directive is optional. It defaults to Off.

MyProxySetLogname On

MyProxyCheckGridmap

Checks the gridmap file to ensure that the DN of the delegation maps to the MyProxy username. If it does not, the authentication attempt fails.

This directive is optional. It defaults to Off.

MyProxyCheckGridmap On

The location of the gridmap file is determined by checking the GRIDMAP, GLOBUSMAP, globusmap, and GlobusMap environment variables. If none are set and the program is running as root, then the location is set to /etc/grid-security/grid-mapfile. Otherwise, the location is set to ~/.gridmap.

Thus, to check /etc/grid-security/grid-mapfile, either set the GRIDMAP environment variable or link the web user's ~/.gridmap to /etc/grid-security/grid-mapfile. (The latter suggestion can have serious security implications if the web user's home directory is under the web root or if a user can modify ~/.gridmap.)

MyProxyRequestedLifetime

Sets the requested delegation lifetime (in minutes).

This directive is optional. It defaults to 120. The minimum value is 5. (This is enforced by MyProxy 3.5 to avoid clock skew issues.)

MyProxyRequestedLifetime 60

The lifetime of the received delegation may be less than the requested lifetime. The maximum delegation lifetime may be restricted by the policy of the MyProxy server, or the credentials stored on the MyProxy server not be valid long enough to satisfy the requested lifetime. See the MyProxyMinLifetime directive.

MyProxyMinLifetime

Sets the minimum acceptable delegation lifetime (in minutes). If the lifetime of the received delegation is less than this value, the authentication attempt fails.

This directive is optional. It defaults to 10. The minimum value is 1. It must be less than the value set by MyProxyRequestedLifetime.

MyProxyMinLifetime 10

Using this directive, you can enforce a minimum delegation lifetime. For example, if a script requires about ten minutes to run, you can mandate that the delegation passed to the script must be good for at least fifteen minutes. If the stored delegation will not be good for at least fifteen minutes, mod_authn_myproxy will attempt to obtain a new one. If the new delegation cannot be obtained or if the lifetime of the new delegation is less than the minimum lifetime, the authentication attempt fails.

Apache authentication configuration

Then, enable authentication and specify mod_authn_myproxy as the provider:

AuthName "realm name"
AuthType Basic
AuthBasicProvider myproxy
Require valid-user

See the Apache 2.2 authentication overview for details.

Technical details

The module caches information about successful authentication attempts. It is not possible to disable the cache. MyProxy offers an option to authenticate without receiving a delegation. However, without a delegation it is not possible to know the validity period of the positive response. Therefore, the response could not be cached. The web server would have to contact the MyProxy server at each request, which would be extremely expensive.

The cache lifetime is equal to the lifetime of the received certificate.

When Apache is not running, the entire contents of the cache directory may be safely removed.

To clean the cache while Apache is running, use the cache cleaner script. If a user's delegation has expired, the script will remove both the user's record and the expired delegation. One or more cache directories can be specified with the --dir option. For verbose output, use the --verbose option.

Developing with mod_authn_myproxy

Environment variables

After a successful authentication, the following environment variables are set:

  • X509_USER_PROXY holds the absolute path to a file containing user's delegation. Clients must treat this file as read-only. This file may be atomically updated at any time.
  • X509_USER_DN holds the distinguished name of the identity that the delegation represents.

    X509_USER_DN is intended as a convenience to allow applications to determine the DN without parsing the certificate. In rare cases, the value of X509_USER_DN may not reflect the stored delegation. This can happen in the following scenario:

    1. The user visits a secured page, and the web server obtains a delegation on her behalf. A long-running application is started with X509_USER_DN set to /O=NCSA/CN=Alice1.
    2. The user obtains a new certificate with DN /O=NCSA/CN=Alice2. The user uploads it (or a proxy for it) to the MyProxy server.
    3. The delegation to the web server expires. The user loads another page, and the web server obtains a fresh delegation. The cached delegation with DN /O=NCSA/CN=Alice1 is (atomically) replaced with a delegation having DN /O=NCSA/CN=Alice2.
    4. Now, the value of X509_USER_DN in the long-running application does not reflect the DN of the delegation.
  • LOGNAME holds the user's MyProxy username. It is set if and only if the optional MyProxySetLogname directive is set to On.
  • MYPROXY_SERVER holds the name of the MyProxy server.
  • MYPROXY_SERVER_PORT holds the port for the MyProxy server.

Writing CGI scripts

This section applies only to programs running as CGI scripts. Special considerations apply for scripts that are interpreted by another Apache module; see the next section.

According to the CGI specification, a script receives request metadata through environment variables.

Apache passes the mod_authn_myproxy variables to subprocesses via environment variables. See your language documentation the particulars of accessing the environment:

Environment variables are inherited by children, so if you spawn another processs (e.g. gsissh) it will receive the mod_authn_myproxy variables.

An example script

This Perl script uses grid-proxy-info to print information about the proxy certificate.

#!/usr/bin/perl

use HTML::Entities;

print "Content-type: text/html\r\n\r\n";
print "<h1>grid-proxy-info</h1>";
print "<pre>";
$output = `grid-proxy-info`;
print encode_entities($output);
print "</pre>";

Interacting with other Apache modules

In general, if you are running client applications via the CGI interface, no special considerations apply; you can simply use your language's facility for reading the environment. However, if you are using an interpreter embedded in Apache, you may have to access Apache's subprocess environment table.

Each time a subprocess is spawned in response to a request, it receives a copy of the subprocess environment table as its environment. This happens, for instance, when a CGI script is executed. mod_authn_myproxy places its environment variables in this table so that they will be available to subprocesses.

However, if you are using an interpreter that is integrated with Apache, your scripts will not spawn a new process. Therefore, they may not receive an environment containing the mod_authn_myproxy variables. If this happens, your script may have to explicitly query the subprocess environment table.

mod_include in Apache 2.2 (server-side includes)

mod_include scripts need no special modifications to work with mod_authn_myproxy. The mod_authn_myproxy variables are treated just like any other environment variable, and they are properly passed to child processes.

mod_php 4.4.2, 5.1.4 (PHP as a module)

mod_authn_myproxy variables are not available via $_ENV. Use getenv() or apache_getenv().

Additionally, new processes don't seem to inherit the mod_authn_myproxy variables. You must explicitly call putenv() for the variables to be passed to children. For example:

putenv('X509_USER_PROXY=' . apache_getenv('X509_USER_PROXY'));
system('grid-proxy-info');

According to the PHP manual, environment variables set with putenv() are cleared at the end of the request. putenv() does not update $_ENV.

mod_perl 2.0.2

mod_authn_myproxy variables are available from the %ENV hash. Use $r->spawn_proc_prog() to spawn another process. (See modperl_env_magic_set_all in modperl_env.c and the mod_perl troubleshooting guide.)

Example scripts

Example scripts are available.

Miscellaneous notes

  • ssh/gsissh
    • When starting gsissh from a script, use the -n option to prevent the client from reading from standard input.
    • If the DISPLAY environment variable is set, ssh may try to enable X11 forwarding. The -x option will explicitly disable X11 forwarding.
    • Sometimes, when running gsissh under mod_php, the HTTP connection does not close. The reason is currently unknown.

Future improvements

Last modified 05/30/08.
©2000-2019 Board of Trustees of the University of Illinois.