Documentation

Server 3.x

SAML (Shibboleth SP)#

This document describes installing Shibboleth on Debian. We’ve most recently tested this on Debian 12, but should work on Debian 11 and Ubuntu 22.04 as well.

NOTE: this is NOT a full Shibboleth SP configuration installation manual. It documents just enough to make it work in most scenarios. Shibboleth is very complex software! You MUST refer to the official documentation and fully comprehend what you are doing. Your NREN / Identity Federation most likely can provide additional guidance on setting up Shibboleth properly.

Installation#

$ sudo apt install libapache2-mod-shib
$ sudo shib-keygen -n sp-encrypt
$ sudo shib-keygen -n sp-signing

Configuration#

Modify /etc/shibboleth/shibboleth2.xml:

Configuring automatic metadata refresh is outside the scope of this document, refer to your identity federation documentation.

Verify the Shibboleth configuration:

$ sudo shibd -t
2024-01-09 08:40:27 WARN Shibboleth.DEPRECATION : MetadataGenerator handler
overall configuration is loadable, check console or log for non-fatal problems

NOTE: the deprecation warning is about the <Handler type="MetadataGenerator" Location="/Metadata" signing="false"/> line in the configuration file. Instead the metadata SHOULD be generated by shib-metagen(1).

Restart Shibboleth:

$ sudo systemctl restart shibd

Next: register your SP in your identity federation, or in your IdP. The metadata URL is typically https://vpn.example.org/Shibboleth.sso/Metadata.

Apache#

In /etc/apache2/sites-available/vpn.example.org.conf add the following:

<VirtualHost *:443>

    ...

    <Location /vpn-user-portal>
        AuthType shibboleth
        ShibRequestSetting requireSession 1
        <RequireAll>
            Require shib-session
            #Require shib-attr entitlement "http://eduvpn.org/role/admin"
            #Require shib-attr unscoped-affiliation staff
        </RequireAll>
    </Location>

    # do not restrict API Endpoint as used by VPN clients
    <Location /vpn-user-portal/api>
        Require all granted
    </Location>

    # do not secure OAuth Token Endpoint as used by VPN clients
    <Location /vpn-user-portal/oauth/token>
        Require all granted
    </Location> 

    # If you run separete node(s) you MUST allow access to "node-api.php" 
    # without protecting it with Shibboleth
    #<Location /vpn-user-portal/node-api.php>
    #    Require all granted
    #</Location>

    ...

    </VirtualHost>

If you have a case where only one attribute needs to match, you can use <RequireAny>instead of <RequireAll>. You will also need to remove the Require shib-session.

Make sure you restart Apache after changing the configuration:

$ sudo systemctl restart apache2

NOTE if you are using IDs such as entitlement and unscoped-affiliation make sure they are correctly enabled/set in /etc/shibboleth/attribute-map.xml.

Portal#

In order to configure the VPN portal, modify /etc/vpn-user-portal/config.php and set the authModule and ShibAuthModule options:

'authModule' => 'ShibAuthModule',

'ShibAuthModule' => [
    'userIdAttribute' => 'uid',
    'permissionAttributeList' => ['entitlement'],
],

Typical values for the userIdAttribute are uid, eppn, pairwise-id, persistent-id or mail. Typical values for permissionAttributeList are entitlement or affiliation. Other attributes are possible. For that refer to /etc/shibboleth/attribute-map.xml. If you modify attribute-map.xml do not forget to restart Shibboleth.

If you do not know what you should choose, see the Debugging section on how to list the attributes that are available, i.e. those provided by your IdP.

Debugging#

If you are having trouble getting Shibboleth to work correctly you can create a file in /usr/share/vpn-user-portal/web/dump.php:

<?php
echo '<pre>';
var_dump($_SERVER);
echo '</pre>';

When now visiting https://vpn.example.org/vpn-user-portal/dump.php, you should see all SAML attributes (and more) being provided to the VPN authentication module. For example:

  ...

  ["mail"]=>
  string(17) "foo@example.org"
  ["entitlement"]=>
  string(58) "http://eduvpn.org/role/admin;https://eduvpn.org/expiry#P1Y"

  ...

In this case you can use the mail and entitlement as values for userIdAttribute and permissionAttributeList. You can see here that entitlement is multi value, the values are separated by the ; character.

When you figured out everything, do NOT forget to delete the dump.php file again!