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 university is planning a move away from use of Cosign (see Cosign at U-M). If at all possible, we recommend you use Shibboleth instead.
Contents
- Example Site Assumptions
- Build and Install mod_cosign
- SSL Certificate Setup
- Configure Your Site To Use Cosign
- Enable Cosign On Your Site
- Common Issues
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 https://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 USERTrust root certificate, 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