Cosign Setup for Apache Web Server

This document details how to set up Cosign authentication for an Apache web server. It uses https://newsite.it.umich.edu/ as an example site that follows certain assumptions that make the setup much easier.

The install process automatically adds a LoadModule directive to /etc/httpd/conf/httpd.conf.

Diagnostic Check

Use Apache's test mode to make sure cosign_module loads.

sudo httpd -t -D DUMP_MODULES | grep cosign

Debian/Ubuntu

# Debian does not have sudo by default, so these must be run as root.
# Your install may already have these
apt-get install autoconf apache2-dev libssl-dev
# The Umich IAM copy of Cosign includes Apache 2.4 support
wget https://github.com/umich-iam/cosign/archive/master.tar.gz
tar xfz master.tar.gz
cd cosign-master
autoconf
./configure --enable-apache2=`which apxs`
make
make install
mkdir -p /var/cosign/filter
chown www-data:www-data /var/cosign/filter

You can, and usually should, reuse the SSL key and signed certificate used for the public-facing site. The key file will need to be readable by the web server's non-root user.

The CA certificate file is a text file of PEM-encoded certificates Apache can use to build a chain. If you are using an InCommon certificate, we strongly recommend using the PEM roll-up bundle, which includes InCommon and campus-specific certificates.

Configure Your Site To Use Cosign

The following directives all go in the <VirtualHost> block for your site. They do not enforce Cosign on their own, but only configure it.

# We recommend using weblogin-test for testing, then replace
# with weblogin.umich.edu when ready for production
CosignHostname weblogin-test.itcs.umich.edu
CosignRedirect https://weblogin-test.itcs.umich.edu
CosignPostErrorRedirect https://weblogin-test.itcs.umich.edu/post_error.html
# You will want a cron task to remove files more than a day old
# find /var/cosign/filter -type f -mtime +0 -exec rm {} \;
CosignFilterDB /var/cosign/filter
# This is your site name without umich.edu suffix.
# Non-umich.edu domains will need an exception.
CosignService newsite.it
# This regular expression (regex) works for umich.edu sites.
# It, too, will need to change for other domains.
CosignValidReference ^https?:\/\/.*\.umich\.edu(\/.*)?
CosignValidationErrorRedirect http://weblogin-test.itcs.umich.edu/cosign/validation_error.html
# You should reuse your public-facing certificate for this back-channel
# CosignCrypto <SSLCertificateKeyFile> <SSLCertificateFile> <CA bundle>
CosignCrypto /etc/pki/tls/private/newsite.it.key /etc/pki/tls/certs/newsite.it.crt /etc/pki/tls/certs/um-certs2016.pem
<Location /cosign/valid>
SetHandler cosign
CosignProtected Off
Require all granted
Satisfy any
</Location>

Diagnostic Check

Restart Apache and visit https://newsite.it.umich.edu/cosign/valid directly. It should return a 403 (Forbidden) error. If it does not, either these settings did not load, or another Location or other redirect is overriding these settings. This is a common issue with Drupal and other PHP frameworks.

Enable Cosign On Your Site

Now, you can add Cosign authentication to the VirtualHost itself, or Location, Directory, and Files resources within it. You may protect multiple resources, and you may require two-factor authentication for some resources.

Diagnostic Check

Restart Apache and browse to a protected area of your site. Apache should redirect you to Weblogin for authentication.

Common Issues

Certificate Handling

Certificate errors show up as redirect loops on the user side, along with snet_starttls errors in Apache's error log.

The Apache non-root user (apache, www-data, or daemon, depending on your setup) must be able to read the SSL key configured in CosignCrypto.

The CA bundle in CosignCrypto must contain the UM Web CA and AddTrust External CA Root certificates, and the full chain for your own SSL certificate. If your site uses an InCommon certificate, we strongly recommend using the PEM roll-up bundle.

URL Rewriting

Making a request directly to /cosign/valid should return a 403 (Forbidden) error.

If it does not:

PHP frameworks often include .htaccess files that contain RewriteRule configurations. You will need to add a RewriteCond to exclude /cosign.

If you are protecting a Tomcat application, setup your ProxyPass rules to exclude /cosign.

Make sure the /cosign/valid resource has "CosignProtected Off."

Client-Side Caching

A few PHP frameworks use ExpiresDefault or Header configurations so visitors can cache script-generated pages. Cosign uses a redirect to send users to Weblogin, but these headers will result in visitors caching the redirect.

Do not use caching headers, unless you can exclude 302 (Temporary Redirect) responses. Cache headers should be limited either by response code or MIME type: