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.

Contents

Example Site Assumptions

https://newsite.it.umich.edu/

  • Is a subdomain of umich.edu.
  • Is already setup for SSL on the standard port 443.
  • Uses an InCommon certificate from WASUP.
  • The Common Name on the certificate matches our site (wildcard certificates require an exception).

This configuration allows you to use the default policy for Weblogin. Other setups, such as a non-umich.edu domain, can work, but you need to contact the ITS Service Center to request an exception.

Build and Install mod_cosign

The original Cosign site is no longer maintained. ITS recommends downloading the latest version from the IAM Github.

RHEL/Centos

# Your install may already have these
sudo yum install autoconf httpd-devel openssl-devel wget

# 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
sudo make install
sudo mkdir -p /var/cosign/filter
sudo chown apache:apache /var/cosign/filter

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

Diagnostic Check

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

. /etc/apache2/envvars
/usr/sbin/apache2 -t -D DUMP_MODULES | grep cosign

Built From Source

In the following code, replace /usr/local/apache2 with the specific path of your Apache installation.

# 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=/usr/local/apache2/bin/apxs
make
sudo make install
sudo mkdir -p /var/cosign/filter
sudo chown daemon:daemon /var/cosign/filter

Diagnostic Check

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

sudo /usr/local/apache2/bin/httpd -t -D DUMP_MODULES | grep cosign

SELinux

If you have SELinux enforced, you will need to enable Apache to make network connections and write to the cookie database.

sudo setsebool httpd_can_network_connect on
sudo semanage fcontext --add --type httpd_sys_rw_content_t /var/cosign/filter
sudo restorecon -F -R /var/cosign/filter

SSL Certificate Setup

The Weblogin back channel uses mutual authentication, which means it will present a certificate chain to your server, but your server must also present a certificate chain in return.

The CosignCrypt directive has three arguments:

CosignCrypto <SSLCertificateKeyFile> <SSLCertificateFile> <SSLCACertificateFile>

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.

<Location /protected>
    CosignProtected On
    AuthType Cosign
    Require valid-user
    # Uncomment this to *require* Duo two-factor authentication
    # CosignRequireFactor two-factor
</Location>

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:

Header append Cache-Control s-maxage=600 "expr=%{REQUEST_STATUS} == 200" 

ExpiresByType image/png A1209600
ExpiresByType image/gif A1209600
ExpiresByType image/jpeg A1209600
ExpiresByType text/javascript A1209600
ExpiresByType text/css A1209600
Tags: 
Last Updated: 
Tuesday, April 18, 2017