cs:tech:idp:shibboleth

Shibboleth IdP

Na této stránce se nachází návod, jak do linuxové distribuce Debian nainstalovat Shibboleth IdP. Před instalací musíme zprovoznit Jetty.


Instalace

Zdrojové kódy stáhneme ze stránky projektu a umístíme do adresáře /opt anebo pomocí programu wget následujícím způsobem. Nezapomeneme ověřit SHA256 otisk a GPG podpis.

# Stažení zdrojového kódu Shibboleth IdP
wget -P /opt \
     https://shibboleth.net/downloads/identity-provider/3.4.6/shibboleth-identity-provider-3.4.6.tar.gz \
     https://shibboleth.net/downloads/identity-provider/3.4.6/shibboleth-identity-provider-3.4.6.tar.gz.asc \
     https://shibboleth.net/downloads/identity-provider/3.4.6/shibboleth-identity-provider-3.4.6.tar.gz.sha256
 
# Přepnutí do adresáře /opt
cd /opt
 
# Kontrola SHA256 otisku
sha256sum -c shibboleth-identity-provider-3.4.6.tar.gz.sha256
 
# Kontrola GPG podpisu
# Nejprve importujeme klíč 07CEEB8B
gpg --keyserver hkp://keys.gnupg.net --search-keys 07CEEB8B
# Nyní můžeme provést samotnou kontrolu
gpg --verify shibboleth-identity-provider-3.4.6.tar.gz.asc

Nyní přistoupíme k samotné instalaci.

# Instalace Shibboleth IdP
tar -xzf shibboleth-identity-provider-3.4.6.tar.gz
cd shibboleth-identity-provider-3.4.6/
./bin/install.sh

Po spuštění instalačního skriptu:

  1. potvrdíme zdrojový instalační adresář,
  2. vyplníme hostname serveru (pokud není vyplněn správně),
  3. potvrdíme entityID,
  4. zadáme scope organizace (pokud není vyplněn správně),
  5. vložíme opakovaně dvě hesla (Backchannel PKCS12 Password a Cookie Encryption Key Password), která si předem vygenerujeme pomocí příkazu openssl rand -hex 20.

Zde je vyobrazen průběh instalačního skriptu install.sh.

Source (Distribution) Directory (press <enter> to accept default): [/opt/shibboleth-identity-provider-3.4.6]
 
Installation Directory: [/opt/shibboleth-idp]
 
Hostname: [idp.example.org]
SAML EntityID: [https://idp.example.org/idp/shibboleth]
Attribute Scope: [example.org]
 
Backchannel PKCS12 Password: 
Re-enter password: 
Cookie Encryption Key Password: 
Re-enter password: 
Warning: /opt/shibboleth-idp/bin does not exist.
Warning: /opt/shibboleth-idp/edit-webapp does not exist.
Warning: /opt/shibboleth-idp/dist does not exist.
Warning: /opt/shibboleth-idp/doc does not exist.
Warning: /opt/shibboleth-idp/system does not exist.
Generating Signing Key, CN = idp.example.org URI = https://idp.example.org/idp/shibboleth ...
...done
Creating Encryption Key, CN = idp.example.org URI = https://idp.example.org/idp/shibboleth ...
...done
Creating Backchannel keystore, CN = idp.example.org URI = https://idp.example.org/idp/shibboleth ...
...done
Creating cookie encryption key files...
...done
Rebuilding /opt/shibboleth-idp/war/idp.war ...
...done
 
BUILD SUCCESSFUL
Total time: 28 seconds

Tím je instalace hotová a zbývá tedy IdP ještě nakonfigurovat.

Konfigurace

Konfigurace může být dost různorodá a vše závisí na tom, zda-li chcete IdP používat pouze pro přístup ke službám federace anebo se rozhodnete používat ho i pro přístup k vašim interním službám.

Zde uvedená ukázka konfigurace slouží jako naprostý základ.

idp.properties

V souboru /opt/shibboleth-idp/conf/idp.properties nastavíme, že všechny cookies budou limitovány na TLS. Bližší informace jsou k dispozici v oficiální dokumentaci.

Dále doplníme podporu pro ukládání souhlasů s vydáváním uživatelských informací (atributů) do databáze.

# Otevřeme konfigurační soubor idp.properties
vim /opt/shibboleth-idp/conf/idp.properties

Nastavíme idp.cookie.secure na hodnotu true a idp.consent.StorageService na hodnotu shibboleth.JPAStorageService:

idp.cookie.secure = true
idp.consent.StorageService = shibboleth.JPAStorageService

ldap.properties

V souboru /opt/shibboleth-idp/conf/ldap.properties se nastavuje konektor do LDAP serveru, pomocí něhož budeme získávat uživatelské atributy.

# Otevřeme konfigurační soubor ldap.properties
vim /opt/shibboleth-idp/conf/ldap.properties

Důležité jsou především následující volby:

idp.authn.LDAP.authenticator     = bindSearchAuthenticator
idp.authn.LDAP.ldapURL           = ldaps://ldap.example.org:636
idp.authn.LDAP.useStartTLS       = false
idp.authn.LDAP.useSSL            = true
idp.authn.LDAP.sslConfig         = certificateTrust
idp.authn.LDAP.trustCertificates = %{idp.home}/credentials/ldap-server.crt
idp.authn.LDAP.baseDN            = ou=people,dc=example,dc=org
idp.authn.LDAP.subtreeSearch     = true
idp.authn.LDAP.bindDN            = uid=shibboleth,ou=users,dc=example,dc=org
idp.authn.LDAP.bindDNCredential  = nejakeheslo
idp.ldaptive.provider            = org.ldaptive.provider.unboundid.UnboundIDProvider

První konfigurační parametr idp.authn.LDAP.authenticator určuje, jak se bude přistupovat k LDAP serveru. Výchozí (zakomentovaná) hodnota je anonSearchAuthenticator, takže se k LDAPu přistupuje anonymně. Pokud však chcete, aby se dotazování LDAP serveru provádělo až po přihlášení, je potřeba nastavit volbu na hodnotu bindSearchAuthenticator.

Volba idp.authn.LDAP.ldapURL určuje, ke kterému LDAP serveru se bude Shibboleth připojovat. Ve výše uvedeném příkladu se připojuje pomocí zabezpečeného SSL (ldaps://) na stadardním portu 636.

Poznámka k ldapURL: V ldapURL nesmíme uvést koncové lomítko, např. ldaps://ldap.example.org:636/, jinak nebude Shibboleth fungovat a v logu najdeme java.lang.NumberFormatException: For input string: „636/“.

Konfigurační volby idp.authn.LDAP.useStartTLS a idp.authn.LDAP.useSSL říkají, že namísto TLS budeme používat SSL. Následující volba idp.authn.LDAP.trustCertificates udává cestu ke kořenovému certifikátu CA, která vydala SSL certifikát pro LDAP server ldap.example.org. Je nutné nezapomenout nakopírovat tento soubor na odpovídající místo!

Volba idp.authn.LDAP.baseDN určuje tzv. „base DN“ v LDAPu. Volby idp.authn.LDAP.bindDN a idp.authn.LDAP.bindDNCredential určují uživatelské jméno a heslo, které se použije při přístupu k LDAP serveru pro získání uživatelských atributů.

Volba na posledním řádku (idp.ldaptive.provider) je důležitá pro fungování LDAPu při použití vyšší verze Javy než 8 (náš případ). Bez přidání této volby se Shibboleth IdP k LDAPu nepřípojí! Bližší informace naleznete v oficiální dokumentaci.

metadata-providers.xml

V konfiguračním souboru /opt/shibboleth-idp/conf/metadata-providers.xml se nastavují zdroje metadat. V následujícím příkladu je jako zdroj metadat použita federace eduID.cz i mezinárodní federace eduGAIN. Metadata se stáhnou a lokálně uloží.

# Otevřeme konfigurační soubor metadata-providers.xml
vim /opt/shibboleth-idp/conf/metadata-providers.xml
<!-- eduID.cz -->
<MetadataProvider
    id="eduidcz"
    xsi:type="FileBackedHTTPMetadataProvider"
    backingFile="%{idp.home}/metadata/eduidcz.xml"
    metadataURL="https://metadata.eduid.cz/entities/eduid+sp"
    maxRefreshDelay="PT15M">
    <MetadataFilter
        xsi:type="SignatureValidation"
        requireSignedRoot="true"
        certificateFile="%{idp.home}/credentials/metadata.eduid.cz.crt.pem" />
    <MetadataFilter xsi:type="EntityRoleWhiteList">
        <RetainedRole>md:SPSSODescriptor</RetainedRole>
    </MetadataFilter>
</MetadataProvider>
 
<!-- eduGAIN -->
<MetadataProvider
    id="edugain"
    xsi:type="FileBackedHTTPMetadataProvider"
    backingFile="%{idp.home}/metadata/edugain.xml"
    metadataURL="https://metadata.eduid.cz/entities/edugain+sp"
    maxRefreshDelay="PT15M">
    <MetadataFilter
        xsi:type="SignatureValidation"
        requireSignedRoot="true"
        certificateFile="%{idp.home}/credentials/metadata.eduid.cz.crt.pem" />
    <MetadataFilter xsi:type="EntityRoleWhiteList">
        <RetainedRole>md:SPSSODescriptor</RetainedRole>
    </MetadataFilter>
</MetadataProvider>

Blok kódu výše, tedy element <MetadataProvider> se všemi atributy, je nutné umístit do elementu <MetadataProvider> v konfiguračním souboru metadata-providers.xml! Sice to působí podivně, ale bez toho nebude XML dokument validní a konfigurace nebude fungovat.

Pokud by vás zajímal význam atributů v elementu <MetadataProvider>, naleznete vše v oficiální dokumentaci. Vše okolo <MetadataFilter> elementu naleznete také v oficiální dokumentaci.

Metadata federací eduID.cz i eduGAIN jsou podepsána. Důrazně doporučujeme tedy jejich autenticitu ověřovat pomocí kontroly podpisu! Veřejný klíč je k dispozici na adrese https://www.eduid.cz/docs/eduid/metadata/metadata.eduid.cz.crt.pem. Stáhněte ho a uložte do adresáře /opt/shibboleth-idp/credentials.

# Stažení veřejného klíče metadata.eduid.cz.crt.pem
wget -P /opt/shibboleth-idp/credentials \
    https://www.eduid.cz/docs/eduid/metadata/metadata.eduid.cz.crt.pem

attribute-resolver.xml

Chcete-li si konfigurační soubor /opt/shibboleth-idp/conf/attribute-resolver.xml nakonfigurovat od začátku a naprosto sami, využijte k tomu soubor /opt/shibboleth-idp/conf/attribute-resolver-ldap.xml, který v sobě zahrnuje i konektor do LDAP serveru.

Doporučuji však usnadnit si práci a vyjít z připraveného souboru na adrese https://www.eduid.cz/shibboleth-idp/attribute-resolver.xml. Atributy naleznete v dokumentaci. Podle tohoto seznamu si attribute-resolver.xml upravte.

Návod v následujících krocích předpokládá, že jste použili připravenou šablonu!

Navíc se předpokládá, že pro generování persistentního NameID identifikátoru používáte atribut uid. Tento SAML atribut nesmí mít v attribute-resolver.xml XML atribut dependencyOnly=„true“, jinak nebude pro generování persistentního NameID k dispozici a persistentní NameID se nevygeneruje. Několik služeb bez persistentního NameID nebude fungovat!

# Stažení attribute-resolver.xml
wget -O /opt/shibboleth-idp/conf/attribute-resolver.xml \
    https://www.eduid.cz/shibboleth-idp/attribute-resolver.xml

Potřebujete-li si definovat své atributy, pak bližší informace ke konfiguraci naleznete v oficiální dokumentaci.

attribute-filter.xml

Mít definované atributy z předchozího kroku nestačí. Ještě je potřeba nadefinovat, které atributy budeme vydávat a komu je budeme vydávat. To se nastavuje v konfiguračním souboru /opt/shibboleth-idp/conf/attribute-filter.xml.

Z důvodu zjednodušení doporučujeme uvolňovat atributy dle našeho doporučení na adrese https://www.eduid.cz/shibboleth-idp/attribute-filter.xml.

Filtr uvolňuje atributy podle kategorií entit Research & Scholarship, Code of Conduct a dále do federací eduID.cz a eduGAIN.

wget -O /opt/shibboleth-idp/conf/attribute-filter.xml \
    https://www.eduid.cz/shibboleth-idp/attribute-filter.xml

Chcete-li si nastavit uvolňování atributů dle svého, tak bližší informace naleznete v oficiální dokumentaci.

idp-metadata.xml

Soubor /opt/shibboleth-idp/metadata/idp-metadata.xml obsahuje metadata IdP, která je potřeba po instalaci doplnit o další informace jako například element <UIInfo>, který se zapisuje do „rozšíření“ (element <Extensions>), např. za <Scope>:

# Otevřeme konfigurační soubor idp-metadata.xml
vi /opt/shibboleth-idp/metadata/idp-metadata.xml
<Extensions>
    <shibmd:Scope regexp="false">example.org</shibmd:Scope>
    <mdui:UIInfo>
        <mdui:DisplayName xml:lang="en">EXAMPLE</mdui:DisplayName>
        <mdui:DisplayName xml:lang="cs">EXAMPLE</mdui:DisplayName>
        <mdui:Description xml:lang="en">EXAMPLE's Identity Provider.</mdui:Description>
        <mdui:Description xml:lang="cs">Poskytovatel identity pro EXAMPLE.</mdui:Description>
        <mdui:InformationURL xml:lang="en">http://www.example.org/en/</mdui:InformationURL>
        <mdui:InformationURL xml:lang="cs">http://www.example.org/cs/</mdui:InformationURL>
        <mdui:Logo height="200" width="200">https://img.example.org/logo-200.gif</mdui:Logo>
    </mdui:UIInfo>
</Extensions>

Dále je nutno doplnit název organizace v elementu <Organization> (patří do elementu <EntityDescriptor> za element </AttributeAuthorityDescriptor>):

<Organization>
    <OrganizationName xml:lang="en">EXAMPLE, a. l. e.</OrganizationName>
    <OrganizationName xml:lang="cs">EXAMPLE, z. s. p. o.</OrganizationName>
    <OrganizationDisplayName xml:lang="en">EXAMPLE</OrganizationDisplayName>
    <OrganizationDisplayName xml:lang="cs">EXAMPLE</OrganizationDisplayName>
    <OrganizationURL xml:lang="en">http://www.example.org/en/</OrganizationURL>
    <OrganizationURL xml:lang="cs">http://www.example.org/cs/</OrganizationURL>
</Organization>

Chybět nesmí ani kontaktní osoby v elementu <ContactPerson> (opět v elementu <EntityDescriptor> za element <Organization>):

<ContactPerson contactType="technical">
    <GivenName>Kryštof</GivenName>
    <SurName>Šáteček</SurName>
    <EmailAddress>mailto:krystof.satecek@example.org</EmailAddress>
</ContactPerson>

V metadatech ještě doplníme podporu pro persistentní identifikátor.

Přidáme do elementu <IDPSSODescriptor> následující řádek těsně před ukončovací element </IDPSSODescriptor>.

<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>

eduGAIN

Kromě služeb ve federaci eduID.cz je možné zpřístupnit uživatelům i služby mezinárodní federace eduGAIN. K tomu je potřeba, aby bylo IdP exportováno do metadat eduGAINu, což se zajistí následující úpravou souboru /opt/shibboleth-idp/metadata/idp-metadata.xml.

Pozor! Následující kód je třeba umístit přesně tímto způsobem! Nejprve je element <EntityDescriptor>, pak následuje element <Extensions> a v něm jsou elementy <RepublishRequest> a <RepublishTarget>! Nepatří tedy do elementu <Extensions> umístěného v elementu <IDPSSODescriptor>!

<EntityDescriptor>
 
    <Extensions>
 
        <!-- eduGAIN -->
        <eduidmd:RepublishRequest xmlns:eduidmd="http://eduid.cz/schema/metadata/1.0">
            <eduidmd:RepublishTarget>http://edugain.org/</eduidmd:RepublishTarget>
        </eduidmd:RepublishRequest>
 
        <!--                                      -->
        <!-- Zde následují element Scope a UIInfo -->
        <!--                                      -->
 
    </Extensions>
 
</EntityDescriptor>

global.xml

Nyní je potřeba v souboru global.xml definovat některé „<bean>y“. Tato konfigurace zajistí správnou konektivitu na MariaDB databázi pro ukládání persistentních identifikátorů a zároveň pro ukládání souhlasů s vydáváním atributů (tzv. uApprove).

# Úpravy v konfiguračním souboru global.xml
vi /opt/shibboleth-idp/conf/global.xml

V prvním bloku kódu nahradíme _SILNE_HESLO_ heslem pro uživatele shibboleth k databázi shibboleth.

<bean id="shibboleth.MySQLDataSource"
    class="org.apache.commons.dbcp2.BasicDataSource"
    p:driverClassName="com.mysql.jdbc.Driver"
    p:url="jdbc:mysql://localhost:3306/shibboleth"
    p:username="shibboleth"
    p:password="___SILNE_HESLO___" />
 
<bean id="shibboleth.JPAStorageService"
    class="org.opensaml.storage.impl.JPAStorageService"
    p:cleanupInterval="%{idp.storage.cleanupInterval:PT10M}"
    c:factory-ref="shibboleth.JPAStorageService.entityManagerFactory" />
 
<bean id="shibboleth.JPAStorageService.entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="packagesToScan" value="org.opensaml.storage.impl"/>
    <property name="dataSource" ref="shibboleth.MySQLDataSource"/>
    <property name="jpaVendorAdapter" ref="shibboleth.JPAStorageService.JPAVendorAdapter"/>
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    </property>
</bean>
 
<bean id="shibboleth.JPAStorageService.JPAVendorAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    p:generateDdl="true"
    p:database="MYSQL"
    p:databasePlatform="org.hibernate.dialect.MySQL5Dialect" />

saml-nameid.properties

Dále musíme provést úpravy v konfiguračním souboru saml-nameid.properties.

# Úpravy v konfiguračním souboru saml-nameid.properties
vi /opt/shibboleth-idp/conf/saml-nameid.properties
# Vygenerování soli
openssl rand -base64 36

Zde definujeme odkazy na výše definované „<bean>y“, dále atribut, který se bude pro výpočet persistentního identifikátoru používat (uid) a sůl (salt) použitou pro výpočet (tu jsme si již vygenerovali výše).

idp.persistentId.sourceAttribute = uid
idp.persistentId.salt = ___SALT___
# Nové IdP
idp.persistentId.encoding = BASE32
# Migrované IdP
#idp.persistentId.encoding = BASE64
idp.persistentId.generator = shibboleth.StoredPersistentIdGenerator
idp.persistentId.dataSource = shibboleth.MySQLDataSource

saml-nameid.xml

Podpora persistentních identifikátorů je ještě potřeba zapnout v konfiguračním souboru saml-nameid.xml.

# Úpravy v konfiguračním souboru saml-nameid.xml
vi /opt/shibboleth-idp/conf/saml-nameid.xml

Stačí odkomentovat následující řádek, který je ve výchozí konfiguraci po instalaci IdP zakomentovaný.

<ref bean="shibboleth.SAML2PersistentGenerator" />

subject-c14n.xml

Teď ještě zbývá úprava v souboru subject-c14n.xml.

# Úpravy v konfiguračním souboru subject-c14n.xml
vi /opt/shibboleth-idp/conf/c14n/subject-c14n.xml

Odkomentujeme tedy následující řádek:

<ref bean="c14n/SAML2Persistent" />

Spuštění

Nyní, když máme IdP nakonfigurováno, opravíme práva v adresáři /opt/shibboleth-idp:

# Úprava práv
chown jetty /opt/shibboleth-idp/{logs,metadata}
chgrp -R jetty /opt/shibboleth-idp/{conf,credentials}
chmod -R g+r /opt/shibboleth-idp/conf
chmod 750 /opt/shibboleth-idp/credentials
chmod 640 /opt/shibboleth-idp/credentials/*

V systemd musíme Jetty povolit přístup pro zápis do adresářů s logy a metadaty.

# Úprava služby jetty9 v systemd
systemctl edit jetty9

Nastavení práv pro záspis do adresářů /opt/shibboleth-idp/{logs,metadata}:

[Service]
ReadWritePaths=/opt/shibboleth-idp/logs/
ReadWritePaths=/opt/shibboleth-idp/metadata/

Zbývá jen znovu načíst konfiguraci pro službu Jetty a tu následně restartovat:

# Restart Jetty
systemctl daemon-reload
systemctl restart jetty9

Nyní, jakmile Jetty po chvilce nastartuje, můžeme vyzkoušet, zda IdP v pořádku běží:

# Zobrazení stavu IdP
/opt/shibboleth-idp/bin/status.sh

Pokud IdP korektně běží, uvidíte následující:

### Operating Environment Information
operating_system: Linux
operating_system_version: 4.19.0-6-amd64
operating_system_architecture: amd64
jdk_version: 11.0.5
available_cores: 1
used_memory: 391 MB
maximum_memory: 1500 MB

### Identity Provider Information
idp_version: 3.4.6
start_time: 2019-12-13T15:34:26+01:00
current_time: 2019-12-13T15:34:28+01:00
uptime: 2512 ms

service: shibboleth.LoggingService
last successful reload attempt: 2019-12-13T14:33:26Z
last reload attempt: 2019-12-13T14:33:26Z

service: shibboleth.ReloadableAccessControlService
last successful reload attempt: 2019-12-13T14:33:50Z
last reload attempt: 2019-12-13T14:33:50Z

service: shibboleth.MetadataResolverService
last successful reload attempt: 2019-12-13T14:33:40Z
last reload attempt: 2019-12-13T14:33:40Z

	metadata source: eduidcz
	last refresh attempt: 2019-12-13T14:33:40Z
	last successful refresh: 2019-12-13T14:33:40Z
	last update: 2019-12-13T14:33:40Z
	root validUntil: 2020-01-12T14:01:02Z

	metadata source: edugain
	last refresh attempt: 2019-12-13T14:33:42Z
	last successful refresh: 2019-12-13T14:33:42Z
	last update: 2019-12-13T14:33:42Z
	root validUntil: 2020-01-09T15:02:02Z

service: shibboleth.RelyingPartyResolverService
last successful reload attempt: 2019-12-13T14:33:39Z
last reload attempt: 2019-12-13T14:33:39Z

service: shibboleth.NameIdentifierGenerationService
last successful reload attempt: 2019-12-13T14:33:39Z
last reload attempt: 2019-12-13T14:33:39Z

service: shibboleth.AttributeResolverService
last successful reload attempt: 2019-12-13T14:33:30Z
last reload attempt: 2019-12-13T14:33:30Z

	DataConnector staticAttributes: has never failed

	DataConnector myLDAP: has never failed

	DataConnector myStoredId: has never failed

service: shibboleth.AttributeFilterService
last successful reload attempt: 2019-12-13T14:33:29Z
last reload attempt: 2019-12-13T14:33:29Z

Tipy

Na stránce tips naleznete některé zajímavé konfigurační tipy, které by vás mohly zajímat, proto se na stránku určitě podívejte.

Vzhled

Výchozí přihlašovací stránka vypadá následujícím způsobem:

Výchozí vzhled přihlašovací stránky.

Její vzhled je možno upravit do vzhledu podobnému stránkám naší organizace. Veškeré úpravy se provádí v adresáři /opt/shibboleth-idp/edit-webapp/, jehož obsah se při aktualizaci Shibboleth IdP, narozdíl od adresáře /opt/shibboleth-idp/webapp/, nepřepisuje.

Po úpravách v adresáři /opt/shibboleth-idp/edit-webapp/ je nutné přegenerovat idp.war. Po zadání následujících příkazů je třeba potvrdit cílový adresář s instalací Shibboleth IdP.

# Přegenerování idp.war
cd /opt/shibboleth-idp
./bin/build.sh
# Průběh generování nového idp.war
Installation Directory: [/opt/shibboleth-idp]
 
Rebuilding /opt/shibboleth-idp/war/idp.war ...
...done
 
BUILD SUCCESSFUL
Total time: 3 seconds

Pak je ještě nutné restartovat Jetty:

# Restart Jetty
systemctl restart jetty9

Máme-li nainstalován Shibboleth IdP, můžeme pokračovat publikací metadat.

Last modified:: 2020/01/15 13:54