====== Aktualizace na Shibboleth IdP 5 ====== Na této stránce se nachází návod, jak aktualizovat Shibboleth IdP řady 4 na řadu 5. **Důrazně doporučuji před aktualizací zálohovat databázi i konfigurace samotného Shibboleth IdP a Jetty a pročíst poznámky k vydání (ChangeLog)!** [[cs:tech:idp:4|Předešlý návod pro IdP řady 4]] i [[..|tento návod]] pro aktualizaci IdP na řadu 5 počítá se skutečností, že //IdP běží na Debianu 11 (Bullseye) a používá Jetty 9.4.39 z distribučních balíčků Debianu//. V případě použití staší verze systému anebo nepoužívání Jetty z balíčků distribuce, je vhodné nejprve aktualizovat systém a/nebo Jetty. V takovém případě se může hodit návod na tzv. [[..:..:shibboleth:migration|online migraci]]. Provozování Shibboleth IdP na jiném operačním systému anebo v jiném kontejneru (např. Tomcat) není z naší strany podporováno. Pokud provozujeme Shibboleth IdP řady 4 dle návodů na webu [[:cs:index|eduID.cz]], pak je aktualizace na novou řadu 5 otázka čtyř kroků: - Aktualizovat na poslední verzi Shibboleth IdP řady 4. - Odinstalovat Jetty 9. - Nainstalovat Jetty verze 11. - Aktualizovat Shibboleth IdP na verzi 5.0.0. ===== Aktualizace na Shibboleth IdP 4.3.1 ===== Abychom mohli nejsnazším způsobem [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199500925/Upgrading|aktualizovat na Shibboleth IdP řady 5]], musíme nejprve [[https://wiki.shibboleth.net/confluence/display/IDP4/Upgrading|aktualizovat na poslední verzi řady 4]], kterou je ke dni 9. 1. 2024 verze 4.3.1. Začneme tím, že si pečlivě přečteme [[https://wiki.shibboleth.net/confluence/display/IDP4/ReleaseNotes|poznámky k vydání]]. Následně [[https://shibboleth.net/downloads/identity-provider/4.3.1/|ze stránky projektu]] stáhneme zdrojové kódy a umístíme je do adresáře ''/opt'' např. pomocí programu //wget// následujícím způsobem. Nezapomeneme ověřit SHA256 otisk a případně i GPG podpis. # Stažení zdrojového kódu Shibboleth IdP wget -P /opt \ https://shibboleth.net/downloads/identity-provider/4.3.1/shibboleth-identity-provider-4.3.1.tar.gz \ https://shibboleth.net/downloads/identity-provider/4.3.1/shibboleth-identity-provider-4.3.1.tar.gz.asc \ https://shibboleth.net/downloads/identity-provider/4.3.1/shibboleth-identity-provider-4.3.1.tar.gz.sha256 Nyní přistoupíme k samotné instalaci. # Instalace Shibboleth IdP cd /opt tar -xzf shibboleth-identity-provider-4.3.1.tar.gz cd shibboleth-identity-provider-4.3.1/ ./bin/install.sh Během instalace potvrdíme pouze zdrojový a cílový adresář, průběh vypadá následovně: Buildfile: /opt/shibboleth-identity-provider-4.3.1/bin/build.xml install: Source (Distribution) Directory (press to accept default): [/opt/shibboleth-identity-provider-4.3.1] ? Installation Directory: [/opt/shibboleth-idp] ? INFO [net.shibboleth.idp.installer.V4Install:155] - Update from version 4.0.1 to version 4.3.1 INFO [net.shibboleth.idp.installer.BuildWar:71] - Rebuilding /opt/shibboleth-idp/war/idp.war, Version 4.3.1 INFO [net.shibboleth.idp.installer.BuildWar:80] - Initial populate from /opt/shibboleth-idp/dist/webapp to /opt/shibboleth-idp/webpapp.tmp INFO [net.shibboleth.idp.installer.BuildWar:89] - Overlay from /opt/shibboleth-idp/edit-webapp to /opt/shibboleth-idp/webpapp.tmp INFO [net.shibboleth.idp.installer.BuildWar:94] - Creating war file /opt/shibboleth-idp/war/idp.war BUILD SUCCESSFUL Total time: 6 seconds Nyní restartujeme Jetty: # Restart Jetty systemctl restart jetty9 Aktualizace Shibboleth IdP na verzi 4.3.1 je hotova. ===== Odinstalování Jetty 9 ===== Odstranit Jetty verze 9 je triviální a postačí k tomu následující použití příkazu ''apt'': # Odstranění balíčku jetty9 apt remove jetty9 ===== Instalace Jetty 11 ===== Nejdříve potřebujeme nainstalovat Javu 17: # Instalace Javy 17 apt install openjdk-17-jre Jelikož //Jetty11// není součástí balíčků Debianu, stáhneme následující soubory ze stránek projektu: # Stažení Jetty11 wget -P /opt \ https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/11.0.16/jetty-home-11.0.16.tar.gz \ https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/11.0.16/jetty-home-11.0.16.tar.gz.asc \ https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/11.0.16/jetty-home-11.0.16.tar.gz.sha1 # Přepnutí do adresáře /opt cd /opt # Kontrola SHA1 otisku echo -e '\t jetty-home-11.0.16.tar.gz' >> jetty-home-11.0.16.tar.gz.sha1 sha1sum -c jetty-home-11.0.16.tar.gz.sha1 # Kontrola GPG podpisu gpg --verify jetty-home-11.0.16.tar.gz.asc # Extrakce archivu s jetty11 tar -xzf jetty-home-11.0.16.tar.gz # Přesunutí adresáře s jetty11 mv jetty-home-11.0.16 jetty11 # Vytvoření adresáře se základem jetty11-idp mkdir -p /opt/jetty11-idp/etc ==== Konfigurace ==== Nakonfigurovat Jetty pro běh Shibboleth IdP je velice triviální, protože stačí stáhnout již připravené konfigurační soubory a pouze v některých z nich udělat drobné změny. === idp.mod === Vytvoříme si v Jetty tzv. modul pro Shibboleth IdP, který obsahuje veškeré závislosti, jež budou pro běh IdP vyžadovány. V adresáři ''/opt/jetty11/modules'' si tedy vytvoříme soubor ''idp.mod'' s tímto obsahem: [description] Shibboleth IdP [depend] annotations deploy ext http http2 https jsp jstl plus requestlog resources rewrite server servlets ssl [files] tmp/ Nejsnáze toho dosáhneme stažením již připraveného souboru: # Stažení souboru idp.mod wget -P /opt/jetty11/modules \ https://www.eduid.cz/jetty/idp.mod === keystore === Pro šifrovanou komunikaci bude IdP využívat TLS certifikát. Ten je možné získat na službě [[https://tcs.cesnet.cz|TCS CESNET]]. //V případě, že nemáte ke službě TCS přístup, můžete využít zdarma certifikát od [[https://letsencrypt.org|Let's Encrypt]] anebo si zakoupit certifikát u libovolné důvěryhodné certifikační autority.// Získaný certifikát (zde označený jako ''cert.pem'') musíme nejprve doplnit o mezilehlý certifikát **vyjma kořenového certifikátu** (zde označený ''chain.pem''). # Spojení koncového a mezilehlého certifikátu cat cert.pem chain.pem > jetty.txt Následně si certifikát (''jetty.txt'') a privátní klíč (''key.pem'') převedeme do formátu PKCS#12. Nejprve zadáme heslo k privátnímu klíči (''key.pem'') a následně dvakrát úplně nové heslo, které si vygenerujeme pomocí ''openssl'' //a poznamenáme!// # Generování nového hesla openssl rand -hex 20 # Převod certifikátu do formátu PKCS#12 openssl pkcs12 -export -inkey key.pem -in jetty.txt -out jetty.pkcs12 Pak již zbývá jen do adresáře ''/opt/jetty11-idp/etc'' nakopírovat soubor ''jetty.pkcs12'' a přejmenovat ho na ''keystore.p12'' s TLS certifikátem, kterému nastavíme práva ''640'' a skupinu ''jetty''. # Přesunutí souboru keystore.12 mv jetty.pkcs12 /opt/jetty11-idp/etc/keystore.p12 # Vytvoření uživatele jetty useradd -s /bin/false -d /opt/jetty11 jetty # Změna práv ke keystoru chmod 640 /opt/jetty11-idp/etc/keystore.p12 chgrp jetty /opt/jetty11-idp/etc/keystore.p12 Heslo, které jsme si vygenerovali pomocí příkazu ''openssl'' a použili ho, následně použijeme v dalším kroku, kde heslo vložíme do konfiguračního souboru ''idp.ini''. === idp.ini === V adresáři ''/opt/jetty11-idp/start.d'' si vytvoříme konfigurační soubor ''idp.ini'' s tímto obsahem: # --------------------------------------- # Module: idp # Shibboleth IdP # --------------------------------------- --module=idp # Allows setting Java system properties (-Dname=value) # and JVM flags (-X, -XX) in this file --exec # Newer garbage collector that reduces memory needed for larger metadata files -XX:+UseG1GC # Maximum amount of memory that Jetty may use -Xmx1500m # Keystore password jetty.sslContext.keyStorePassword=FIXME # Truststore password jetty.sslContext.trustStorePassword=FIXME # KeyManager password jetty.sslContext.keyManagerPassword=FIXME # HTTP jetty.http.host=127.0.0.1 jetty.http.port=80 # HTTPS jetty.ssl.host=0.0.0.0 jetty.ssl.port=443 # Disable SSL renegotiation jetty.sslContext.renegotiationAllowed=false # Hide Jetty version jetty.httpConfig.sendServerVersion=false etc/tweak-ssl.xml Opět můžeme stáhnout připravený soubor, tentokrát ho však budeme muset upravit: # Stažení souboru idp.ini wget -P /opt/jetty11-idp/start.d \ https://www.eduid.cz/jetty/idp.ini # Otevřeme konfigurační soubor idp.ini vim /opt/jetty11-idp/start.d/idp.ini V souboru ''/etc/jetty11-idp/start.d/idp.ini'' nyní musíme nastavit ještě následující hesla na hodnotu vygenerovanou v předchozím kroku pomocí příkazu ''openssl'': jetty.sslContext.keyStorePassword= ___HESLO___ jetty.sslContext.trustStorePassword= ___HESLO___ jetty.sslContext.keyManagerPassword= ___HESLO___ === tweak-ssl.xml === V adresáři ''/opt/jetty11-idp'' si vytvoříme soubor ''tweak-ssl.xml'', v němž definujeme zakázané a povolené šifry a protokoly: .*DES.* .*DSS.* .*MD5.* .*NULL.* .*RC4.* .*_RSA_.*MD5$ .*_RSA_.*SHA$ .*_RSA_.*SHA1$ TLS_DHE_RSA_WITH_AES_128.* TLS_DHE_RSA_WITH_AES_256.* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 SSL SSLv2 SSLv2Hello SSLv3 TLS_ECDHE.* Opět můžete použít jíž připravený soubor: # Stažení souboru tweak-ssl.xml wget -P /opt/jetty11-idp/etc \ https://www.eduid.cz/jetty/tweak-ssl.xml === idp.xml === V adresáři ''/opt/jetty11-idp/webapps'' si vytvoříme konfigurační soubor, který zajistí, že v kontejneru Jetty poběží Shibboleth IdP. Soubor s názvem ''idp.xml'' bude mít tento obsah: false false true Již připravený soubor si můžete stáhnout: # Stažení souboru idp.xml wget -P /opt/jetty11-idp/webapps \ https://www.eduid.cz/jetty/idp.xml === index.jsp === Vytvoříme adresář ''/opt/jetty11-idp/webapps/root'' a následně do souboru ''index.jsp'' umístíme přesměrování na stránku naší domovské organizace. **Změňte ''www.example.org'' na domovskou adresu své organizace!** # Vytvoření složky statického webu v Jetty mkdir /opt/jetty11-idp/webapps/root # Vytvoření přesměrování na domovskou stránku echo '<% response.sendRedirect("https://www.example.org"); %>' > \ /opt/jetty11-idp/webapps/root/index.jsp ==== Knihovny ==== Shibboleth IdP 5.0.0 bez viditelných oznámení — podobně jako řada 4 — obsahuje //commons-dbcp2.jar// a //commons-pool2.jar//, takže není nutné tyto knihovny dodávat do Jetty. Jetty potřebuje pro správnou funkčnost do složky s externími knihovnami ''/opt/jetty11/lib/ext'' nalinkovat pouze //mariadb-java-client.jar//, což je JDBC konektor do databáze MariaDB, kam se ukládají persistentní identifikátory uživatelů a souhlasy s uvolněním osobních informací. # Vytvoření složky lib/ext mkdir -p /opt/jetty11-idp/lib/ext # Vytvoření symbolického odkazu na JDBC ln -s /usr/share/java/mariadb-java-client.jar \ /opt/jetty11-idp/lib/ext/mariadb-java-client.jar ==== Bezpečnost ==== Tento krok není pro běh IdP nutný, ale je velice vhodný pro zvýšení bezpečnosti uživatelů, kteří budou do přihlašovací stránky na IdP zadávat svá uživatelská jména a hesla. === jetty-rewrite.xml === V adresáři ''/opt/jetty11-idp/etc/jetty11'' smažte původní soubor ''jetty-rewrite.xml'' a nahraďte jej novým s následujícím obsahem: Zkontrolujte si zejména **Content-Security-Policy** hlavičku! Pokud se v prohlížeči na IdP nenačtou např. styly nebo obrázky, je to chybějícími záznamy právě v Content-Security-Policy hlavičce. Pokud byste např. chtěli povolit načítání obrázků ze všech [šifrovaných] URL adres (a ne jenom z URL adresy serveru s IdP, čili //'self'//), pak musíte upravit //img-src// následovně: ''img-src: 'self' https:''. Používáte-li pro obrázky formát SVG, který v sobě obsahuje definici kaskádových stylů, nezapomeňte do //style-src// přidat ještě hodnotu //'unsafe-inline'//, jinak se styly na SVG obrázek neaplikují. Výsledná definice pro styly tedy bude muset vypadat takto: ''style-src 'unsafe-inline' 'self'.'' //I přes tyto počáteční problémy se však toto bezpečnostní opatření vyplatí, protože webový prohlížeč odmítne uživatelům načíst podstrčené soubory, pokud by se to útočníkovi nějak povedlo.// **Budete-li používat výchozí přihlašovací stránku IdP, budete mít s těmito pravidly drobný zádrhel. Výchozí přihlašovací stránka zobrazuje loga služeb. Pokud však v //img-src// nebudete mít ''https:'', loga se vám na přihlašovací stránce zobrazovat nebudou. A to nevypadá moc hezky. Zvažte tedy úpravu souboru ''views/login.vm'', anebo povolte načítání __všech__ obrázků po protokolu //https//.** REQUEST ASYNC * Strict-Transport-Security max-age=15768000 * X-Content-Type-Options nosniff * X-Xss-Protection 1; mode=block * X-Frame-Options DENY * Content-Security-Policy default-src 'self'; style-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self'; frame-ancestors 'none' * Referrer-Policy no-referrer-when-downgrade Jako v předchozích případech, i tento soubor je již připravený a můžete si ho stánout: # Přepsání původního souboru jetty-rewrite.xml novým wget -O /opt/jetty11-idp/etc/jetty-rewrite.xml \ https://www.eduid.cz/jetty/jetty11-rewrite.xml ==== systemd ==== Vytvoříme soubor služby jetty11 pomocí následující příkazu: # Vytvoření služby jetty11 pro systemd systemctl edit --full --force jetty11.service Po překopírování níže uvedeného obsahu soubor **uložíme**: [Unit] Description=Jetty 11 Web Application Server After=syslog.target network.target remote-fs.target nss-lookup.target [Service] AmbientCapabilities=CAP_NET_BIND_SERVICE # Configuration Environment="JETTY_HOME=/opt/jetty11" Environment="JETTY_STATE=/opt/jetty11-idp/jetty11/jetty.state" Environment="JETTY_RUN=/opt/jetty11-idp/jetty11" Environment="JAVA_OPTS=-Djava.awt.headless=true" EnvironmentFile=-/opt/jetty11/default/jetty11 # Security User=jetty Group=jetty PrivateTmp=yes NoNewPrivileges=true WorkingDirectory=/opt/jetty11-idp/ LogsDirectory=jetty11 LogsDirectoryMode=750 ProtectSystem=strict ReadWritePaths=/opt/jetty11-idp/logs/ ReadWritePaths=/opt/jetty11-idp/jetty11/ TimeoutSec=infinity # Lifecycle Type=forking ExecStart=/opt/jetty11/bin/jetty.sh start PIDFile=/opt/jetty11-idp/jetty11/jetty.pid SuccessExitStatus=143 Restart=on-abort # Logging SyslogIdentifier=jetty11 [Install] WantedBy=multi-user.target Dále si ještě vytvoříme pracovní adresáře a stavový soubor pro Jetty: # Vytvoření složek pro jetty11 mkdir /opt/jetty11-idp/{jetty11,logs} # Upravení práv složek chown jetty /opt/jetty11-idp/{jetty11,logs} # Vytvoření souboru stavu jetty touch /opt/jetty11-idp/jetty11/jetty.state chown jetty:jetty /opt/jetty11-idp/jetty11/jetty.state V systemd musíme Jetty povolit přístup pro zápis do adresářů s logy a metadaty. # Úprava služby jetty11 v systemd systemctl edit jetty11 Nastavení práv pro záspis do adresářů ''/opt/shibboleth-idp/{logs,metadata}'': [Service] ReadWritePaths=/opt/shibboleth-idp/logs/ ReadWritePaths=/opt/shibboleth-idp/metadata/ ==== Modul rewrite ==== Před samotným spuštěním Jetty, přidáme a povolíme modul //rewrite// pomocí následujícího příkazu: export JETTY_HOME=/opt/jetty11 export JETTY_BASE=/opt/jetty11-idp cd $JETTY_HOME java -jar start.jar --add-modules=rewrite ==== Restart ==== Konfigurace je hotová, čili můžeme Jetty spouštět po startu operačního systému a zároveň restartovat: # Spouštět Jetty po startu operačního systému systemctl enable jetty11 # Restartování Jetty systemctl restart jetty11 Přesvědčíme se, že vše funguje: # Kontrola síťových spojení ss -tlpn | fgrep java Měli bychom vidět, že port ''80'' poslouchá pouze na adrese ''127.0.0.1'' a port ''443'' na všech adresách: # Kontrola síťových spojení LISTEN 0 50 [::ffff:127.0.0.1]:80 *:* users:(("java",pid=15630,fd=61)) LISTEN 0 50 *:443 *:* users:(("java",pid=15630,fd=55)) Vyzkoušíme, jestli funguje přesměrování na domovskou stránku naší organizace: # Vyzkoušení přesměrování wget -S -O/dev/null http://localhost wget -S -O/dev/null https://`hostname -f` ===== Aktualizace na Shibboleth IdP 5.0.0 ===== Před aktualizací na V5.0.0 si pečlivě přečteme [[https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199500367/ReleaseNotes|poznámky k vydání]]. Následně [[https://shibboleth.net/downloads/identity-provider/5.0.0/|ze stránky projektu]] stáhneme zdrojové kódy a umístíme je do adresáře ''/opt'' např. pomocí programu //wget// následujícím způsobem. Nezapomeneme ověřit SHA256 otisk a případně i GPG podpis. # Stažení zdrojového kódu Shibboleth IdP wget -P /opt \ https://shibboleth.net/downloads/identity-provider/5.0.0/shibboleth-identity-provider-5.0.0.tar.gz \ https://shibboleth.net/downloads/identity-provider/5.0.0/shibboleth-identity-provider-5.0.0.tar.gz.asc \ https://shibboleth.net/downloads/identity-provider/5.0.0/shibboleth-identity-provider-5.0.0.tar.gz.sha256 Nyní přistoupíme k samotné instalaci. # Instalace Shibboleth IdP cd /opt tar -xzf shibboleth-identity-provider-5.0.0.tar.gz cd shibboleth-identity-provider-5.0.0/ ./bin/install.sh Během instalace potvrdíme pouze zdrojový a cílový adresář, průběh vypadá následovně: Installation Directory: [/opt/shibboleth-idp] ? INFO [net.shibboleth.idp.installer.V4Install:155] - Update from version 4.3.1 to version 5.0.0 INFO [net.shibboleth.idp.installer.BuildWar:71] - Rebuilding /opt/shibboleth-idp/war/idp.war, Version 5.0.0 INFO [net.shibboleth.idp.installer.BuildWar:80] - Initial populate from /opt/shibboleth-idp/dist/webapp to /opt/shibboleth-idp/webpapp.tmp INFO [net.shibboleth.idp.installer.BuildWar:89] - Overlay from /opt/shibboleth-idp/edit-webapp to /opt/shibboleth-idp/webpapp.tmp INFO [net.shibboleth.idp.installer.BuildWar:94] - Creating war file /opt/shibboleth-idp/war/idp.war Ještě zbývá doinstalovat jdbc a nashorn pluginy shibbolethu IdP. Obě dvě instalace potvrdíme y. /opt/shibboleth-idp/bin/plugin.sh -I net.shibboleth.plugin.storage.jdbc /opt/shibboleth-idp/bin/plugin.sh -I net.shibboleth.idp.plugin.nashorn ==== global.xml ==== Nyní je potřeba v souboru ''global.xml'' definovat některé "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). **Staré beany zakomentujeme nebo smažeme.** # Úpravy v konfiguračním souboru global.xml vim /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//. Nakonec je třeba u mariaDB změnit tzv. collation u sloupců primárních klíčů v DB shibboleth.StorageRecords mysql USE shibboleth; alter table StorageRecords modify context varchar(255) character set utf8mb4 collate utf8mb4_bin; alter table StorageRecords modify id varchar(255) character set utf8mb4 collate utf8mb4_bin; Nyní restartujeme Jetty: # Restart Jetty systemctl restart jetty11 Aktualizace na V5.0.0 je hotová.