cs:tech:sp:shibboleth

Shibboleth SP 3

Následující návod popisuje instalaci a konfiguraci Shibboleth SP řady 3. Jako poskytovatele služby (Service Provider, SP) můžete také použít SimpleSAMLphp, jehož instalace a konfigurace je na našich stránkách také zdokumentována.

V návodu budeme používat linuxovou distribuci Debian v jeho poslední verzi 11 s kódovým označením Bullseye. Používáte-li jinou distribuci, některé kroky (např. instalace balíčků) se u vás budou odpovídajícím způsobem lišit.

Problém s instalací na Ubuntu 18.04 LTS (Bionic Beaver)!

Ivan Masár z Univerzity Tomáše Bati ve Zlíně narazil na problém s instalací balíčku libapache2-mod-shib2 na Ubuntu 18.04 LTS (Bionic Beaver). Ten vyžaduje balíček libcurl3, nicméně ostatní balíčky povětšinou vyžadují libcurl4. Způsobuje to, že balíček libapache2-mod-shib2 blokuje další mnohdy potřebné balíčky, např. php-curl.

Problém je v Ubuntu zdokumentován a existuje i řešení.

Návod provází kompletní instalací a konfigurací Shibboleth SP včetně zdrojů metadat federace eduID.cz a Social IdPs (GitHub, Google, LinkedIn, ORCID).

Instalace

Balíček Shibboleth SP v Debianu včetně modulu pro HTTP server Apache nainstalujeme následujícím příkazem:

# Instalace Shibboleth SP včetně modulů pro Apache HTTP server
apt install libapache2-mod-shib

Pokud na serveru chybí Apache, bude doinstalován jako závislost anebo je možné ho nejprve doinstalovat následujícím příkazem:

# Instalace Apache
apt install apache2

Konfigurace

Máme-li nainstalovaný Shibboleth SP z balíčků v Debianu, konfigurace je uložena v adresáři /etc/shibboleth. Nejdůležitějším souborem je pak shibboleth2.xml.

# Nejdůležitější nastavení Shibboleth SP se provádí v shibboleth2.xml
vi /etc/shibboleth/shibboleth2.xml

entityID

Služba se musí ve federaci nějak identifikovat a k tomuto účelu se používá entityID. V atributu entityID u elementu <ApplicationDefaults> definujeme entityID naší služby. Výchozí hodnota je nastavena na https://sp.example.org/shibboleth, doporučuji změnit pouze hodnotu sp.example.org na DNS název serveru.

<!-- Nastavení entityID -->
<ApplicationDefaults entityID="https://sp.example.org/shibboleth"
    REMOTE_USER="eppn subject-id pairwise-id persistent-id"
    cipherSuites="DEFAULT:!EXP:!LOW:!aNULL:!eNULL:!DES:!IDEA:!SEED:!RC4:!3DES:!kRSA:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1">

Sezení

V elementu <Sessions> je možné nastavit několik důležitých voleb. Pro zvýšení bezpečnosti nastavíme u tohoto elementu atributy handlerSSL, resp. cookieProps na hodnoty true, resp. https následujícím způsobem (ostatní atributy a hodnoty můžeme ponechat na výchozích hodnotách):

<!-- Nastavení handlerSLL a cookieProps -->
<Sessions lifetime="28800" timeout="3600" relayState="ss:mem"
    checkAddress="false" handlerSSL="true" cookieProps="https"
    redirectLimit="exact">

WAYF/DS

Přihlášení ke službě jde nastavit buď vůči jednomu konkrétnímu IdP anebo vůči více IdP pomocí WAYF/DS. Použití WAYF/DS je častější případ. Obojí se provádí v elementu <SSO>.

Chcete-li použít WAYF/DS a dát tak uživatelům možnost si vybrat svou domovskou organizaci pro ověření, musíte z elementu <SSO> odstranit atribut entityID, následně můžete v atributu discoveryURL nastavit URL adresu WAYF/DS. V následujícím příkladu použijeme WAYF/DS federace eduID.cz, avšak můžete použít svůj vlastní.

<!-- Autentizace vůči IdP vybranému z WAYF/DS -->
<SSO discoveryProtocol="SAMLDS" discoveryURL="https://ds.eduid.cz/wayf.php">
    SAML2
</SSO>

Budete-li chtít nastavit ověření vůči jednomu konkrétnímu IdP, nechte v elementu <SSO> pouze atribut entityID s hodnotou odpovídající entityID danému IdP.

<!-- Autentizace vůči jednomu konkrétnímu IdP -->
<SSO entityID="https://idp.example.org/idp/shibboleth">
    SAML2
</SSO>

Metadata služby

Standardní metadata služby, která si můžete nechat vygenerovat po přístupu na https://sp.example.org/Shibboleth.sso/Metadata, je potřeba doplnit šablonou o určité údaje (např. organizace, kontakt atd.) než je možné službu zaregistrovat do federace. Korektní metadata tedy vygenerujeme následujícím postupem.

V shibboleth2.xml najdeme element <Handler> týkající se metadat:

<!-- Extension service that generates "approximate" metadata based on SP configuration. -->
<Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>

a doplníme do něj atribut template=„metadata-template.xml“, kterým Shibbolethu sdělíme, odkud (metadata-template.xml) má číst dodatečné informace pro metadata.

<!-- Extension service that generates "approximate" metadata based on SP configuration. -->
<Handler type="MetadataGenerator" Location="/Metadata" signing="false" template="metadata-template.xml"/>

Soubor metadata-template.xml s doplňujícími informacemi o službě neexistuje, takže si ho musíme vytvořit a to ideálně v adresáři /etc/shibboleth.

# Vytvoříme si XML dokument s doplňujícími informacemi o službě
vi /etc/shibboleth/metadata-template.xml

Obsah souboru metadata-template.xml upravíme tak, aby odpovídal skutečnosti.

<?xml version="1.0" encoding="utf-8" ?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
 
  <md:SPSSODescriptor>
 
    <md:Extensions>
      <mdui:UIInfo xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
        <mdui:DisplayName xml:lang="en">Software Database</mdui:DisplayName>
        <mdui:DisplayName xml:lang="cs">Databáze software</mdui:DisplayName>
        <mdui:Description xml:lang="en">Software available for download.</mdui:Description>
        <mdui:Description xml:lang="cs">Seznam software ke stažení.</mdui:Description>
        <mdui:InformationURL xml:lang="en">https://sp.example.org/en/info</mdui:InformationURL>
        <mdui:InformationURL xml:lang="cs">https://sp.example.org/cs/info</mdui:InformationURL>
        <mdui:Logo height="128" width="128">https://sp.example.org/logo.png</mdui:Logo>
      </mdui:UIInfo>
    </md:Extensions>
 
    <md:AttributeConsumingService index="0">
      <md:ServiceName xml:lang="en">Software Database</md:ServiceName>
      <md:ServiceName xml:lang="cs">Databáze software</md:ServiceName>
      <md:ServiceDescription xml:lang="en">Software available for download.</md:ServiceDescription>
      <md:ServiceDescription xml:lang="cs">Seznam software ke stažení.</md:ServiceDescription>
      <md:RequestedAttribute FriendlyName="eppn" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
      <md:RequestedAttribute FriendlyName="givenName" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
      <md:RequestedAttribute FriendlyName="mail" Name="urn:oid:0.9.2342.19200300.100.1.3" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
      <md:RequestedAttribute FriendlyName="sn" Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true"/>
    </md:AttributeConsumingService>
 
  </md:SPSSODescriptor>
 
  <md:Organization>
    <md:OrganizationName xml:lang="en">Organizace, a. l. e.</md:OrganizationName>
    <md:OrganizationName xml:lang="cs">Organizace, z. s. p. o.</md:OrganizationName>
    <md:OrganizationDisplayName xml:lang="en">Organizace</md:OrganizationDisplayName>
    <md:OrganizationDisplayName xml:lang="cs">Organizace</md:OrganizationDisplayName>
    <md:OrganizationURL xml:lang="en">https://www.example.org/en</md:OrganizationURL>
    <md:OrganizationURL xml:lang="cs">https://www.example.org/cs</md:OrganizationURL>
  </md:Organization>
 
  <md:ContactPerson contactType="technical">
    <md:GivenName>Kryštof</md:GivenName>
    <md:SurName>Šáteček</md:SurName>
    <md:EmailAddress>mailto:krystof.satecek@example.org</md:EmailAddress>
  </md:ContactPerson>
 
</md:EntityDescriptor>

Finální metadata

Po restartování shibd procesu budou korektní metadata k dispozici na adrese https://HOSTNAME/Shibboleth.sso/Metadata.

Hodnoty uživatelských atributů

Toto je vhodné pouze pro ladění konfigurace a v produkčním stavu služby nemá význam.

Při přístupu na adresu https://HOSTNAME/Shibboleth.sso/Session se zobrazí, nejste-li přihlášeni, pouze informace „A valid session was not found.“ Pokud ale budete přihlášení, čili budete mít na službě vytvořené sezení, uvidíte zajímavé informace, např. které atributy jste od IdP získali. Chcete-li si kromě seznamu atributů nechat zobrazit i jejich hodnoty, musíte změnit hodnotu atributu showAttributeValues na true u elementu <Handler> s atributem type rovným hodnotě Session:

<!-- Zobrazení hodnot atributů na diagnostické stránce /Shibboleth.sso/Session -->
<Handler type="Session" Location="/Session" showAttributeValues="true"/>

Kontakt na správce služby

Je také vhodné nastavit kontakt na správce služby. Pokud přihlášení z nějakého důvodu selže, obvykle se zobrazí i e-mailová adresa, na které je možné informovat správce.

E-mailová adresa správce se nastavuje v atributu supportContact u elementu <Errors>:

<Errors supportContact="root@example.org"
    helpLocation="/about.html"
    styleSheet="/shibboleth-sp/main.css"/>

Metadata federace

Metadata federace se nastavují v elementu <MetadataProvider>. V následujících příkladech si ukážeme konfiguraci metadat federace eduID.cz a také služeb sociálních IdP jako GitHub, Google, LinkedIn a ORCID.

Jelikož jsou metadata obou zmíněných federací digitálně podepsána, budeme tento podpis kontrolovat. Pro to si musíme nejprve stáhnout veřejný klíč.

# Stažení veřejného klíče pro kontrolu autentičnosti metadat
wget -P /etc/shibboleth https://www.eduid.cz/docs/eduid/metadata/metadata.eduid.cz.crt.pem

Nyní zbývá nastavit zdroje metadat a nezapomenout na ověření pravosti metadat (kontrola vůči veřejnému klíči, který jsme právě stáhli).

Konfigurace federace eduID.cz jako zdroje metadat:

<!-- Metadata federace eduID.cz -->
<MetadataProvider type="XML" validate="true"
    url="https://metadata.eduid.cz/entities/eduid+idp"
    backingFilePath="eduid.xml" maxRefreshDelay="900">
 
    <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
    <MetadataFilter type="Signature" certificate="metadata.eduid.cz.crt.pem" verifyBackup="false"/>
</MetadataProvider>

Konfigurace federace eduGAIN jako zdroje metadat:

<!-- Metadata federace eduGAIN -->
<MetadataProvider type="XML" validate="true"
    url="https://metadata.eduid.cz/entities/edugain+idp"
    backingFilePath="edugain.xml" maxRefreshDelay="900">
 
    <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
    <MetadataFilter type="Signature" certificate="metadata.eduid.cz.crt.pem" verifyBackup="false"/>
</MetadataProvider>

Konfigurace federace Social IdPs (GitHub, Google, LinkedIn a ORCID) jako zdroje metadat:

<!-- Metadata služby Social IdP (GitHub, Google, LinkedIn, ORCID) -->
<MetadataProvider type="XML" validate="true"
    url="https://metadata.eduid.cz/entities/socialidps"
    backingFilePath="socialidps.xml" maxRefreshDelay="900">
 
    <MetadataFilter type="RequireValidUntil" maxValidityInterval="2419200"/>
    <MetadataFilter type="Signature" certificate="metadata.eduid.cz.crt.pem" verifyBackup="false"/>
</MetadataProvider>

Význam atributů elementu <MetadataProvider>:

  • type=„XML“ – metadata jsou načtena z lokálního nebo vzdáleného XML dokumentu,
  • url – URL metadat,
  • backingFilePath – název (a případně i adresář, výchozí /var/cache/shibboleth/), kam se metadata uloží,
  • maxRefreshDelay – maximální doba mezi načtením nových metadat (v sekundách).

Význam elementů <MetadataFilter> a jeho atributů:

  • type=„RequireValidUntil“ – vyžaduje, aby kořenový element v metadatech měl atribut validUntil,
  • maxValidityInterval – maximální doba platnosti metadat v sekundách,
  • type=„Signature“ – ověří XML podpis v metadatech,
  • certificate – certifikát obsahující veřejný klíč použitý k ověření podpisu metadat.

Vygenerování a konfigurace self-sign certifikátu

Komunikace ve federaci se šifruje, proto SP musí v metadatech uvádět svůj veřejný klíč, pomocí něhož IdP bude moci zašifrovanou zprávu (XML assertion) rozšifrovat. Výrazně doporučujeme v metadatech používat self-sign certifikát s dlouho dobou platnosti, např. 10 nebo i více let. Není vhodné používat certifikát od důvěryhodné certifikační autority, u něhož je platnost omezena na maximálně 2 roky a následně je nutné tento certifikát vyměnit.

V linuxové distribuci Debian je pro generování self-sign certifikátu pro Shibboleth SP přítomný shellovský skript shib-keygen, který stačí spustit s odpovídajícími parametry.

# Vygenerování self-sign certifikátu pro Shibboleth SP
shib-keygen -h sp.example.org -y 10 -e https://sp.example.org/shibboleth

Význam jednotlivých přepínačů:

  • -h – hostname serveru, kde služba běží,
  • -y – platnost certifikátu v rocích,
  • -e – entityID, pro které certifikát vystavujeme.

Certifikát, resp. klíč, se uloží do souboru sp-cert.pem, resp. sp-key.pem v adresáři /etc/shibboleth/. Nyní již jen zbývá nakonfigurovat použití self-sign certifikátu v Shibbolethu. Původní elementy <CredentialResolver> zakomentujeme nebo smažeme a poté na jejich místo uvedeme následující (všimněte si, že oproti původním elementům zde není žádný atribut use):

<CredentialResolver type="File" key="sp-key.pem" certificate="sp-cert.pem"/>

Restart Shibboleth SP

Nyní musíme restartovat Shibboleth SP, aby se načetla nová konfigurace.

systemctl restart shibd

Registrace služby v metadatech federace eduID.cz

Nyní je potřeba službu zaregistrovat do federace eduID.cz. Stáhněte metadata z adresy https://HOSTNAME/Shibboleth.sso/Metadata a postupujte podle návodu pro publikaci metadat.

Použití u Apache

Uživatelské atributy

Uživatelské atributy získá web server v proměnných, které se definují v konfiguračním souboru attribute-map.xml. Například níže uvedené mapování zajistí, že proměnné obsahující křestní jméno a příjmení (v SAML2 kódování), budou dostupné v proměnných givenName a sn.

# SAML2
<Attribute name="urn:oid:2.5.4.42" id="givenName"/>
<Attribute name="urn:oid:2.5.4.4" id="sn"/>

REMOTE_USER

V proměnné REMOTE_USER bude po přihlášení uživatele uloženo jeho uživatelské jméno. V konfiguračním souboru shibboleth2.xml lze v atributu REMOTE_USER u elementu <ApplicationDefaults> nadefinovat mezerou oddělený seznam atributů, z nichž se Shibboleth SP pokusí uživatelské jméno získat. První proměnná (ve výchozím nastavení je: eppn subject-id pairwise-id persistent-id), která bude obsahovat nějakou hodnotu, se použije a uloží se do proměnné REMOTE_USER:

<ApplicationDefaults entityID="https://sp.example.org/shibboleth"
    REMOTE_USER="eppn subject-id pairwise-id persistent-id">

eduPersonUniqueId

Pokud byste chtěli namísto hodnoty atributu eduPersonPrincipalName použít hodnotu uloženou v eduPersonUniqueId, bude-li k dispozici, stačí v konfiguraci Shibbolethu (shibboleth2.xml) přidat uniqueId na začátek proměnné REMOTE_USER:

<ApplicationDefaults entityID="https://sp.example.org/shibboleth"
    REMOTE_USER="uniqueId eppn subject-id pairwise-id persistent-id"

V takovém případě je ale ještě potřeba zajistit mapování atributu eduPersonUniqueId na proměnnou uniqueId v Shibboleth SP. To se nastavuje v konfiguračním souboru attribute-map.xml:

<Attribute name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" id="uniqueId">
    <AttributeDecoder xsi:type="ScopedAttributeDecoder"/>
</Attribute>

Přístup po přihlášení

V níže uvedeném příkladu si pomocí Shibbolethu zpřístupníme adresář (/shibbloleth) ve webovém serveru Apache. Podle konfigurace v souboru /etc/shibboleth/shibboleth2.xml budeme následně při přístupu k danému adresáři přesměrování na WAYF/DS anebo na konkrétní IdP, vůči kterému budou moci uživatelé provést své přihlášení.

<Location /shibboleth>
    AuthType            shibboleth
    Require             shibboleth
    ShibRequestSetting  requireSession  1
</Location>

Aby výše uvedená konfigurace byla funkční, je potřeba, aby byl v HTTP serveru Apache aktivován modul pro Shibboleth. Ten se aktivuje automaticky po instalaci, v případě, že by však aktivní nebyl je možné ho aktivovat ručně:

# Aktivace modulu pro Shibboleth SP v Apache
a2enmod shib

Nyní je nutné restartovat Apache, aby si načetl nejen nově povolený modul, pokud jste ho museli aktivovat sami ručně, ale také aby si přečetl novou konfiguraci s přístupem k adresáři /shibboleth.

# Restartování Apache pro načtení všech povolených modulů
systemctl restart apache2

Lazy sessions

Chceme-li u webové aplikace povolit přístup anonymním uživatelům a přihlášení vyžadovat až pro přístup k nějaké specifické části anebo pro zpřístupnění úprav, můžeme použít tzv. lazy sessions. To se hodí zejména pro wiki stránky, které je možné bez přihlášení bez omezení prohlížet, ale upravovat použe po přihlášení. Zároveň to umožňuje indexovat web vyhledávacím robotům různých vyhledávačů (Seznam.cz, Google atd.). Stačí requireSession nastavit na hodnotu 0 (nula) namísto 1 jako v předchozí části.

<Location /shibboleth>
    AuthType            shibboleth
    Require             shibboleth
    ShibRequestSetting  requireSession  0
</Location>

Bližší možnosti nastavení jsou k dispozici na oficiálních stránkách Shibbolethu (Apache, htaccess).

Poslední úprava:: 2024/08/06 13:49