Tuesday, 6 October 2009

Upgrade to shibboleth-idp2.1.3

Shibboleth-idp 2.1.3 brings some great news, like properties now working inside attribute-resolver.

Unfortunately this upgrade should be taken seriously: I just unpacked the src, noticed a minor glitch from my previous setup (StoredID requires now just one dependency, no more), then suddently all connection from IE were broken with a white page and the following trace in the logs:

 at java.lang.Thread.run(Thread.java:619) [na:1.6.0_12]
10:07:05.583 - ERROR [edu.internet2.middleware.shibboleth.idp.authn.provider.Use
rnamePasswordLoginServlet:143] - Unable to redirect to login page.
org.apache.jasper.JasperException: Exception in JSP: /login.jsp:10

7:     LoginContext loginContext = HttpServletHelper.getLoginContext(HttpServletHelper.getStorageService(application),
8:                                                                   application, request);
9:                                                                   
10:     EntityDescriptor entityDescriptor = HttpServletHelper.getRelyingPartyMetadata(loginContext.getRelyingPartyId(),
11:                                                    HttpServletHelper.getRelyingPartyConfirmationManager(application)); 
12:                                                     
13:     Session userSession = HttpServletHelper.getUserSession(request);

As Mozilla Firefox run great, I double checked configuration files until, out of desperation, upgraded tomcat from version 5.5 to 6. Issue solved.

Frankly speaking, it was written at Preparing Apache Tomcat for the Shibboleth Identity Provider, but this issue arises with Debian: with RedHat no trouble.

Now the fun part: property file in attribute-resolver.xml: it is now possible to modify in handler.xml the attribute-resolver.xml definition:
<Service id="shibboleth.AttributeResolver"
             xsi:type="attribute-resolver:ShibbolethAttributeResolver">
        <ConfigurationResource file="/opt/shibboleth-idp/conf/attribute-resolver.xml" xsi:type="resource:FilesystemResource" >
        <ResourceFilter xsi:type="PropertyReplacement"
                        xmlns="urn:mace:shibboleth:2.0:resource"
                        propertyFile="/opt/shibboleth-idp/conf/my.properties"/>
        </ConfigurationResource>
    </Service>

where my.properies is:
bind_dn = cn=admin,dc=test,dc=com
bind_pw = WN./NHmh

which translates in attribute-resolver.xml:
 <resolver:DataConnector id="ldap1" xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
        ldapURL="ldap://localhost" 
 baseDN="ou=people,dc=test,dc=com" 
 principal="${bind_dn}"
        principalCredential="${bind_pw}"
 useStartTLS="true">
        <FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </FilterTemplate> 
    </resolver:DataConnector>

More examples at Dealing with Sensitive Configuration Information

Tuesday, 29 September 2009

Enable tomcat manager to reload shibboleth

It would be useful to be able to reload shibboleth without having to stop and restart tomcat. It is actually possible, but it is necessary to enable the manager servlet, which requires some steps.

First of all, install
sudo apt-get install tomcat5.5-admin

Then configure apache to handle /manager url though mod_ajp: add the following line in the ssl virtual host (then reload apache)
ProxyPass /manager ajp://localhost:8009/manager

Change permission to manager deployment fragment so it could be executed by tomcat5 user:
sudo chmod +x /etc/tomcat5/conf/Catalina/localhost/manager

Then create a principal able to access the manager web page: edit /etc/tomcat5.5/tomcat-users.xml by adding a user like:
<user username="admin" password="secret" roles="standard,manager"/>
(role admin is necessary to access to manager)

Then you can use the commands listed at:
http://tomcat.apache.org/tomcat-5.5-doc/manager-howto.html#Introduction

For instance, to reload shibboleth:
https://idp.server.com/manager/reload?path=/idp

Thursday, 17 September 2009

Server side sort with OpenLDAP2.4.18

OpenLDAP2.4.18 sports server side sorting (RFC 2891).

First of all, during configuration, sss should be enabled:
./configure --enable-hdb=yes --enable-sssvlv --enable-ppolicy --with-cyrus-sasl --with-tls=openssl

Then in slapd.conf, overlay has to be enabled:
overlay sssvlv
This line has to be added either in the global part or inside a backend directive.

Then, a ldapsearch can test the feature:
/usr/local/bin/ldapsearch -h localhost -x -E 'sss=cn' 'sn=m*' cn
if there is an attribute with a ordering rule.

If not, an error arises:
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: sn=m*
# requesting: cn 
# with server side sorting control
#

# search result
search: 2
result: 18 Inappropriate matching
text: serverSort control: No ordering rule

# numResponses: 1

You can add ordering rules to schemas: for instance to add ordering rules to sn, modify sn entry in core.schema as follows:
attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' )
 DESC 'RFC2256: last (family) name(s) for which the entity is known by'
 ORDERING caseIgnoreOrderingMatch
 SUP name )

This time ldapsearch returns:
# search result
search: 2
result: 0 Success
control: 1.2.840.113556.1.4.474 false MIQAAAADCgEA
sortResult: (0) Success

# numResponses: 4602
# numEntries: 4601

Monday, 14 September 2009

Install shibboleth DiscoveryService1.1.1

Instructions are ok, but I tripped on some pitfalls.

1) when deploying service, service name has to be
discovery
, so the URL in tomcat should be /discovery and deployment fragment in /etc/tomcat5.5/Catalina/localhost should look like:

<Context docBase="/opt/shibboleth-ds/war/discovery.war"
privileged="true"
antiResourceLocking="false"
antiJARLocking="false"
unpackWAR="false"
swallowOutput="true" />

this should be obvious from war name, but not to me.
2) before doing install.sh I had to remove servlet-api-2.3.jar from directory /lib. Otherwise I had an error in tomcat:
INFO:
validateJarFile(/var/lib/tomcat5.5/webapps/discovery/WEB-INF/lib/servlet-api-2.3.jar)
- jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class:
javax/servlet/Servlet.class
3) no log starts, unless you hit the url of the discoveryService, which is https://my-server.com/discovery/WAYF
4) session initiator of shibboleth-sp should look like:

<SessionInitiator acsByIndex="false" type="Chaining"
Location="/discovery" id="discovery" relayState="cookie">
<SessionInitiator type="SAML2" defaultACSIndex="1"
template="bindingTemplate.html"/>
<SessionInitiator type="Shib1" defaultACSIndex="5"/>
<SessionInitiator type="SAMLDS"
URL="https://my-server.com/discovery/WAYF"/>
</SessionInitiator>

With the SP packeged with debian/lenny, i had to add
acsByIndex="false" in the first line.
5) with the same shibboleth-sp I had to regenerate metadata from Shibboleth.sso/Metadata, as it was missing:

<md:Extensions>
<DiscoveryResponse
xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"
Location="http://bacedifo.cesia.unimo.it/Shibboleth.sso/discovery"
index="1"/>
</md:Extensions>

before the keys section (<md:KeyDescriptor use="signing">), inside md:SPSSODescriptor section.

Wednesday, 2 September 2009

Query Shibboleth2 Attribute Authority without WebSSO

First of all, please read the illuminating thread on shibboleth mailing list titled How can I only use AA of Shibboleth IdP, specially Tom Scavo's answer.

In this post I would like to show how to query the Shibboleth AA remotely from command line. This query can be well authomated in a kind of web service, which offers the informations Shibboleth gathers from different sources exactly as offered to Shibboleth SP.

The tool used is curl. It is necessary:
* craft a valid attribute request to send to shibboleth-idp
* relax security to accept queries authentication-less.

Actually authentication works as in Shibboleth-SP1.3 attribute query: requester is authenticated with x509 client certificates.

Create a valid attribute request with curl


sudo curl -v -K .curlrc

with
 $ cat .curlrc
url =
"https://idp.site.com:8443/idp/profile/SAML1/SOAP/AttributeQuery"
cert = "/etc/ssl/certs/client.pem"
key = "/etc/ssl/private/client.key"
cacert = "/etc/ssl/certs/ca-chain.pem"
data-binary = @soap.xml

and

$ cat soap.xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
IssueInstant="2009-06-10T07:21:37Z" MajorVersion="1" MinorVersion="1"
RequestID="_37fd92205b573e2b52d1a27e2e3b2192">
<samlp:AttributeQuery
Resource="https://moodle-idem.unimore.it/shibboleth">
<saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:NameIdentifier
Format="urn:mace:shibboleth:1.1:nameid-format:unspecified">the_username</saml:NameIdentifier>
</saml:Subject>
</samlp:AttributeQuery>
</samlp:Request>
</S:Body>
</S:Envelope>

Please note the_username is the principalName in the IdP Attribute Resolver.

Configurations changes on the IdP



You should instruct IdP:

  • Accept Attribute query without former authentication

  • Map the nameid in the query with a local principal


The first is done in relying-party.xml: just comment out the lines about samlsec:Replay e samlsec:IssueInstant from SecurityPolicy shibboleth.SAML1AttributeQuerySecurityPolicy (of course IssueInstant is just not to have to forge the correct datetime, if you script it you could enforce this control).

The second is done in attribute-resolver.xml: modify line

<resolver:PrincipalConnector xsi:type="Transient" xmlns="urn:mace:shibboleth:2.0:resolver:pc" id="saml1Unspec"
nameIDFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" />

to

<resolver:PrincipalConnector xsi:type="Direct" xmlns="urn:mace:shibboleth:2.0:resolver:pc" id="direct"
nameIDFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" />

It should be safe doing that because there are three nameId format, the 2.0 is used by Shibboleth-sp2.0 (which actually does not request attribute query, anyhow), the 1.0 is used by Shibboleth-sp1.3, so 1.1 format should be unused, unless othe saml clients do. In the latter case, I have no idea how to solve the issue.

Metadata


In metadata you should add a SP-like entry with the client certificate used by curl. Attribute filter applies rule according to this fake SP-entry.

Thursday, 14 May 2009

ruby ResolverScriptAttributeDefinition in shibboleth2.1

As advertised at shibboleth2.1 can leverage scripting languages as jruby via jsr223.

Unfortunately documentation just covers ecmascript, no examples for ruby.

Here follows a working example:


<resolver:AttributeDefinition id="example3" xsi:type="Script"
language="ruby" xmlns="urn:mace:shibboleth:2.0:resolver:ad">
<resolver:Dependency ref="ldap" />
<resolver:Dependency ref="example2" />
<resolver:Dependency ref="example1" />
<resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
name="urn:mace:unimore.it:attribute-def:example3" />
<resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
name="urn:mace:unimore.it:attribute-def:example3" friendlyName="example3" />
<Script>
<![CDATA[
include Java

include_class 'edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute'

$example3 = BasicAttribute.new("example3")
[$example1, $example2].each do |array|
array.get_values.each do |v|
$example1.get_values.add v
end
end
]]>
</Script>
</resolver:AttributeDefinition>


In this example values from example1 and example2 fields are merged in the new example3 attribute.

Key point to note are:
* variables are exported from shibboleth as globals ($ prefix);
* as import_package did not work for me, just including edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute is enought;
* values of attribute are of type Java::JavaUtil::ArrayList. I'm not really sure normal ruby array operation work (maybe yes);
* puts can be useful with aacli.sh: it prints on the console.

Friday, 10 April 2009

JRuby via jsr223

jsr223 allows embedding jruby code in java.

Unfortunately, at least on Debian lenny, setup requires some work.

First of all, be sure to install java1.6, for example with sun-java6-jdk package.

Then two more downloads are required:
* jruby, for instance jruby1.1.6
* jruby-engine-1.1.6.zip
Version of jruby engine must match jruby version.

Unpack Jruby, define $JRUBY_HOME to the expanded directory and have PATH=$PATH:$JRUBY_HOME/bin.

Unpack jruby-engine-*.zip.

Include in classpath jruby.jar and jruby-engine.jar from the /lib dir of the unpacked tarball.

Compile javacode as usual with javac; to run code, it could be necessary to add a -cp .:./jruby.jar:./jruby-engine.jar switch to java.

It should be possible to use jsr223-engines tarball instead of jruby-engine-*, but I tried with no luck. jruby1.0 is a deb package, but installing it didn't help, and I feared it could introduce path problems so I removed it.

Tuesday, 10 March 2009

First look on apache servicemix

I'm reading something about ESBs, and I'm focusing on servicemix, because of the richness of the documentation.

I found very strange tutorial 2.6 maven task:

mvn jbi:projectDeploy -DforceUpdate=true

fails complaining missing servicemix-file-su, which is of course specified in sa's pom.xml.

Actually it works, if the zip file is deployed manually in the /hotdeploy dir.

Tuesday, 10 February 2009

Shibboleth2 signoff (kind of)

Sometimes someone asks for a signoff procedure for shibboleth. As well known, Single Sign Off it is not possible in shibboleth2.1.

It is possibile to configure a shibboleth2-sp to authenticate user each time asks for a resource, actually breaking single sign on. Just modify shibboleth2.xml by adding forceAuth="true":


<SessionInitiator type="Chaining" Location="/Login" isDefault="true" id="Intranet"
relayState="cookie" entityID="https://idp.test.com/idp/shibboleth">
<SessionInitiator type="SAML2" defaultACSIndex="1" template="/opt/shibboleth-sp/etc/shibboleth/bindingTemplate.html" forceAuthn="true"/>
<SessionInitiator type="Shib1" defaultACSIndex="5"/>
</SessionInitiator>


This configuration allows user to execute a local sign off which forces her to re-authenticate on the IdP without closing the browser.

Please note this setting is completely insecure, as the allegedly logged out user is actually still logged in on the IdP so can access other services with the former identity. It can be secure if a service is kiosked or a IdP is in charge to serve just one SP.

Friday, 30 January 2009

openldap24: schema replica with syncrepl

Store configuration in the directory itself



One of the hot feature of openldap24 is to store configuration in the same ldap directory. Advantages are:

  • runtime modification of configuration with ldapmodify without service restart;

  • leverage of the syncprov replica of configuration branches, as schema or acl.



To enable storage of configuration in the directory itself, just start slapd with the -F switch, which points to a slapd.d directory, owned by ldap:ldap, usually located ad /etc/ldap/slapd.d (debian):

/usr/local/libexec/slapd -u ldap -g ldap -f slapd.conf -F slapd.d -d-1

(later remove the -f switch; older debian startup scripts do require -f so it could be necessary modify them).

How to replicate schema branch



First of all enable overlay syncprov over cn=config on the master server: this is the needed ldif to achieve that:

dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
changetype: add
objectClass: olcOverlayConfig
olcOverlay: syncprov

Or, if the configuration has not yet been migrated, edit slapd.conf:


database config
rootpw {SSHA}WGWXrWf/RG99aVWs3VBMn5nyJGzhCfkS
overlay syncprov

Than add to master server a acl to enable a user to read cn=config like:

access to dn.subtree="cn=config" by dn="cn=confreplica,dc=example,dc=com" read

slapd.conf on the slave should look:


#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/local/etc/openldap/schema/core.schema
#core.schema has to be included anyhow
#include /usr/local/etc/openldap/schema/cosine.schema
#include /usr/local/etc/openldap/schema/inetorgperson.schema
#include /usr/local/etc/openldap/schema/openldap.schema

# Define global ACLs to disable default read access.

# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org

pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args

# Load dynamic backend modules:
modulepath /usr/local/libexec/openldap
moduleload back_bdb
# moduleload back_hdb
# moduleload back_ldap

[...] acl go here

loglevel stats ACL sync

database config
rootdn "cn=admin,cn=config"
rootpw {SSHA}WGWXrWf/RG99aVWs3VBMn5nyJGzhCfkS
syncrepl rid=002
provider=ldap://master.example.com:389
type=refreshAndPersist
interval=00:00:10:00
searchbase="cn=schema,cn=config"
filter="objectClass=olcSchemaConfig"
scope="sub"
binddn="cn=confreplica,dc=example,dc=com"
bindmethod=simple
credentials="secret"
# next database sections


Than, migrate configuration on slave from slapd.conf to slapd.d as usual.

Wednesday, 14 January 2009

SASL/EXTERNAL with openldap

SASL EXTERNAL mechanism allows passwordless authentication with x509 user certificates.

I believe it could prove very useful for replication, where, with simple bind, bind_dn and bind_pw were to be written in cleartext in slapd.conf.

This mechanism is also very handy because it requires encryption to work, and a clear text connection can't work.

Steps are:

  • apt-get install libsasl2-modules-ldap on the server;

  • modify slapd.conf to use TLS and to try verify peer;

  • modify user .ldaprc to include user certificate.



slapd.conf should include:

TLSCACertificateFile /etc/ssl/certs/ca-cert.pem
TLSCertificateFile /etc/ssl/certs/server.pem
TLSCertificateKeyFile /etc/ssl/private/server.key
TLSVerifyClient try

where server.pem and server.key and server certificate and unprotected key, while ca-cert.pem is the certificate file of the CA under which is issued the client user certificate.

.ldaprc:

TLS_CACERT /etc/ssl/certs/server-ca-chain.pem
TLS_CACERTDIR /etc/ssl/certs
TLS_CERT /home/user/client.pem
TLS_KEY /home/user/client.key
SASL_MECH EXTERNAL

where client.key can be protected or unprotected key and server-ca-chain is cert file of the CA which issued the server cert.

An error like this one:

ldapsearch -x -ZZ -h server.test.com 'uid=user'
ldap_start_tls: Connect error (-11)
additional info: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

means the client is using a certificate with a different CA from TLSCACertificateFile.

If everything is in order:

ldapsearch -x -ZZ -H ldap://server.test.com -b "" -LLL -s base supportedSASLMechanisms
dn:
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: CRAM-MD5
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: NTLM
supportedSASLMechanisms: EXTERNAL

And it possible to launch:

ldapsearch -ZZ -h server.test.com 'uid=user'

to read in /var/log/ldap.log:

Jan 14 12:08:12 server slapd[15308]: conn=38 op=1 BIND authcid="cn=bacedifo,dc=test,dc=com" authzid="cn=bacedifo,dc=test,dc=com"
Jan 14 12:08:12 server slapd[15308]: conn=38 op=1 BIND dn="cn=bacedifo,dc=test,dc=com" mech=EXTERNAL ssf=0

Monday, 12 January 2009

Upgrade from shibboleth idp 2.1.0 to 2.1.2

This upgrade has proved to be very smooth.

I was scared by the upgrade ad hoc page. Actually it was about upgrade from 2.0 to 2.1 version.

Instead it was enought to download the tar.gz, verify signature, unzip run
sh install.sh
No need to backup configuration data, if you choose not to overwrite it.

It's only needed to build again the link with libraries not included in the war bundle, ad example the jdbc ones:

sudo ln -s /usr/share/java/mysql-connector-java.jar $IDP_HOME/lib/

copy personalized login pages from old source to new source path:

cp -va shibboleth-identityprovider-2.1.0/src/main/webapp/login.jsp
shibboleth-identityprovider-2.1.2/src/main/webapp/

and restart tomcat.

Friday, 9 January 2009

Block ssh connection by IP

The subject is rather lame, as blocking ssh by IP source is really last resource. But sometimes can be handy.

  • Modify sshd_config
    Just add in /etc/ssh/sshd_config

    AllowUsers *@192.169.1.1

    People non connecting from 192.168.1.1 will be prompted for username and password, but they could try forever as none will work.

  • Use inetd
    Add in /etc/hosts.deny:

    sshd: ALL

    and in /etc/hosts.allow:

    sshd: 192.169.1.1

    People outside 192.168.1.1 receive a: ssh_exchange_identification: Connection closed by remote host, while nmap states port 22 as "open".

  • Use iptables
    Add to INPUT chain, with a default deny, something like:

    iptables -A INPUT -p tcp -m tcp -s 192.169.1.1/32 --dport 22 --syn -j ACCEPT

    People outside 192.168.1.1 will have connection hanged, and nmap says port 22 is "filtered".