Shibboleth IDP 2.4 amb Debian Wheezy 7.1

Objectiu:

L’objectiu d’aquesta entrada és disposar d’una màquina que executi el servei de proveïdor d’identitat (en endavant idp) Shibboleth versió 2.4. Aquesta màquina serà l’encarregada d’autenticar els usuaris dels diferents serveis web de la nostra organització tot proporcionant un entorn d’entrada única (Single Sign On) a la vegada que subministrarà els atributs que aquestes aplicacions web requereixin.

L’autenticació i l’obtenció dels atributs es duran a terme mitjançant un directori LDAP.

Aquesta entrada està altament basada en les configuracions que SWITCH té per a la seva federació (https://www.switch.ch/aai/docs/shibboleth/SWITCH/latest/idp/deployment). Tot i així el document de SWITCH està basat en un entorn ja muntat al que s’han d’afegir la resta d’organitzacions. El nostre objectiu és desplegar l’entorn de Single Sign On en un entorn local i des de zero.

Requeriments previs:

El sistema operatiu que utilitzarem és Debian Wheezy versió 7.1. La instal·lació del sistema operatiu no es detallarà. Existeix una guia per a Debian Lenny 5.0 en aquest bloc que es pot utilitzar sense massa complicacions, ja que el procés d’instal·lació és gairebé calcat.

Per allotjar l’idp utilitzarem tomcat6 disponible als repositoris de Debian. S’utilitzarà també apache2 com a proxy_ajp i com a proveïdor de seguretat SSL.

A la vegada serà necessari disposar d’algun sistema de resolució de noms, ja sigui mitjançant un servidor DNS (com ara bind) o bé mitjançant l’arxiu /etc/hosts en cada màquina on treballem. Tal i com s’indica en aquesta entrada el nom de la màquina on s’allotjarà l’idp serà idp.domain.org, alhora, per la propera entrada, el nom del proveïdor de serveis serà sp.domain.org.

Instal·lació del programari bàsic:

Partirem doncs d’un Debian Wheezy 7.1 net on treballarem amb l’usuari root.

Instal·larem els següents paquets dels repositoris oficials:

$ apt-get install unzip ntp curl ccze ca-certificates
$ apt-get install default-jre-headless
$ apt-get install apache2 tomcat6

NOTA: El paquet default-jre-headless no instal·la els requeriments d’X11 que tampoc fan falta.

Configuració del servei tomcat6:

Un cop instal·lat el programari bàsic aturem el servei tomcat6 i en modifiquem les propietats d’arrencada:

$ service tomcat6 stop
$ pico /etc/default/tomcat6
...
JAVA_OPTS="-Djava.awt.headless=true -Xmx512M -XX:MaxPermSize=128M -Dcom.sun.security.enableCRLDP=true"
...

NOTA: Substituïm la línia que hi ha configurada.

A continuació modifiquem les propietats per defecte de tomcat6 tot traient l’opció d’autodeploy, afegint el connector ajp al port 8009 i comentant la resta de connectors no necessaris:

$ pico /etc/tomcat6/server.xml
...
    <!--
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="UTF-8" redirectPort="8443" />
    -->
...
    <!-- Define an AJP 1.3 Connector on port 8009 --> 
    <Connector port="8009" address="127.0.0.1" enableLookups="false" redirectPort="443" protocol="AJP/1.3" tomcatAuthentication="false" />
...
    <!-- Define the default virtual host
         Note: XML Schema validation will not work with Xerces 2.2.
    -->
    <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="false" xmlValidation="false" xmlNamespaceAware="false">
...

Instal·lació de l’idp:

Per fer la instal·lació és necessari que el sistema conegui la ubicació del jre de java. Això ho podem fer amb un export o en l’arxiu .profile d’entrada en sessió:

$ pico ~/.profile
...
IdPCertLifetime=3
JAVA_HOME=/usr/lib/jvm/default-java
export IdPCertLifetime
export JAVA_HOME
...

A continuació obtenim el programari de l’idp i l’instal·lem al tomcat6:

$ cd /usr/local/src
$ curl -O http://shibboleth.net/downloads/identity-provider/2.4.0/shibboleth-identityprovider-2.4.0-bin.zip
$ unzip shibboleth-identityprovider-2.4.0-bin.zip
$ cd shibboleth-identityprovider-2.4.0
$ chmod u+x install.sh

Afegim el rang d’adreces IP de la xarxa que estem usant per tal d’accedir a les pàgines d’estatus de l’idp. Això ens anirà bé a l’hora de fer el debug. Un cop tot estigui funcionant correctament es pot tornar a limitar l’accés:

$ pico src/main/webapp/WEB-INF/web.xml
...
    <!-- Space separated list of CIDR blocks allowed to access the status page -->
    <init-param>
        <param-name>AllowedIPs</param-name>
        <param-value>127.0.0.1/32 ::1/128 {EL_NOSTRE_RANG}</param-value>
    </init-param>
...
$ mkdir /usr/share/tomcat6/endorsed/
$ cp ./endorsed/*.jar /usr/share/tomcat6/endorsed/
$ ./install.sh

NOTA: Per tornar a tancar l’accés és necessari disposar del codi font de l’aplicació, és a dir la carpeta que s’ha descarregat i on s’estan duent a terme les modificacions, desfer l’edició i tornar a executar la comanda ./install.sh.

La instal·lació ens demanarà on volem instal·lar el programari, el lloc predeterminat és /opt/shibboleth-idp. Aquesta ubicació és correcta i recomanable. A continuació, i per tal de crear la configuració adaptada i els certificats adients ens demanarà el nom del servei on s’allotjarà l’idp. Aquest punt és important ja que afectarà als certificats que crearem més tard així com les configuracions que haurem de fer en la resta de proveïdors de serveis que desitgin contactar amb l’idp. Així doncs escollim un nom DNS que s’adapti a la nostra organització. En aquest document utilitzarem el nom idp.domain.org.

Deixem que es dugui a terme la instal·lació i procedim a afegir l’arxiu .war a la configuració de tomcat6:

$ pico /etc/tomcat6/Catalina/localhost/idp.xml
<Context
    docBase="/opt/shibboleth-idp/war/idp.war"
    privileged="true"
    antiResourceLocking="false"
    antiJARLocking="false"
    unpackWAR="false"
    swallowOutput="true"
    cookies="false" />

Apliquem la seguretat necessària al directori de l’idp:

$ cd /opt/shibboleth-idp
$ chown root credentials/idp.key
$ chgrp tomcat6 credentials/idp.{key,crt}
$ chmod 440 credentials/idp.key
$ chmod 644 credentials/idp.crt
$ rm credentials/idp.jks
$ chown -R tomcat6 logs metadata
$ chgrp -R tomcat6 conf credentials logs metadata war lib
$ chown tomcat6 conf/attribute-filter.xml
$ chmod 664 conf/attribute-filter.xml
$ chmod 750 lib war
$ chmod 750 conf credentials
$ chmod 775 logs metadata

Permetem que l’idp autentiqui mitjançant nom d’usuari i contrasenya i comentem l’opció d’autenticació mitjançant usuari remot:

$ pico $IDP_HOME/conf/handler.xml
...
    <!--
    <ph:LoginHandler xsi:type="ph:RemoteUser">
        <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</ph:AuthenticationMethod>
    </ph:LoginHandler>
    -->
...
    <!--  Username/password login handler -->
    <ph:LoginHandler xsi:type="ph:UsernamePassword" jaasConfigurationLocation="file:///opt/shibboleth-idp/conf/login.config">
        <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</ph:AuthenticationMethod>
    </ph:LoginHandler>
...

Per l’autenticació dels usuaris mitjançant LDAP modifiquem l’arxiu d’autenticació de l’idp:

$ pico conf/login.config
ShibUserPassAuth {
   edu.vt.middleware.ldap.jaas.LdapLoginModule required
      ldapUrl="ldap://ldap.domain.org"
      baseDn="dc=domain,dc=org"
      bindDn="cn=binduser,dc=domain,dc=org"
      bindCredential="password"
      searchScope="SUBTREE"
      userFilter="uid={0}";
};

ALTERNATIVA: Si s’utilitza Active Directory és millor accedir pel port 3268 i el filtre d’usuari s’hauria de modificar també:

ShibUserPassAuth {
   edu.vt.middleware.ldap.jaas.LdapLoginModule required
      ldapUrl="ldap://ad.domain.org:3268"
      baseDn="dc=domain,dc=org"
      bindDn="cn=binduser,dc=domain,dc=org"
      bindCredential="password"
      searchScope="SUBTREE"
      userFilter="samaccountname={0}";
};

Creació dels certificats SSL de seguretat per l’apache2:

A continuació crearem els certificats SSL que incorporarem en la configuració d’apache2 per tal que la comunicació els usuaris finals sigui segura. No s’entra en detall del que es fa en cada comanda. Existeix un tutorial d’openssl aquí si es desitja més informació.

$ pico /usr/lib/ssl/openssl.cnf

Canviem les següents línies:

dir             = .
certificate	= $dir/ca.crt
private_key	= $dir/private/ca.key

Creem una CA de desenvolupament i els certificats necessaris:

$ cd
$ mkdir -p CA/{certs,private,newcerts}
$ cd CA
$ openssl req -x509 -days 3650 -newkey rsa:2048 -keyout ca.key -out ca.crt
$ chmod g-rwx,o-rwx private
$ echo '01' > serial
$ touch index.txt
$ mv ca.key private/
$ chmod 0600 private/ca.key
$ openssl req -nodes -newkey rsa:2048 -keyout idp.domain.org.key -out idp.domain.org.req
$ openssl ca -in idp.domain.org.req -out idp.domain.org.crt
$ rm idp.domain.org.req
$ openssl req -nodes -newkey rsa:2048 -keyout sp.domain.org.key -out sp.domain.org.req
$ openssl ca -in sp.domain.org.req -out sp.domain.org.crt
$ rm sp.domain.org.req

NOTA: Com es pot apreciar, s’ha creat un certificat per a idp.domain.org i un pel proveïdor de serveis sp.domain.org que ens farà falta en la següent entrada.

Un cop creats els certificats afegim la CA al grup de certificats arrel vàlids pel sistema:

$ mkdir /usr/share/ca-certificates/domain.org
$ cp ca.crt /usr/share/ca-certificates/domain.org
$ dpkg-reconfigure ca-certificates

Configuració de l’apache2:

Modifiquem la configuració d’apache2 per adaptar-la als nostres requeriments:

$ mkdir /etc/apache2/ssl
$ cp idp.domain.org* /etc/apache2/ssl
$ chmod 0600 /etc/apache2/ssl/idp.domain.org.key
$ a2enmod ssl
$ a2enmod proxy_ajp

A continuació afegim una configuració nova de VirtualHost per a l’idp:

$ pico /etc/apache2/sites-available/idp
ServerName idp.domain.org
<VirtualHost _default_:443>
	ServerName idp.domain.org:443
	ServerAdmin suport@domain.org

	DocumentRoot /var/www

	SSLEngine On
	SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
	SSLProtocol all -SSLv2
	SSLCertificateFile /etc/apache2/ssl/idp.domain.org.crt
	SSLCertificateKeyFile /etc/apache2/ssl/idp.domain.org.key

	<Proxy ajp://localhost:8009>
	    Allow from all
	</Proxy>

	ProxyPass /idp ajp://localhost:8009/idp retry=5

	BrowserMatch "MSIE [2-6]" \
             nokeepalive ssl-unclean-shutdown \
             downgrade-1.0 force-response-1.0
	# MSIE 7 and newer should be able to use keepalive
	BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>

<VirtualHost _default_:8443>
	ServerName idp.domain.org:8443
	ServerAdmin suport@domain.org

	DocumentRoot /var/www

	SSLEngine On
	SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
	SSLProtocol all -SSLv2
	SSLCertificateFile /opt/shibboleth-idp/credentials/idp.crt
	SSLCertificateKeyFile /opt/shibboleth-idp/credentials/idp.key
	SSLVerifyClient optional_no_ca
	SSLVerifyDepth 10

	<Proxy ajp://localhost:8009>
	    Allow from all
	</Proxy>

	ProxyPass /idp ajp://localhost:8009/idp retry=5

	BrowserMatch "MSIE [2-6]" \
             nokeepalive ssl-unclean-shutdown \
             downgrade-1.0 force-response-1.0
	# MSIE 7 and newer should be able to use keepalive
	BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>

Habilitem la configuració:

$ a2dissite default
$ a2ensite idp

Deixem de donar servei al port 80 ja que no és necessari. L’idp només escoltarà connexions segures.

$ pico /etc/apache2/ports.conf
NameVirtualHost *:443

<IfModule mod_ssl.c>
    # If you add NameVirtualHost *:443 here, you will also have to change
    # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
    # to <VirtualHost *:443>
    # Server Name Indication for SSL named virtual hosts is currently not
    # supported by MSIE on Windows XP.
    Listen 443
    Listen 8443
</IfModule>

Arrencada de l’idp:

Finalment reiniciem el servei apache2 i iniciem el servei tomcat6:

$ service apache2 restart
$ service tomcat6 start

La següent comanda ens mostrarà els registres d’arrencada per poder verificar que l’idp ha arrencat sense incidències:

$ tail -f /var/log/tomcat6/catalina.out $IDP_HOME/logs/idp-process.log | ccze

Comprovació final:

Per comprovar que el servei funciona podem accedir a la pàgina següent des d’un navegador:

https://idp.domain.org/idp/status

La pàgina, en text clar, ens mostrarà l’estat del nostre idp.

En aquest punt la instal·lació de l’idp es pot donar per completada tot i que actualment no és capaç d’autenticar cap proveïdor de serveis o subministrar atributs ja que aquestes opcions encara no s’han configurat. L’entrada següent mostrarà com dur a terme la configuració bàsica d’un proveïdor de serveis (SP) i, aleshores, mostrarem com subministrar atributs.

Documentació:

Bona sort amb la documentació de Shibboleth. Ells ja hi posen bona fe, ja, però és força complexa de seguir. Us deixo l’enllaç a la wiki: https://wiki.shibboleth.net/confluence/display/SHIB2/Home