Stiahneme a rozbalíme inštalačný balíček:
wget https://shibboleth.net/downloads/identity-provider/3.4.1/shibboleth-identity-provider-3.4.1.tar.gz tar -xzf shibboleth-identity-provider-3.4.1.tar.gz
Spustíme inštaláciu:
./shibboleth-identity-provider-3.4.1/bin/install.sh
Výstup:
Source (Distribution) Directory (press <enter> to accept default): [/root/shibboleth-identity-provider-3.4.1] Installation Directory: [/opt/shibboleth-idp] Hostname: [demoidp.sanet.sk] SAML EntityID: [https://demoidp.sanet.sk/idp/shibboleth] Attribute Scope: [sanet.sk] Backchannel PKCS12 Password: <Heslo3> Re-enter password: <Heslo3> Cookie Encryption Key Password: <Heslo4> Re-enter password: <Heslo4> 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 = demoidp.sanet.sk URI = https://demoidp.sanet.sk/idp/shibboleth ... ...done Creating Encryption Key, CN = demoidp.sanet.sk URI = https://demoidp.sanet.sk/idp/shibboleth ... ...done Creating Backchannel keystore, CN = demoidp.sanet.sk URI = https://demoidp.sanet.sk/idp/shibboleth ... ...done Creating cookie encryption key files... ...done Rebuilding /opt/shibboleth-idp/war/idp.war ... ...done BUILD SUCCESSFUL Total time: 3 minutes 8 seconds
Presunieme inštalačný adresár do /opt
(zatial neviem načo) a nastavíme opravnenia:
mv shibboleth-identity-provider-3.4.1 /opt/ chown -R idp:idp /opt/shibboleth-id*
Reštartujeme Jetty, servlet by sa mal nahrať:
systemctl restart jetty
Stav IdP môžeme zobraziť príkazom:
/opt/shibboleth-idp/bin/status.sh
Funkčnost je možné overiť aj zobrazením stránky v prehliadači: https://demoidp.sanet.sk/idp
Prepnúť sa na používateľa idp:
su - idp
Aby Shibboleth poznal cestu k Jave aj pod neprivilegovaným učtom musíme ju špecifikovať:
JAVA_HOME=/usr/java/latest /opt/shibboleth-idp/bin/reload-service.sh -id shibboleth.ReloadableAccessControlService
V konfigurácii idp nastavíme premennú idp.cookie.secure
na true (odkomentovať a zmeniť na true):
vim /opt/shibboleth-idp/conf/idp.properties
idp.cookie.secure = true
a reštartujeme jetty (ako root)
systemctl restart jetty
Tu je možné obmedziť prístup k stránkam so špeciálnou funkcionalitou (pre adminov):
vim /opt/shibboleth-idp/conf/access-control.xml
<util:map id="shibboleth.AccessControlPolicies"> <entry key="AccessByIPAddress"> <bean id="AccessByIPAddress" parent="shibboleth.IPRangeAccessControl" p:allowedRanges="#{ {'127.0.0.1/32', '194.160.44.13/32'} }" /> </entry> ...
Znovunačitame konfigurácie (pokiaľ robíme pod userom idp musíme stále zadávať JAVA_HOME):
JAVA_HOME=/usr/java/latest /opt/shibboleth-idp/bin/reload-service.sh -id shibboleth.ReloadableAccessControlService
Teraz by malo byť možné z vybraných IP zobraziť napríklad info o stave idp: https://demoidp.sanet.sk/idp/status
Zaitaľ sa mi nepodarilo nakonfigurovať IdP tak aby mu stačilo spojenie s LDAP bez SSL. Možno je to bug: http://shibboleth.net/pipermail/users/2015-August/023536.html
Pre použitie SSL treba stiahnuť ssl certifikat z LDAP servera:
openssl s_client -showcerts -connect io.fpv.umb.sk:636 </dev/null 2>/dev/null|openssl x509 -outform PEM > /opt/shibboleth-idp/credentials/ldap-server.crt
vim /opt/shibboleth-idp/conf/ldap.properties
idp.authn.LDAP.authenticator = bindSearchAuthenticator idp.authn.LDAP.ldapURL = ldaps://ldap.umb.sk:636 idp.authn.LDAP.useStartTLS = false idp.authn.LDAP.useSSL = true idp.authn.LDAP.connectTimeout = PT3S idp.authn.LDAP.responseTimeout = PT3S idp.authn.LDAP.sslConfig = certificateTrust idp.authn.LDAP.trustCertificates = %{idp.home}/credentials/ldap-server.crt idp.authn.LDAP.baseDN = ou=users,dc=ldap,dc=umb,dc=sk idp.authn.LDAP.subtreeSearch = true idp.authn.LDAP.userFilter = (uid={user}) idp.authn.LDAP.bindDN = cn=demoidp,ou=system,ou=users,dc=ldap,dc=umb,dc=sk idp.authn.LDAP.bindDNCredential = ------- heslo pre ldap usera ------- idp.attribute.resolver.LDAP.ldapURL = %{idp.authn.LDAP.ldapURL} idp.attribute.resolver.LDAP.connectTimeout = %{idp.authn.LDAP.connectTimeout:PT3S} idp.attribute.resolver.LDAP.responseTimeout = %{idp.authn.LDAP.responseTimeout:PT3S} idp.attribute.resolver.LDAP.baseDN = %{idp.authn.LDAP.baseDN:undefined} idp.attribute.resolver.LDAP.bindDN = %{idp.authn.LDAP.bindDN:undefined} idp.attribute.resolver.LDAP.bindDNCredential = %{idp.authn.LDAP.bindDNCredential:undefined} idp.attribute.resolver.LDAP.useStartTLS = %{idp.authn.LDAP.useStartTLS:true} idp.attribute.resolver.LDAP.trustCertificates = %{idp.authn.LDAP.trustCertificates:undefined} idp.attribute.resolver.LDAP.searchFilter = (uid=$resolutionContext.principal)
vim /opt/shibboleth-idp/conf/metadata-providers.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- This file is an EXAMPLE metadata configuration file. --> <MetadataProvider id="ShibbolethMetadata" xsi:type="ChainingMetadataProvider" xmlns="urn:mace:shibboleth:2.0:metadata" xmlns:resource="urn:mace:shibboleth:2.0:resource" xmlns:security="urn:mace:shibboleth:2.0:security" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd"> <!-- MEtadata federacie - maxRefreshDelay urcuje ako casto sa budu metadata aktualizovat --> <MetadataProvider id="safeid-metadata" xsi:type="FileBackedHTTPMetadataProvider" backingFile="%{idp.home}/metadata/safeid.xml" metadataURL="https://www.safeid.sk/metadata/metadata.safeid.sk.xml" maxRefreshDelay="PT2H"> <MetadataFilter xsi:type="SignatureValidation" requireSignedRoot="true" certificateFile="%{idp.home}/credentials/SAFEID_metadata_signer.pem" /> </MetadataProvider> </MetadataProvider>
Stiahnuť verejný kľúč pre kontrolu podpisu metadát:
cd /opt/shibboleth-idp/credentials wget https://www.safeid.sk/metadata/cert/SAFEID_metadata_signer.pem
Reštart služby pre načítanie metadát:
JAVA_HOME=/usr/java/latest /opt/shibboleth-idp/bin/reload-service.sh -id shibboleth.MetadataResolverService
Kontrola, či sa metadata stiahli:
ls -l /opt/shibboleth-idp/metadata/
Vo výpise by sa mal nachádzať súbor safeid.xml
s aktuálnym časom vytvorenia.
cd /opt/shibboleth-idp/conf mv attribute-resolver-ldap.xml attribute-resolver.xml
TODO: Doplnit alebo nalinkovat obsah suboru attribute-resolver.xml
Tu definujeme, ktoré atribúty budeme uvolnovať a komu.
vim /opt/shibboleth-idp/conf/attribute-filter.xml
TODO: Doplnit alebo nalinkovat obsah suboru attribute-filter.xml
Tu treba doplniť metadata.
vim /opt/shibboleth-idp/metadata/idp-metadata.xml
TODO: Doplnit alebo nalinkovat obsah suboru idp-metadata.xml
Po reštarte jetty budú metadata dostupné na adrese https://demoisp.sanet.sk/idp/shibboleth. Metadata je potrebné validovať vo validátore: https://mdr.safeid.sk/saml-validator/
Identifikátor sa generuje pre každý pár používateľ-služba a slúži na ochranu súkromia používatela (služba zároveň vie, že sa jedná o rovnakého používateľa). Kedže sa pre každú sluzbu generuje iný identifikátor a tento identifikátor je nahodny reťazec, nie je jednoducho možne pre prevádzkovateľa služby používateľa identifikovať ale zároven to umožäuje zo strany služby ukladať rôzne personalizované nastavenia atď. V tom je hlavný rozdiel oproti identifikátoru eduPersonPrinciaplName
, ktorý má spravidla hodnotu login@domena
.
Podpora pre túto funkcionalitu nie je povinná, ale je doporučovaná. Podobný efekt je možné dosiahnuť používaním generovaného čísla namiesto loginu používateľa v eduPersonPrinciaplName
. Samorejme to stráca zmysel ak spolu s týmto identifikátorom posielame ďalšie údaje ako meno, mail atď.
Navyše niektoré z konfigurašnych krokov, ktoré budú potrebné pre jeho spravádzkovanie bude potrebné aj tak urobiž kvôli ukladaniu súhlasov s poskytovaním atribútov.
Pre ukladanie údajov je odporúčané použiť databázu MySQL (nie MariaDB).
Nainštalovať repozitár od Oracle - MySQL server:
yum install https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm yum update yum install mysql-community-server
Spustiť server:
systemctl enable mysqld systemctl startmysqld
Po spustení server vygeneruje heslo pre roota, ktoré sa nachádza v logu:
cat /var/log/mysqld.log | grep password
Spustíme procedúru pre zabezpečenie databazy, v rámci ktorej zmeníme heslo pre roota (pozor, mysql8 má štandardne aktívne dosť prísne požiadavky na zložitosť hesla).
Aby sa nám s DB ľahšie pracovalo môžeme uložiť prihlasovacie údaje do súboru .my.cnf
:
vim /root/.my.cnf
obsah súboru:
[client] user=root password="4T............1I"
Nastavíme oprávnenia pre súbor:
chmod go-rwx .my.cnf
Prihlásime sa do cmd clienta a spustíme SQL príkazy pre vytvorenie databázy a používateľa (nezabudneme na silné heslo):
mysql
SET NAMES 'utf8'; SET CHARACTER SET utf8; CHARSET utf8; CREATE DATABASE IF NOT EXISTS shibboleth CHARACTER SET=utf8; CREATE USER 'shibboleth'@'localhost' IDENTIFIED BY 'jeGYjU....hFf7S'; GRANT ALL ON shibboleth.* TO 'shibboleth'@'localhost'; FLUSH PRIVILEGES;
Vytvoríme novú tabuľku v datábaze shibboleth:
USE shibboleth; CREATE TABLE IF NOT EXISTS `shibpid` ( `localEntity` VARCHAR(255) NOT NULL, `peerEntity` VARCHAR(255) NOT NULL, `principalName` VARCHAR(255) NOT NULL DEFAULT '', `localId` VARCHAR(255) NOT NULL, `persistentId` VARCHAR(50) NOT NULL, `peerProvidedId` VARCHAR(255) DEFAULT NULL, `creationDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `deactivationDate` TIMESTAMP NULL DEFAULT NULL, PRIMARY KEY (localEntity, peerEntity, persistentId) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Doinštalujeme knižnice do Jetty:
http://tux.rainside.sk/apache//commons/dbcp/binaries/commons-dbcp2-2.5.0-bin.tar.gz http://tux.rainside.sk/apache//commons/pool/binaries/commons-pool2-2.6.0-bin.tar.gz https://search.maven.org/remotecontent?filepath=commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.jar https://cdn.mysql.com//Downloads/Connector-J/mysql-connector-java-8.0.13.tar.gz
TODO: Momentalne to bezi so starsimi kniznicami:
https://search.maven.org/remotecontent?filepath=org/apache/commons/commons-dbcp2/2.1.1/commons-dbcp2-2.1.1.jar https://search.maven.org/remotecontent?filepath=org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2.jar
Keďže MySQL je v aktuálnej verzii 8, driver musí byť tieť “najnovší” mysql-connector-java-8.0.13.tar.gz
.
Archívy treba porozbaľovať a potom skopírovať súbory:
cp commons-dbcp2-2.5.0/commons-dbcp2-2.5.0.jar /opt/jetty/lib/ext/ cp commons-pool2-2.6.0/commons-pool2-2.6.0.jar /opt/jetty/lib/ext/ cp commons-logging-api-1.1.jar /opt/jetty/lib/ext/ cp mysql-connector-java-8.0.13/mysql-connector-java-8.0.13.jar /opt/jetty/lib/ext/
chown idp:idp /opt/jetty/lib/ext/*
vim /opt/shibboleth-idp/conf/attribute-resolver.xml
Doplniť nový atribút:
<AttributeDefinition id="eduPersonTargetedID" xsi:type="SAML2NameID" nameIdFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"> <InputDataConnector ref="myStoredId" attributeNames="storedId"/> <AttributeEncoder xsi:type="SAML1XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" encodeType="false"/> <AttributeEncoder xsi:type="SAML2XMLObject" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10" friendlyName="eduPersonTargetedID" encodeType="false"/> </AttributeDefinition>
A nový data konektor:
<DataConnector id="myStoredId" xsi:type="StoredId" sourceAttributeID="uid" generatedAttributeID="storedId" salt="<Zadat vygenerovany SALT>" queryTimeout="0"> <InputAttributeDefinition ref="uid"/> <BeanManagedConnection>shibboleth.MySQLDataSource</BeanManagedConnection> </DataConnector>
Konfiguračný súbor uložíme.
Vygenerujeme salt pomocou príkazu:
openssl rand -base64 36 2>/dev/null
Vystup vyzerá napríklad takto:
LdudV6JOJDzQOaF/4a75mApxsIFf7LVbjdgG3ME3hh7saPJw
Dodefinujeme potrebné beany v global.xml
vim /opt/shibboleth-idp/conf/global.xml
<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="<heslo pre MySQL pouzivatela shibboleth>" /> <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" />
Nový atribút zaradíme aj do konfigurácie filtrov attribute-filter.xml
. Keďže sa jedná o anonymný atribút, môžeme ho sprístupnovať všetkým.
vim /opt/shibboleth-idp/conf/attribute-filter.xml
<AttributeRule attributeID="eduPersonTargetedID"> <PermitValueRule xsi:type="ANY" /> </AttributeRule>
Upravíme súbor saml-nameid.properties
:
vi /opt/shibboleth-idp/conf/saml-nameid.properties
Doplníme potrebné atribúty (odkazy na beany a salt):
idp.persistentId.generator = shibboleth.StoredPersistentIdGenerator idp.persistentId.dataSource = shibboleth.MySQLDataSource idp.persistentId.sourceAttribute = uid idp.persistentId.salt = LdudV6JOJDzQOaF/4a75mApxsIFf7LVbjdgG3ME3hh7saPJw
Ďalej upravíme konfiguráciu v saml-nameid.xml
vim /opt/shibboleth-idp/conf/saml-nameid.xml
V sôbore odkomentujeme tento riadok:
<ref bean="shibboleth.SAML2PersistentGenerator" />
Ďalej upravíme súbor:
vim /opt/shibboleth-idp/conf/idp.properties
V súbore doplníme riadok:
idp.consent.StorageService = shibboleth.JPAStorageService
Ešte ostáva upraviť súbor subject-c14n.xml
:
vim /opt/shibboleth-idp/conf/c14n/subject-c14n.xml
V súbore odkomentujeme riadok:
<ref bean="c14n/SAML2Persistent" />
V metadatach budeme oznamovaž, že IdP podporuje persistentný identifikátor:
vim /opt/shibboleth-idp/metadata/idp-metadata.xml
Do elementu IDPSSODescriptor
pridáme element (napríklad za element <ArtifactResolutionService …>):
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
Vygenerujeme nový WAR súbor a reľtartujeme Jetty:
/opt/shibboleth-idp/bin/build.sh systemctl restart jetty
TODO