NVO SSO Installation

From MyWiki

Revision as of 17:57, 3 February 2009 by Bbaker (Talk | contribs)
Jump to: navigation, search
NVO Single Signon

Overview
   - Architecture
   - Login Server Federation
Installation
   - From scratch
   - From VM Images
Replication
   - Current Configuration

Software Versions

Apache HTTPD
2.0+
Pubcookie
3.3+
mod_perl
2.0+
MySQL
4.0+
Java
1.4.2+
Ant
1.6.5+
Tomcat
5.0+
Globus Toolkit
4.0+
MyProxy
3.5+ (included
in Globus 4.0.2+)

Installing NVO Single Signon, both application server, or web portals, and login servers. Feel free to contact Bill Baker or Mike Freemon with any questions.

Contents

Application Server

If you have a web server running already, it should be straightforward to connect to an NVO login server. NCSA currently operates a login server at [1], which we encourage you to connect to for development.

Participation in NVO SSO requires the following software:

In addition, if you are running Tomcat, you will need to install:

  • mod_jk, a connector between the Apache web server and Tomcat

Further, if you require grid security credentials (X.509 proxy certificates), you will need:

  • mod_perl, a framework for running Perl scripts inside the Apache web server
  • Globus Toolkit, for its command line MyProxy client; you may use an alternate command line MyProxy client instead, such as one implemented in Java or Python.

Pubcookie Client

An application server will delegate authentication to a login server with mod_pubcookie, an Apache module written in C.

Refer to mod_pubcookie's installation documentation for full documentation; for our setup we make a few changes—notably our handling of symmetric keys—described below.

Build Pubcookie Apache Module

Download and unpack the code, and:

$ ./configure
$ make
# make install

In Pubcookie 3.3.x, you may encounter a make error involving the file rules.mk when you build on a Red Hat based system. To work around it, modify module/Makefile, changing the property top_builddir from /etc/httpd to /usr/lib/httpd (or wherever the httpd-devel package keeps rules.mk and its other makefiles).

Configure Pubcookie

Create Pubcookie's config file, by default at /usr/local/pubcookie/config, to point to the login server. Here is a sample:

# 1 is a good starting point
logging_level: 1

# ssl config
ssl_key_file: /etc/grid-security/hostkey.pem
ssl_cert_file: /etc/grid-security/hostcert.pem

# keyclient-specific config
keymgt_uri: https://sso.us-vo.org:2222
ssl_ca_path: /etc/grid-security/certificates

Symmetric Key

Each pubcookie client requires a symmetric key that is shared with the Pubcookie login server. For now, we need to make all of those keys the same, due to limitations in our integration between MyProxy and Pubcookie.

For this step, you will need to obtain a copy of the shared symmetric key from the administrator of your login server.

The first application server

Create a new key with Pubcookie's keyclient command.

Subsequent application servers

This is a hack: we make all of the application servers' symmetric keys identical. In the future, once decryption is moved from the MyProxy server to the application servers themselves, it will not be necessary.

  1. Create a new key with Pubcookie's keyclient command.
  2. Overwrite the new key, by default /usr/local/pubcookie/keys/<hostname>, with the key obtained from the login server administrator.
  3. Ensure that the login server has done the same, so that its key identifying the application server matches the one on the application server.

Granting Cert

Now, you can get a copy of the login server's granting certificate

$ cd /usr/local/pubcookie
$ ./keyclient -G keys/pubcookie_granting.cert
Granting cert saved to keys/pubcookie_granting.cert

Return on Logout

On logout, Pubcookie redirects the user's web browser to the login server. We provide a mechanism to return the user, instead, to the application server. The mechanism uses Pubcookie's PubcookieAppID as a channel to send a return address to the login server, since Pubcookie doesn't provide a built-in mechanism. Then JavaScript in the response page on the login server parses the PubcookieAppID to determine whether and where to send the user after logout.

  • Configure Pubcookie on the app server for logout, using the PubcookieEndSession directive in your Apache config. For example:
<LocationMatch .*/pc_logout_clearlogin>
   AuthType Basic
   PerlInitHandler Myproxy::Mod_Myproxy2
   require valid-user
   PubcookieEndSession clearlogin
</LocationMatch>
  • Use your PubcookieAppID to tell the login server your post-logout plan.
<Location /[app-location]>
   PubcookieAppID Portal-logoutGoto_public/welcome_back.html
</Location>
  • Explanation:
    • Include logoutgoto_ (case-insensitive) in your PubcookieAppID to request a return to your application server.
    • The rest of the PubcookieAppID will be used to generate a return URL, by appending it to the hostname of your application server. In the example above, running on nvoapp1.ncsa.uiuc.edu, the return URL would be http://nvoapp1.ncsa.uiuc.edu/public/welcome_back.html.
    • Include debug in PubcookieAppID for some help from the JavaScript script with debugging. For example, Portal-debug-logout_public/welcome_back.html.

Apache Configuration

Most of mod_pubcookie's configuration actually comes from Apache's config files. If your Apache httpd installation includes a conf.d directory, we recommend you create a pubcookie.conf file; but you can also place all of the configuration in httpd.conf.

mod_pubcookie Configuration in Apache

For details on Pubcookie directives in Apache config files, see Pubcookie directives.

The directions below are a supplement to MyProxy's mod_pubcookie docs, which explain things more completely.

conf/httpd.conf

Change (or add, if not already there) Apache's AllowOverride directive to include AuthConfig:

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
#
    AllowOverride AuthConfig
conf.d/pubcookie.conf

(Or include in httpd.conf.)

This is our demo setup; it includes a public area that users are directed to by default that does not require authentication to enter (and which does not invoke Pubcookie at all), plus a protected area that requires Pubcookie authentication. It also includes debugging output for both the public and protected areas.

We use a simple mod_perl script, mod_perl/perl/nsa/Welcome.pm, for our content, whose source is available from our demo server. It uses grid-proxy-info to read out information from security credentials (expiration time and DN).

# use /public/welcome as a default entry page
<LocationMatch "^/$">
    Redirect / http://nvoapp1.ncsa.uiuc.edu/public/welcome
</LocationMatch>

LoadModule pubcookie_module   modules/mod_pubcookie.so

<IfModule mod_pubcookie.c>

  PubcookieGrantingCertFile /usr/local/pubcookie/keys/pubcookie_granting.cert
  PubcookieSessionKeyFile /etc/grid-security/hostkey.pem
  PubcookieSessionCertFile /etc/grid-security/hostcert.pem
  PubcookieKeyDir /usr/local/pubcookie/keys/

  PubcookieLogin https://sso.us-vo.org/
  PubcookieLoginMethod POST
  PubcookieDomain .ncsa.uiuc.edu
  PubcookieEncryption DES
  PubcookieAuthTypeNames Basic

  PubcookieNoObscureCookies on

  <IfModule mod_perl.c>
    PerlRequire /etc/httpd/conf/perl_startup.pl
    PerlWarn On

    <Location dump>
      SetHandler perl-script
#      PerlFixupHandler Myproxy::Mod_Myproxy
      PerlResponseHandler Myproxy::Dump
    </Location>

    <Location /protected/dump>
      SetHandler perl-script
#      PerlFixupHandler Myproxy::Mod_Myproxy
      PerlResponseHandler Myproxy::Dump
    </Location>

    <Location /protected/welcome>
      SetHandler perl-script
#      PerlFixupHandler Myproxy::Mod_Myproxy
      PerlResponseHandler Nsa::Welcome
    </Location>

    <Location /public/welcome>
      SetHandler perl-script
#      PerlFixupHandler Myproxy::Mod_Myproxy
      PerlResponseHandler Nsa::Welcome
    </Location>

    <LocationMatch .*/pc_logout_clearlogin>
      AuthType Basic
#      PerlInitHandler Myproxy::Mod_Myproxy
      require valid-user
      PubcookieEndSession clearlogin
    </LocationMatch>
  </IfModule>

</IfModule>

Note the reference to /etc/httpd/conf/perl_startup.pl. It's a simple file telling mod_perl where to find packages:

use lib qw(/var/www/mod_myproxy/perl);
1;

Security (.htaccess)

Now, you need to tell Apache which directories require Pubcookie authentication. In our demo server, we only require it in protected. An easy way to do that is with an .htaccess file in that directory:

AuthType Basic
require valid-user

Testing Single Signon

At this point, after restarting httpd, you should have a working Pubcookie authentication system between your application server and a login server. If you are using an existing login server, such as the NCSA server, you will need to register with an email address to get a user account. If authentication is not working, now is a good time to sort everything out, since the following steps depend on this one.

If your application is running in Tomcat, you will also need to install mod_jk (see below), but otherwise, if you don't need grid security credentials -- in the form of X.509 proxy certificates from MyProxy -- your configuration is complete.

If you are using your own login server, you may try setting Pubcookie's verifier to alwaystrue to test the connection between your application and login servers.

Grid Security Credentials

You may need grid security credentials, either for

  • access to third-party services, or
  • to access Registration Authority (RA) details about users

To retrieve security credentials as part of your signon process, proceed to install mod_myproxy:

mod_perl Packages

  1. Create a mod_myproxy directory (in the example above, /var/www/mod_myproxy) and place Mod_Myproxy.pm in a subdirectory perl/Myproxy (note the directory capitalization, which must match the Perl packaging in Mod_Myproxy.pm).
  2. Update the constants near the beginning of Mod_Myproxy.pm, to reflect your site:
    • GLOBUS_LOCATION: your globus installation directory
    • MYPROXY_SERVER: the hostname of your login server
    • CRED_STORE_DIR: be sure that this directory is either creatable or already existing and readable exclusively by apache (or whatever account httpd is running under).

mod_myproxy

Finally, for access to grid security credentials, mod_myproxy will send a secure Pubcookie token to MyProxy and receive a credential in return, which it will store on the application server's local file system and make available to web applications.

mod_myproxy depends on Need links MyProxy, which is installed as part of the Globus Toolkit, as described in #Common Base, below.

If you followed the steps above, it will be ready to activate by uncommenting the Mod_Myproxy lines in your HTTPD configuration file. They look like this:

#      PerlFixupHandler Myproxy::Mod_Myproxy

If all goes well, once you restart your webserver, mod_myproxy will create grid security credentials on your application server when you log in. If it isn't working, enable debugging in Mod_Myproxy.pm, as described in the comments near the beginning of the script.

Common Base

Login servers and application servers have a few common requirements. If you are using virtual machines (VMWare, Xen, etc.) you can save time by building a base system with common software and then cloning it for further customization as either a login server or application server.

Pre-packaged and commonly available software

These are available from Linux distributions' package management systems such as apt, yum, and yast:

  1. Apache HTTPD web server
  2. mod_perl Apache module
  3. mod_ssl Apache module
  4. Apache headers and development utilities such as apxs, often packaged as httpd-devel
  5. In addition, if your application server will require Java, you will probably want to install Java, Tomcat, and mod_jk as part of your base as well (see Login Server, below, for details).

Globus Toolkit

  1. Install Globus Toolkit. The current version as of this writing is 4.0.2.
    • If you are building from source, you will not need to do a full install—make gsi-myproxy postinstall will be sufficient in place of make (you will still need to make install afterwards).
    • The MyProxy documentation offers a step-by-step guide to installing Globus and MyProxy. Note that for a login server, following it through step 4 will be sufficient, and for an application server, only step 1, installing Globus and the MyProxy client, is required.
  2. Set up the Globus environment within your Apache HTTPD daemon. For example, your Apache startup script may refer to /etc/sysconfig/httpd, where environment variables are exported. If you are using bash, you could add these lines to it:
export GLOBUS_LOCATION=<globus location>
source $GLOBUS_LOCATION/etc/globus-user-env.sh

Host Certificates

Both MyProxy and Pubcookie require host certificates, which can either be generated with Globus Simple CA or from an existing CA.

To create a certificate with Simple CA:

  1. Either:
    • follow the instructions below by installing it on your login server, or
    • if you are only running an application server, contact the administrator of your login server.
  2. Generate a host certificate as described in the MyProxy documentation.

Login Server

Login servers should be highly secure because they contain user passwords and can issue security credentials. In the future, we intend to split login servers into two components:

  1. MyProxy CA
  2. Web (Apache/Tomcat) / Database (MySQL) / Pubcookie / PURSe

For now, however, the functions are combined, due to limitations in PURSe and for simplicity.

Pre-packaged and commonly available software

mod_jk is available from package managers, but Java and Tomcat typically are not.

  1. MySQL database server, typically packaged as mysql (client) and mysql-server.
  2. Java—we are using Sun's Java 5 (a.k.a. J2SE 1.5), although version 1.4.2 also works.
  3. Apache Tomcat Java servlet engine—both versions 5.0 and 5.5 should work.
  4. mod_jk Apache module.
    • login server: optional—allows access to PURSe on port 80.
    • application server: only required for integration with Java-based web applications
  5. Apache ant is available from most package managers, compiled to native code, even though it is written in Java. You will need the JUnit extensions as well, often packaged as ant-junit.

Globus Simple CA

PURSe requires Globus Simple CA. Install it with the script $GLOBUS_LOCATION/setup/globus/setup-simple-ca, as described in the MyProxy documentation.

MyProxy Certificate Authority

You may run MyProxy CA to eliminate long-term credentials from your system by having MyProxy authenticate directly against the PURSe user database and create short-term credentials on the fly, instead of issuing short-term proxies of long-term credentials.

  1. Install MySQL headers, often packaged as mysql-devel.
  2. Install PAM-MySQL.
  3. Update PURSe
  4. Configure PAM-MySQL
  5. Configure MyProxy PAM
  6. Configure MyProxy CA

Update PURSe

PAM-MySQL does not use MySQL's encode() function, which PURSe uses to obscure passwords. Instead, you can use SHA1 hashing, via user_table.password_sha1 in the PURSe database. If your PURSe database does not have this column, you can add it manually, and upgrade your PURSe installation to support it. This SQL will add it and populate the column based on existing values:

mysql> use purseDatabase;
mysql> alter table user_table add column password_sha1 blob;
mysql> update user_table set password_sha1=sha1(decode(password,'<passphrase>');

Configure PAM-MySQL

PAM-MySQL's PAM config file -- for example, /etc/pam.d/myproxy_mysql -- should contain something like this:

auth    required /usr/lib/security/pam_mysql.so user=<mysql user> \
                 passwd=<password> db=purseDatabase table=user_table \
                 usercolumn=user_name passwdcolumn=password_sha1 crypt=sha1

account required /usr/lib/security/pam_mysql.so user=<mysql user> \
                 passwd=<password> db=purseDatabase table=user_table \
                 usercolumn=user_name passwdcolumn=password_sha1 crypt=sha1

Configure MyProxy PAM

Configure MyProxy to use PAM for authentication, rather than credential passphrases, in myproxy-server.config. The relevant config lines will look something like this:

pam "sufficient"
pam_id "myproxy_mysql"

MyProxy Configuration

MyProxy is included in Globus distributions 3.9 and later. Integration with Pubcookie requires MyProxy version 3.5 or later, which is included with Globus 4.0.2. If you have an earlier version of Globus, download the latest MyProxy package and install it.

Useful MyProxy documentation:

In myproxy-server.config, be sure to set pubcookie_granting_cert and pubcookie_app_server_key, as documented on the MyProxy Pubcookie page.

Tomcat

Install Apache Tomcat; versions 5.0 and 5.5 will both work. Tomcat will need to run as the same user as MyProxy since PURSe needs to be able to create security credentials in MyProxy's repository directory (by default, /var/myproxy).

PURSe

Download PURSe and install it. Note: Was unable to get PURSe working based on installation instructions. Copied from myproxy-pubcookie instead, and even that was fairly painful.

Pubcookie Login Service

Build and install Pubcookie

Pubcookie is a cryptographically secure web-based single signon system. Download Pubcookie and install it from source. We use version 3.3 in this example, but these instructions will also work with version 3.2.1.

There are two options to building Pubcookie: a server version and a client version (the default). To build the server version for your login server:

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

Then follow the Pubcookie installation directions. Below are some guidelines for configuration for NVO SSO and other Globus users.

Pubcookie config file

By default, Pubcookie will be installed in /usr/local/pubcookie, with a configuration file at /usr/local/pubcookie/config. Edit that file:

  1. SSL session keypair and granting key pair
    1. Note that just changing the permissions of hostkey.pem, so that apache can read it, will break other software, such as MyProxy, which expect it to be readable only by its owner, which is root by default.
      If you want to use the same host certificate as your globus installation, you will need to make a copy of /etc/grid-security/hostkey.pem that is readable by the user that will be running Pubcookie, which will most likely be apache. For example:
      cp /etc/grid-security/hostkey.pem /etc/grid-security/pubcookie_hostkey.pem
      chown apache.apache /etc/grid-security/pubcookie_hostkey.pem
    2. In /usr/local/pubcookie/config, set ssl_key_file to point to your new key file, /etc/grid-security/pubcookie_hostkey.pem in this example.
    3. Set ssl_cert_file to /etc/grid-security/hostcert.pem.
    4. granting_key_file and granting_cert_file can be set to the same values as ssl_key_file and ssl_cert_file; they are used when generating symmetric keys for application servers.
  2. Domain-specific variables
    1. login_uri and login_host: point to your login server.
    2. enterprise_domain: the domain of your login server, which does not have to be shared by all application servers.
    3. keymgt_uri: point to your login server (and keep it at port 2222 unless you need to change it due to firewall issues—application servers will need to be able to access it one time each during setup).
  3. Miscellaneous configuration
    1. Remember to update keyserver_client_list when you add application servers in the future.
      keyserver_client_list: list your initial application servers, to grant them permission to obtain a symmetric key to participate in SSO. You may also comment out this setting to allow any application server to obtain a symmetric key.
    2. ssl_ca_file: comment out and replace with ssl_ca_path: /etc/grid-security/certificates to point to your Globus installation's list of trusted CAs.

Keyserver service

Install the keyserver service in inetd.

Apache Configuration

The simplest configuration is to place Pubcookie's index.cgi in Apache's root content directory and configure Apache to execute it, as described in the Pubcookie documentation. Using symbolic links aid maintainability:

ln -s /usr/local/pubcookie/index.cgi <docroot>/index.cgi
ln -s /usr/local/pubcookie/images <docroot>/images

MyProxy-based Authentication

Once you have Pubcookie working with the alwaystrue verifier, switch to using MyProxy for username/password authentication by using it as an external password verifier.

  1. Change basic_verifier from alwaystrue to verify_fork. To Do: use alwaystrue first, then switch later
  2. Save the Perl script myproxy_fork.pl to /usr/local/pubcookie/myproxy_fork.pl. Pubcookie will call it for password verification.
  3. Customize constants in myproxy_fork.pl for your local installation:
    1. $GLOBUS_LOCATION: your Globus installation directory
    2. $MYPROXY_SERVER: your login server's hostname (can be localhost in this case)
  4. Add this line to the Pubcookie config file: verify_exe: /usr/local/pubcookie/myproxy_fork.pl

Integrating Tomcat

In order for a Java application running in Tomcat (or other servlet engine) to use Pubcookie-based SSO, you need to proxy it behind Apache HTTPD, so that the external request is handled by Apache, but delegated internally to Tomcat. The benefits are:

Note that any application server that supports the AJP protocol, such as Jetty, can be proxied behind Apache with mod_jk.
  • Login server: allows PURSe registration and management to run on port 80 and 443, instead of secondary ports such as 8080 and 8443.
  • Application server: Integrate Java-based web applications with NVO SSO.

mod_jk integrates Pubcookie SSO with Java applications by passing, as environment variables, the name of the current user and the location that user's security credential file.

Login Server

The easiest way to use Apache HTTPD as a front-end for another web server is with mod_proxy. Older versions had difficulty with Pubcookie's cookies, but current versions seem to work smoothly.

Configuring mod_proxy

In a HTTPD config file such as httpd.conf or pubcookie.conf, add:

ProxyPass /purse http://localhost:8081/purse
ProxyPassReverse /purse http://localhost:8081/purse

Note that the first and second /purse in the lines above don't need to match. The first is the path to reach PURSe via HTTPD on port 80 and 443, and the second is the path in Tomcat. You could change the first /purse to /nvo_register, for example.

Next, make sure that you have a port open in Tomcat to receive requests:

<Connector port="8081"
    maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
    enableLookups="false" redirectPort="8443" acceptCount="100"
    debug="0" connectionTimeout="20000"
    disableUploadTimeout="true"
    proxyName="<hostname>"
    proxyPort="80" />

(Be sure to substitute the hostname of your server for <hostname>.) You could equally well connect to port 8080, which is presumably already open.

Application Servers

mod_proxy, unfortunately, does not work with Pubcookie-based SSO, because Pubcookie's granting cookies never get cleared and replaced with session cookies. Instead, Tomcat's mod_jk, although it is more complex to set up, is recommended for application servers, to connect Tomcat to SSO.

mod_jk

Initial installation and configuration

See Tomcat's mod_jk docs for initial installation and configuration.

Additional configuration

To require Pubcookie authentication, add this to your HTTP configuration:

<Location /<app_name>/>
    PerlFixupHandler Myproxy::Mod_Myproxy
    AuthType Basic
    require valid-user
</Location>

Once mod_jk is basically working, you will need to configure it to pass X509_USER_PROXY to your Java applications (where it can be retrieved it via request.getAttribute("X509_USER_PROXY")). In your Apache mod_jk configuration file, add:

JkEnvVar X509_USER_PROXY none

In Tomcat's server.xml, in the AJP connector dedicated to mod_jk, which is on port 8009 by default, add

tomcatAuthentication="false"

So that request.getRemoteUser() will return the SSO username.

mod_proxy_ajp

The Pubcookie team has reported success using mod_proxy_ajp which is an extension to mod_proxy that is included in most default installations of Apache HTTPD 2.2. Unfortunately, we haven't gotten their approach to work yet, but we compiled materials based on their emails for future reference, in case someone can get it working. Once the problems are worked out, we expect it to be an improvement over mod_jk, since it is more flexible and appears to have broader community support.

Accessing SSO Properties in Java

The username of the current user is returned as a String from:

request.getRemoteUser()

The file location of the user's GSI credential is returned as a String from:

request.getAttribute("X509_USER_PROXY")
Loading a GSI security credential

This code requires the following JARs. They are all available in Globus Toolkit version 4:

  • cog-jglobus.jar
  • cryptix-asn1.jar
  • cryptix32.jar
  • jce-jdk13-125.jar
  • puretls.jar

This code will load an org.ietf.jgss.GSSCredential object from the credential file on disk. It is derived from Terry Fleury's MyProxyDelegator class:

// 1. read raw bytes from file
File credFile = new File(filename);
byte[] credBytes = new byte[(int) credFile.length()];
FileInputStream fileIn = null;
try {
    fileIn = new FileInputStream(credFile);
    fileIn.read(credBytes);
} finally { fileIn.close(); }

// 2. parse raw bytes as GSI credential
ExtendedGSSManager mgr = (ExtendedGSSManager) ExtendedGSSManager.getInstance();
// byte[] buffer, int option, int lifetime, OID mechanism, int usage
ExtendedGSSCredential credential = mgr.createCredential
          (credBytes, ExtendedGSSCredential.IMPEXP_OPAQUE,
           GSSCredential.DEFAULT_LIFETIME, null,
           ExtendedGSSCredential.INITIATE_AND_ACCEPT);


Personal tools