UABgrid On-line CA Construction Notes

The system is built on a Debian4 minimal install. Only the web-server component was selected during install leading toward a spartan application foundation that should be just enough to run the CA services. The system was configured to prevent root login and an administrator account defined to run system utilities. The plan is to have dedicated administrator accounts for specific admins to support the tracking of configuration changes, these may be consolidated into one account once configuration management replaced direct manipulation of the system.

Additional Packages

Some packages do need to be added after install however:

apt-get install \
  less openssh-server ntp-server ntpdate patch

Network Configuration

The ca.uabgrid.uab.edu hostname was assigned during installation so there's no need to change it. The install used dhcp for interface configuration so we need to change that. This is done in /etc/network/interfaces. Change the file to replace the definition of eth0 with the following:

allow-hotplug eth0
auto eth0
iface eth0 inet static
 address 138.26.125.66
 gateway 138.26.1.1
 netmask 255.255.0.0
 network 138.26.0.0
 broadcast 138.26.255.255

This defines the public interface.

The /etc/resolve.conf needs to contain:

search uabgrid.uab.edu
nameserver 138.26.134.2
nameserver 138.26.1.2

This will eventually be updated to receive naming services via the core-cluster.

Firewall Configuration

A firewall configuration will eventually be needed to control access and help define the security on the external and internal network interfaces. This debian shorewall firewall config may be helpful. At present, only WWW and SSH services are exposed by the system so a firewall would simply control SSH access. Again, this will become more imporant as the configuration management interfaces are enabled.

Configure Time Synchronization

cd /etc
patch -b ntp.conf << EOF
19,22c19,20
< server 0.debian.pool.ntp.org iburst
< server 1.debian.pool.ntp.org iburst
< server 2.debian.pool.ntp.org iburst
< server 3.debian.pool.ntp.org iburst
---
> server tick.dpo.uab.edu
> server tock.dpo.uab.edu
EOF

You'll also want to sync the clock up to make sure the system is ready to go:

/etc/init.d/ntp stop
ntpdate-debian
/etc/init.d/ntp start

Use ntpdate-debian to leverage the time server settings in ntp.conf above.

Shibboleth SP Configuration

Install the Shibboleth SP for Debian Etch.

apt-get install libapache2-mod-shib

Note: there is a problem with the log4cpp build on Debian which causes the shibd process to die under load (discussed on the shib-users list). The work around is to not use the PatternLayout format and instead use BasicLayout. This bug can be avoided with the following patch to the shibd logging configuration:

cd /etc/shibboleth
patch -b shibd.logger << EOF
19,21c19,21
< #log4j.appender.shibd_log.layout=org.apache.log4j.BasicLayout
< log4j.appender.shibd_log.layout=org.apache.log4j.PatternLayout
< log4j.appender.shibd_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
---
> log4j.appender.shibd_log.layout=org.apache.log4j.BasicLayout
> #log4j.appender.shibd_log.layout=org.apache.log4j.PatternLayout
> #log4j.appender.shibd_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
27,28c27,29
< log4j.appender.tran_log.layout=org.apache.log4j.PatternLayout
< log4j.appender.tran_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
---
> log4j.appender.tran_log.layout=org.apache.log4j.BasicLayout
> #log4j.appender.tran_log.layout=org.apache.log4j.PatternLayout
> #log4j.appender.tran_log.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
EOF
/etc/init.d/shibd restart

The difference between the log file formats when using BasicLayout is that the timestamps are printed in Unix time (seconds since the epoch) instead of and easier to formatted date/time. Whether this is a problem or not is a preference issue. Having the timestamps in Unix time makes parsing the date easier. The more human readable date format may be helpful during debugging so it can always be turned on when debugging and turned off under ordinary operation.

Requesting UABgrid Credentials

In order to access the UABgrid infrastructure a resource needs to have registered identity. This identity is define via a certificate signed by the UABgrid CA. This is required for both web and grid resources. While web servers are not required to use the UABgrid issued certificates for their client facing services (the are required on the back-end to access identity services), we serves are permitted to use the certificates for client services. This is the practice we use for the core UABgrid service and what is assumed in the instructions below. (The following steps are an updated form of earlier docs and not grid-specific.)

The first step is to create a the public/private key pair and signing request for the public key. This can be done in a single step. The openssl config file built below provides reasonable defaults for user input and avoids having to type in values. You can accept the defaults for everything but the Common Name field and email address.

cd /etc/ssl/private
cat << EOF > uabgrid-openssl.conf
#
# OpenSSL configuration file for generating a certificate signing request for UABgrid.
#

# This definition stops the following lines choking if HOME isn't
# defined.
HOME                    = .
RANDFILE                = $ENV::HOME/.rnd

####################################################################
[ req ]
encrypt_key             = no
default_bits            = 1024
default_keyfile         = hostkey.pem
distinguished_name      = req_distinguished_name

# This sets a mask for permitted string types.
string_mask = nombstr

[ req_distinguished_name ]
countryName                     = Country Name (use default value. press enter)
countryName_default             = US
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (use default value. press enter)
stateOrProvinceName_default     = Alabama

localityName                    = Locality Name (use default value. press enter)
localityName_default            = Birmingham

0.organizationName              = Organization Name (use default value. press enter)
0.organizationName_default      = University of Alabama at Birmingham

organizationalUnitName          = Organizational Unit Name (use default value. press enter)
organizationalUnitName_default  = UABgrid

commonName                      = Common Name (ie, your fully qualified server hostname)
commonName_max                  = 64

emailAddress                    = Email Address for certificate owner
emailAddress_max                = 64
EOF
openssl req -new -out `hostname --fqdn`.csr -keyout `hostname --fqdn`.key \
  -config uabgrid-openssl.conf

After generating the certificate signing request (CSR) you need to send it to jpr@uab.edu to have it signed by the UABgrid CA. Either attach the .csr file to a message or just paste the output of the following command in an email.

cat `hostname --fqdn`.csr 

Once the certificate is signed, you'll get a response containing your certificate. You can paste the certificate into the file /etc/ssl/certs/your.host.name.crt

vi /etc/ssl/certs/`hostname --fqdn`.crt

The host now has a certificate ready for use within the UABgrid identity framework and one that can be used to provide SSL web services to users.

Note: if you are setting up a web-based virtual host the will provide an SSL service, you can just replace the above uses of hostname --fqdn with the name of your virtual host.

After installing your new certificate, you will also need to trust the UABgrid CA by installing the UABgrid CA root on this host.

cd /etc/ssl/certs
wget -N http://uabgrid.uab.edu/files/56498486.0

Define the web server configuration

The core UABgrid services take the approach of defining a explicit vhost container for the web site configuration, rather then relying on the default (non-virtual host contained) web server configuration. This keeps a configuration clean and makes it easy to migrate to any hosting platform.

The Debian base puts Apache virtual hosts in /etc/apache2/sites-available, so this is the base of configuration. We start with this template and add specific services to it. The template includes both HTTP and HTTPS service interfaces.

cd /etc/apache2/sites-available
cat << EOF > new-service-site
<VirtualHost _IPADDR_:80>
        ServerName _FQDN_
        ServerAdmin webmaster@_FQDN_
        ServerSignature On

        ErrorLog /var/log/apache2/error-_SHORTNAME_.log
        LogLevel warn
        CustomLog /var/log/apache2/access-_SHORTNAME_.log combined

        DocumentRoot /srv/www/_SHORTNAME_

        <Directory /srv/www/_SHORTNAME_/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        Alias /secure /var/www/secure
        <Directory /var/www/secure>
                AllowOverride All
                Options All
                Order allow,deny
                Allow from all
        </Directory>

</VirtualHost>

<VirtualHost _IPADDR_:443>
        ServerName _FQDN_
        ServerAdmin webmaster@_FQDN_
        ServerSignature On

        ErrorLog /var/log/apache2/error-_SHORTNAME_.log
        LogLevel warn
        CustomLog /var/log/apache2/access-_SHORTNAME_.log combined

        DocumentRoot /srv/www/_SHORTNAME_

        SSLEngine on
        SSLCertificateFile /etc/ssl/certs/_FQDN_.crt
        SSLCertificateKeyFile /etc/ssl/private/_FQDN_.key
        SSLCACertificatePath /etc/ssl/certs

        <Directory /srv/www/_SHORTNAME_/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        Alias /secure /var/www/secure
        <Directory /var/www/secure>
                AllowOverride All
                Options All
                Order allow,deny
                Allow from all
        </Directory>

</VirtualHost>
EOF

This template can be modified for the current service, in this case ca.uabgrid, with the following sed script (adjust as needed).

sed -e 's/_IPADDR_/138.26.125.66/' \
    -e 's/_FQDN_/ca.uabgrid.uab.edu/' \
    -e 's/_SHORTNAME_/ca.uabgrid/' \
    new-service-site > ca.uabgrid

Remove the temporary site template:

rm new-service-site

A few things to note about the template and conversion. We expect virtual sites to exist under /srv/www, there is one resource /secure which can be shared across all hosted sites on a system and used to test shibboleth attribute distribution (more later), the virtual hosts are always IP-based. You can do name-based virtual hosts but they are less useful if your goal is to provide some assurance about a users identity accessing an application (as is the case on UABgrid), finally, the SSL configuration files point to the files created above.

Set up the site specific vhost directory:

mkdir -p /srv/www/ca.uabgrid
touch /srv/www/ca.uabgrid/index.html # don't reveal you site structure needlessly

Set up the secure directory for testing the UABgrid attribute distribution.

mkdir -p /var/www/secure
cat << EOF > /var/www/secure/printenv.pl
#!/usr/bin/perl -w

print "Content-type: text/html\n\n";

foreach $key (sort keys %ENV) {
  print("$key: $ENV{$key}<br>\n");
}
EOF
cat << EOF > /var/www/secure/phpinfo.php
<?php

phpinfo();

?>
EOF
cat << EOF > /var/www/secure/.htaccess
AuthType shibboleth
ShibRequireSession On
require valid-user
AddHandler cgi-script .pl
EOF

Note: after initial tests are complete, you may want to restrict access to /secure to just the users that are responsibe for the hosting system itself. This can be done by replacing require valid-user with require user username@domain.

This virtual host definition needs to be enabled. On Debian this is done with a2enable sitename. We also want to disable the default "default" site, which is a catch all virtual host that comes with the Debian package. This is not necessary (and undersirable) with explict site configurations

a2ensite ca.uabgrid
a2dissite default

We will need to restart the apache server before the site changes take effect, but new site is now in place and ready for use.

# ls /etc/apache2/sites-enabled/
ca.uabgrid

Configure support for SSL service and mod-rewrite (since this is common for apps):

a2enmod ssl
a2enmod rewrite

The final step is to support HTTP and HTTPS. By default, only port 80 is active for Apache. The following patch will add port 443 support to expose the HTTPS virtual host:

cd /etc/apache2
patch -b ports.conf << EOF
1a2
> Listen 443
EOF

Configure Shibboleth SP

The final step before the web server can be used to provide applications that leverage the UABgrid identity framework is to configure the Shibboleth service provider module. The steps here essentially configure your web server to act as a trusted recipient of UABgrid identity attributes. From the perspective of authentication, this is essentially web single-sign on. What's important to know, is that users never send their credentials (username and password) to your application. Your web application simply receives a statement (assertion) from the UABgrid identity framework saying "this is user xyz@abc". In addition to users identity, other attributes such as their email and UABgrid group membership information is provided. Your web service is a trusted receiver of this information and, due to the trust relationship with UABgrid, trusts that this information is valid. Because this attribute exchange is all handled with server-to-server certificate trusts, your web service knows it is UABgrid that is supplying the information and UABgrid knows it is your web service receiving it. This intricacies of the trusts can be controlled by either side, but this is the basic premiss. It's also probably more than needs stating for these instructions, but is worth being reminded of.

To configure your web service, you need three things: 1. A valid configuration file for the Apache Shibboleth module: shibboleth.xml 1. A file that defines the trusted source of the identity attributes you are receiving: uabgrid-metadata.xml 1. A file the defines the identity attributes you are willing to accept and what CGI variables will contain them

Configuring shibboleth.xml

First, move the sample shibboleth.xml that comes with the install out of the way.

cd /etc/shibboleth
mv shibboleth.xml shibboleth.xml.dist

Then save the following configuration file template:

cd /etc/shibboleth
cat << EOF > shibboleth.xml.template
<SPConfig xmlns="urn:mace:shibboleth:target:config:1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:mace:shibboleth:target:config:1.0 shibboleth-targetconfig-1.0.xsd"
    clockSkew="180"
    logger="/etc/shibboleth/shibboleth.logger">

    <Extensions>
        <Library path="/usr/lib/shibboleth/xmlproviders.so" fatal="true"/>
    </Extensions>

    <Global logger="/etc/shibboleth/shibd.logger">
        
        <UnixListener address="/var/run/shibd.sock"/>

        <MemorySessionCache cleanupInterval="300" cacheTimeout="3600" 
            AATimeout="30" AAConnectTimeout="15"
            defaultLifetime="1800" retryInterval="300" 
            strictValidity="false" propagateErrors="true"/>
        
    </Global>
    
    <Local logger="/etc/shibboleth/native.logger" localRelayState="true">
        <RequestMapProvider type="edu.internet2.middleware.shibboleth.sp.provider.NativeRequestMapProvider">
            <RequestMap applicationId="default">
                <Host name="_FQDN_">
                    <Path name="secure" authType="shibboleth" requireSession="true" exportAssertion="true">
                    </Path>
                </Host>
            </RequestMap>
        </RequestMapProvider>
        
        <!-- Only used by IIS. Here for completeness -->
        <Implementation>
            <ISAPI normalizeRequest="true">
                <Site id="1" name="_FQDN_">
                    <!-- <Alias>www-alias.example.edu</Alias> -->
                </Site>
            </ISAPI>
        </Implementation>
    </Local>

    <!--
    The Applications section is where most of Shibboleth's SAML bits are defined.
    Resource requests are mapped in the Local section into an applicationId that
    points into to this section.
    -->
    <Applications id="default" 
        providerId="https://_FQDN_/shibboleth"
        homeURL="https://_FQDN_/"
        xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
        xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">

        <Sessions lifetime="7200" timeout="3600" checkAddress="false"
            handlerURL="/Shibboleth.sso" handlerSSL="true" 
            idpHistory="true" idpHistoryDays="7">
            
            <SessionInitiator  id="UABgrid" isDefault="true" 
                Location="/WAYF/UABgrid"
                Binding="urn:mace:shibboleth:sp:1.3:SessionInit"
                wayfURL="https://vo.uabgrid.uab.edu/shibboleth-idp/SSO"
                wayfBinding="urn:mace:shibboleth:1.0:profiles:AuthnRequest"/>
                            
            <md:AssertionConsumerService Location="/SAML/POST" index="1" isDefault="true"
                Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post"/>
            <md:AssertionConsumerService Location="/SAML/Artifact" index="2" isDefault="false"
                Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"/>
            
            <md:SingleLogoutService Location="/Logout" 
                Binding="urn:mace:shibboleth:sp:1.3:Logout"/>

        </Sessions>

        <Errors session="/etc/shibboleth/sessionError.html"
            metadata="/etc/shibboleth/metadataError.html"
            rm="/etc/shibboleth/rmError.html"
            access="/etc/shibboleth/accessError.html"
            supportContact="_EMAIL_"
            logoLocation="/shibboleth-sp/logo.jpg"
            styleSheet="/shibboleth-sp/main.css"/>

        <!-- Indicates what credentials to use when communicating -->
        <CredentialUse TLS="uabgrid" Signing="uabgrid">
        </CredentialUse>
            
        <!-- AAP can be inline or in a separate file -->
        <AAPProvider type="edu.internet2.middleware.shibboleth.aap.provider.XMLAAP" 
            uri="/etc/shibboleth/AAP.uabgrid.xml"/>
        
        <!-- UABgrid metadata -->
        <MetadataProvider type="edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata"
            uri="/etc/shibboleth/uabgrid-metadata.xml"/>
        
        <!-- The standard trust provider supports SAMLv2 metadata with path validation extensions. -->
        <TrustProvider type="edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrust"/>
                    
    </Applications>
    
    <!-- Define all the private keys and certificates here that you reference from <CredentialUse>. -->
    <CredentialsProvider type="edu.internet2.middleware.shibboleth.common.Credentials">
        <Credentials xmlns="urn:mace:shibboleth:credentials:1.0">
            <FileResolver Id="uabgrid">
                <Key>
                    <Path>/etc/ssl/private/_FQDN_.key</Path>
                </Key>
                <Certificate>
                    <!-- Certificate and the whole chain -->
                    <Path>/etc/ssl/certs/_FQDN_.crt</Path>
                </Certificate>
            </FileResolver>
        </Credentials>
    </CredentialsProvider>
</SPConfig>
EOF

Now adjust the template to serve as the official host configuration:

sed -e 's/_FQDN_/ca.uabgrid.uab.edu/' -e 's/_EMAIL_/jpr@uab.edu/' \
  shibboleth.xml.template > shibboleth.xml

Register the web service

The service needs to be registered in with the UABgrid identity frame to be a trusted destination for attributes. Please contact jpr@uab.edu to request registration.

Complete Shibboleth configuration

Download the UABgrid metadata and default attribute configuration file.

cd /etc/shibboleth
wget -N http://uabgrid.uab.edu/files/uabgrid-metadata.xml
wget -N http://uabgrid.uab.edu/files/AAP.uabgrid.xml

Restart the web service

/etc/init.d/shibd restart
/etc/init.d/apache2 restart

Test Service

The service is now ready for testing. If all has gone as expected, you should be able to point your browser at https://ca.uabgrid.uab.edu/secure/printenv.pl and see an output of the attributes available to your web site.