Toto je staršia verzia dokumentu!


Inštalácia Shibboleth

IdP budeme inštalovať na Centos 7 podľa návodu uverejneného na https://www.eduid.cz/cs/tech/idp (s príslušnými zmenami).

yum install vim wget unzip ntp

Kvôli správnej funkcionalite IdP je dôležité aby mal server nastavený presný čas. To zabezpečíme spustením služby ntpd.

systemctl enable ntpd
systemctl start ntpd

Po chvíli je možné vidieť zoznam serverov, s ktorými prebieha synchronizácia:

ntpq -p

Aplikácia Shibboleth IdP je napísaná v jazku Java. Na jej spustenie budeme potrebovať Oracle JDK. Najskôr musíme na stránke http://www.oracle.com/technetwork/java/javase/downloads/index.html odkliknúť súhlas s lic. podmienkami Oracle: http://www.oracle.com/technetwork/java/javase/downloads/index.html

Potom stiahneme instalačný balíček (skopírujeme URL z webu - inštalujem JDK 8):

yum install jdk-8u192-linux-x64.rpm

Kontrola, či je Java nainštalovaná správne:

update-alternatives --display java

alebo

java -version

Ak sme inštalovali Javu z RPM od Oracle, JAVA_HOME treba nastaviť na adresár:

/usr/java/latest

Pridáme export JAVA_HOME do ~/.bashrc a ~/.bash_profile

JAVA_HOME=/usr/java/latest
export JAVA_HOME

Kvôli lepším možnostiam šifrovania treba doinštalovať JCE.

JCE stiahneme zo stránky Oracle podobne ako JDK (so súhlasom): http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

Zip archív rozbalime:

unzip -x jce_policy-8.zip

Rozbalené súbory skopírujeme na príslušné miesto do JAVA_HOME:

cp UnlimitedJCEPolicyJDK8/*.jar /usr/java/jdk1.8.0_192-amd64/jre/lib/security/

Ako aplikačný server budeme používať Jetty (podľa odporúčania Shibbloleth).

Server Jetty bude bežať pod neprivilegovaným používateľom (aj ked spúšťať sa bude pod rootom, ale o tom neskôr), ktorého treba vytvoriť:

groupadd idp
useradd -m -g idp -s /bin/bash idp

Stiahneme instalačný balík z webu (napr 9.3): http://central.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.3.25.v20180904/

Rozbalíme balík, presunieme ho do /opt a premenujeme na jetty:

tar -zxvf jetty-distribution-9.3.25.v20180904.tar.gz
mv jetty-distribution-9.3.25.v20180904 /opt/
mv /opt/jetty-distribution-9.3.25.v20180904 /opt/jetty

Zmeníme vlastníka adresára:

chown -R idp:idp /opt/jetty

Vytvoríme konfiguračný súbor v /etc

vim /etc/default/jetty

s obsahom:

JETTY_HOME=/opt/jetty
JETTY_BASE=/opt/jetty

Prepneme sa do používateľa idp a nakonfigurujeme Jetty pre potreby IdP:

su idp
cd /opt/jetty
java -jar /opt/jetty/start.jar --add-to-startd=http,https,logging,deploy,jsp,jstl,plus,servlets,annotations,ext,resources,logging,requestlog,setuid,rewrite

Upravíme konfiguračný súbor http.ini.

vim /opt/jetty/start.d/http.ini

HTTP len pre localhost na porte 80:

--module=http
jetty.http.host=localhost
jetty.http.port=80

HTTPS bude počúvať na štandartnom porte 443:

vim /opt/jetty/start.d/ssl.ini
jetty.ssl.port=443

Kvôli spúšťaniu jetty pod neprivilegovaným používateľom na privilegovanom porte:

vim /opt/jetty/start.d/setuid.ini
# ---------------------------------------
# Module: setuid
--module=setuid

## SetUID Configuration
jetty.setuid.startServerAsPrivileged=false
jetty.setuid.userName=idp
jetty.setuid.groupName=idp
jetty.setuid.umask=002

Vytvoríme domovskú strúnku pre web server (stále pod používateľom idp - obsah stránky podľa uváženia - môže byť aj presmerovanie na inú stránku).

mkdir -p /opt/jetty/webapps/root
vim /opt/jetty/webapps/root/index.html

Pripravíme server pre aplikáciu Shebboleth IdP:

mkdir /opt/jetty/tmp

Vytvoríme konfiguračný súbor aplikácie:

vim /opt/jetty/webapps/idp.xml

s obsahom:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
    <Set name="war">/opt/shibboleth-idp/war/idp.war</Set>
    <Set name="contextPath">/idp</Set>
    <Set name="extractWAR">false</Set>
    <Set name="copyWebDir">false</Set>
    <Set name="copyWebInf">true</Set>
    <Set name="tempDirectory">/opt/jetty/tmp</Set>
</Configure>
vim /opt/jetty/start.d/server.ini

Nebude sa zobrazovať verzia servera:

jetty.httpConfig.sendServerVersion=false

Content-Security-Policy by sme si mali upraviť podľa našich potrieb ale zatiaľ to necháme tak.

vim /opt/jetty/etc/jetty-rewrite.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
 
<Configure id="Server" class="org.eclipse.jetty.server.Server">
 
  <!-- =========================================================== -->
  <!-- configure rewrite handler                                   -->
  <!-- =========================================================== -->
  <Call name="insertHandler">
    <Arg>
      <New class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
        <Set name="rewriteRequestURI"><Property name="jetty.rewrite.rewriteRequestURI" deprecated="rewrite.rewriteRequestURI" default="true"/></Set>
        <Set name="rewritePathInfo"><Property name="jetty.rewrite.rewritePathInfo" deprecated="rewrite.rewritePathInfo" default="false"/></Set>
        <Set name="originalPathAttribute"><Property name="jetty.rewrite.originalPathAttribute" deprecated="rewrite.originalPathAttribute" default="requestedPath"/></Set>
 
 
        <!-- Set DispatcherTypes  -->
        <Set name="dispatcherTypes">
          <Array type="javax.servlet.DispatcherType">
            <Item><Call class="javax.servlet.DispatcherType" name="valueOf"><Arg>REQUEST</Arg></Call></Item>
            <Item><Call class="javax.servlet.DispatcherType" name="valueOf"><Arg>ASYNC</Arg></Call></Item>
          </Array>
        </Set>
 
 
        <Call name="addRule">
          <Arg>
            <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
              <Set name="pattern">*</Set>
              <Set name="name">Strict-Transport-Security</Set>
              <Set name="value">max-age=15768000</Set>
            </New>
          </Arg>
        </Call>
 
        <Call name="addRule">
          <Arg>
            <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
              <Set name="pattern">*</Set>
              <Set name="name">X-Content-Type-Options</Set>
              <Set name="value">nosniff</Set>
            </New>
          </Arg>
        </Call>
 
        <Call name="addRule">
          <Arg>
            <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
              <Set name="pattern">*</Set>
              <Set name="name">X-Xss-Protection</Set>
              <Set name="value">1; mode=block</Set>
            </New>
          </Arg>
        </Call>
 
        <Call name="addRule">
          <Arg>
            <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
              <Set name="pattern">*</Set>
              <Set name="name">X-Frame-Options</Set>
              <Set name="value">DENY</Set>
            </New>
          </Arg>
        </Call>
 
        <Call name="addRule">
          <Arg>
            <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
              <Set name="pattern">*</Set>
              <Set name="name">Content-Security-Policy-Report-Only</Set>
              <Set name="value">default-src 'self'; style-src 'self' https://maxcdn.bootstrapcdn.com; script-src 'self' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src 'self'; font-src https://maxcdn.bootstrapcdn.com; frame-ancestors 'none'</Set>
            </New>
          </Arg>
        </Call>
 
        <Call name="addRule">
          <Arg>
            <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
              <Set name="pattern">*</Set>
              <Set name="name">Referrer-Policy</Set>
              <Set name="value">no-referrer-when-downgrade</Set>
            </New>
          </Arg>
        </Call>
 
      </New>
    </Arg>
  </Call>
</Configure>

Certifikát budem generovať ako root (exit).

Pripravime si SSL certifikát, ktorý budeme potrebovať ďalej.

Vygenerovanie novej žiadosti o cerifikát:

cd /root/ssl_cert
openssl req -new -newkey rsa:2048 -nodes -keyout demoidpkey -out demoidp.csr

Sôbor .csr poslať na podpis (stačí obsah sôboru). Podpísaný certifikát premenujeme na demoidp.crt.

Momentálne by sme mali mať v adresáari /root/ssl_cert tieto certifikáty:

  • demoidp.crt
  • demoidp.csr
  • demoidp.key
  • DigiCertCA.crt

Súbor so žiadosťou demoidp.csr už nebudeme potrebovať.

Certifikáty musíme “zlúčiť” do jedného sôboru:

cat demoidp.crt DigiCertCA.crt > jetty-cert.txt

Vytvorený sôbor prevedieme do formátu PKCS #12. Pri tejto operácii budeme vyzvaný na zadanie hesla. Heslo si zapamätáme (označíme si ho ako Heslo1):

openssl pkcs12 -export -inkey demoidp.key -in jetty-cert.txt -out jetty-cert.pkcs12

Certifikát importujeme do keystore (súbor keystore sa vytvorí v adresári, kde zadávame príkaz - pozor aby boli práva na zápis). Pri vytváraní budeme požiadaný o vytvorenie nového hesla (označíme si ho Heslo2) a zadanie pôvodného hesla k certifikatu (Heslo1).

$JAVA_HOME/bin/keytool -importkeystore -srckeystore jetty-cert.pkcs12 -srcstoretype PKCS12 -destkeystore keystore

Keystore presunieme do /etc a zmeníme mu oprávnenia:

mv keystore /opt/jetty/etc
chown idp:idp /opt/jetty/etc/keystore

Pomocou jetty-util vygenerujeme obsfukované verzie hesiel Heslo1 a Heslo2:

java -cp /opt/jetty/lib/jetty-util-9.3.25.v20180904.jar org.eclipse.jetty.util.security.Password <Heslo2>

Výstupom príkazu bude niečo ako:

2018-12-06 12:28:09.771:INFO::main: Logging initialized @97ms
sKbH...Q5r9Q
OBF:1rxd1f9t1...1l5b1pbe1dv01v2n1f8t1rvh
MD5:b31221...a3b41cbac61f

Podobne treba obsfukovať aj Heslo1

java -cp /opt/jetty/lib/jetty-util-9.3.25.v20180904.jar org.eclipse.jetty.util.security.Password <Heslo1>

Výstupom príkazu bude niečo ako:

2018-12-06 12:30:12.968:INFO::main: Logging initialized @98ms
YAbK...3tRm
OBF:1sa31i7i1vfx...61jlf1e1z1vgx1i8g1sb7
MD5:34cdf9c2...904d366401d6

Obsfukované heslá zadáme do súboru start.d/ssl.ini:

vim /opt/jetty/start.d/ssl.ini

Heslá pre keyStorePassword a trustStorePassword su rovnaké:

jetty.sslContext.keyStorePassword=OBF:1rxd1f9t1v1r...1f8t1rvh        #Heslo2
jetty.sslContext.keyManagerPassword=OBF:1sa31i7i1vfx1...1i8g1sb7     #Heslo1
jetty.sslContext.trustStorePassword=OBF:1rxd1f9t1v1r...1v2n1f8t1rvh  #Heslo2

Zakážeme málo bezpečné šifry:

Vytvoríme súbor /opt/jetty/etc/tweak-ssl.xml

vim /opt/jetty/etc/tweak-ssl.xml

Obsah súboru:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
  <!-- Zakázání starých a nedůvěryhodných šifer -->
  <Call name="addExcludeCipherSuites">
    <Arg>
      <Array type="String">
        <Item>.*DES.*</Item>
        <Item>.*DSS.*</Item>
        <Item>.*MD5.*</Item>
        <Item>.*NULL.*</Item>
        <Item>.*RC4.*</Item>
        <Item>.*_RSA_.*MD5$</Item>
        <Item>.*_RSA_.*SHA$</Item>
        <Item>.*_RSA_.*SHA1$</Item>
        <Item>TLS_DHE_RSA_WITH_AES_128.*</Item>
        <Item>TLS_DHE_RSA_WITH_AES_256.*</Item>
      </Array>
    </Arg>
  </Call>
 
  <!-- Zakázání nedůvěryhodných protokolů -->
  <Call name="addExcludeProtocols">
    <Arg>
     <Array type="java.lang.String">
       <Item>SSL</Item>
       <Item>SSLv2</Item>
       <Item>SSLv2Hello</Item>
       <Item>SSLv3</Item>
     </Array>
    </Arg>
  </Call>
 
  <!-- Povolení Forward Secrecy -->
  <Set name="IncludeCipherSuites">
    <Array type="String">
      <Item>TLS_DHE_RSA.*</Item>
      <Item>TLS_ECDHE.*</Item>
    </Array>
  </Set>
 
</Configure>

Pridáme obsah súboru do konfigurácie https:

echo /opt/jetty/etc/tweak-ssl.xml >> /opt/jetty/start.d/https.ini

Ak sme niekde omylom zle nastavili oprávnenia nastavíme ich znovu:

chown idp:idp -R /opt/jetty

Vytvoríme definíciu služby pre systemd:

Jetty treba spušťať pod rootom a potom keď otvorí port 80 a 443 sa “znížia” jeho oprávnenia na idp. Používateľ idp tie porty nevie otvoriť.

vim /etc/systemd/system/jetty.service
#
# A basic systemd configuration for Jetty to start on boot 
# 
# Uses the Service scenario of 'oneshot' run as root
# and once the process has run, it is considered successful
# regardless of error code (even 'FAILURE') as jetty
# may take longer to start than jetty.sh observes it's logs 
# for.  
#
#

[Unit]
Description=Jetty Web Application Server
After=network.target

[Install]
WantedBy=multi-user.target
Alias=jetty.service
 
[Service]
Type=oneshot

# Execute pre and post scripts as root
PermissionsStartOnly=true

# The process will be considered active after it exits
RemainAfterExit=yes

# Note on the Start we do not wait for successful start.
# This is to allow the container to run beyond the jetty shell script
# in cases where it takes very long to start and results in jetty.sh
# reporting FAILED.  It's a false positive on failure.

ExecStart=-/opt/jetty/bin/jetty.sh start
ExecStop=/opt/jetty/bin/jetty.sh stop
ExecReload=/opt/jetty/bin/jetty.sh restart 
TREBA TO ESTE OTESTOVAT (asi ten unitfile nefunguje)

Povoliť HTTPS na firewalle:

firewall-cmd --zone=public --permanent --add-service=https
firewall-cmd --reload

Spustiť jetty:

systemctl daemon-reload
systemctl enable jetty
systemctl start jetty

Po spustení (chvíľu to trvá) by mala fungovať homepage po nasmerovaní browsera na demoidp.sanet.sk.

Zistenie stavu servera:

/opt/jetty/bin/jetty.sh check

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.39.60/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">
 
    <!-- safeID -->
    <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
  • install-idp.1563826555
  • Posledná úprava: 12. 10. 2020 15:24