Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Obě strany předchozí revize Předchozí verze
Následující verze
Předchozí verze
cs:tech:idp:jetty [2020/03/27 07:51] – [idp.ini] 9ec128d6c1ed31e124c9d0343d1175613f20f405@einfra.cesnet.czcs:tech:idp:jetty [2024/03/27 08:37] (aktuální) Jan Oppolzer
Řádek 1: Řádek 1:
 ====== Jetty ====== ====== Jetty ======
  
-**Na této stránce se nachází návod, jak do linuxové distribuce Debian nainstalovat Jetty jako servlet kontejner a HTTP server pro potřeby Shibboleth IdP. Před instalací musíme zprovoznit [[cs:tech:idp:mariadb]].** +  * [[:cs:tech:idp:5:jetty|Jetty pro Identity Provider 5]] 
- +  * [[:cs:tech:idp:4:jetty|Jetty pro Identity Provider 4]]
----- +
- +
-===== Instalace ===== +
- +
-//Jetty// nainstalujeme následujícím příkazem: +
- +
-<code bash> +
-# Instalace Jetty +
-apt install --no-install-recommends jetty9 +
-</code> +
- +
-Nastavíme proměnnou //JAVA_HOME// pro současnou i budoucí relace: +
- +
-<code bash> +
-# Nastavení proměnné JAVA_HOME +
-eval $(echo "export JAVA_HOME=/usr" | tee -a /root/.bashrc) +
-</code> +
- +
-===== 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 ''/usr/share/jetty9/modules'' si tedy vytvoříme soubor ''idp.mod'' s tímto obsahem: +
- +
-<code> +
-[description] +
-Shibboleth IdP +
- +
-[depend] +
-annotations +
-deploy +
-ext +
-http +
-http2 +
-https +
-jsp +
-jstl +
-plus +
-requestlog +
-resources +
-rewrite +
-server +
-servlets +
-ssl +
- +
-[files] +
-tmp/ +
-</code> +
- +
-Nejsnáze toho dosáhneme stažením již připraveného souboru: +
- +
-<code bash> +
-# Stažení souboru idp.mod +
-wget -P /usr/share/jetty9/modules \ +
-    https://www.eduid.cz/jetty/idp.mod +
-</code> +
- +
-==== 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]]. +
- +
-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''). +
- +
-<code bash> +
-# Spojení koncového a mezilehlého certifikátu  +
-cat cert.pem chain.pem > jetty.txt +
-</code> +
- +
-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!// +
- +
-<code bash> +
-# 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 +
-</code> +
- +
-Pak již zbývá jen do adresáře ''/etc/jetty9'' vygenerovat soubor ''keystore'' s TLS certifikátem, kterému nastavíme práva ''640'' a skupinu ''jetty''. Během generování keystoru budeme dotázáni k dvojnásobnému zadání nového hesla ke keystoru a poté k zadání stávajícího hesla. Ve všech třech případech zadáme heslo, které jsme si vygenerovali pomocí ''openssl'' a poznamenali. +
- +
-<code bash> +
-# Generování keystore +
-keytool -importkeystore -srckeystore jetty.pkcs12 \ +
-    -srcstoretype PKCS12 -destkeystore /etc/jetty9/keystore +
- +
-# Změna práv ke keystoru +
-chmod 640 /etc/jetty9/keystore +
-chgrp jetty /etc/jetty9/keystore +
-</code> +
- +
-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 ''/etc/jetty9/start.d'' si vytvoříme konfigurační soubor ''idp.ini'' s tímto obsahem: +
- +
-<code ini> +
-# ---------------------------------------  +
-# 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 +
-</code> +
- +
-Opět můžeme stáhnout připravený soubor: +
- +
-<code bash> +
-# Stažení souboru idp.ini +
-wget -P /etc/jetty9/start.d \ +
-    https://www.eduid.cz/jetty/idp.ini +
-</code> +
- +
-V souboru ''/etc/jetty9/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'': +
- +
-<code> +
-jetty.sslContext.keyStorePassword=   ___HESLO___ +
-jetty.sslContext.trustStorePassword= ___HESLO___ +
-jetty.sslContext.keyManagerPassword= ___HESLO___ +
-</code> +
- +
-==== tweak-ssl.xml ==== +
- +
-V adresáři ''/etc/jetty9'' si vytvoříme soubor ''tweak-ssl.xml'', v němž definujeme zakázané a povolené šifry a protokoly: +
- +
-<code xml> +
-<?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"> +
-  +
-    <!-- Exclude old and unsafe ciphers --> +
-    <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> +
- +
-    <!-- Exclude old and unsafe protocols --> +
-    <Call name="addExcludeProtocols"> +
-        <Arg> +
-            <Array type="java.lang.String"> +
-                <Item>SSL</Item> +
-                <Item>SSLv2</Item> +
-                <Item>SSLv2Hello</Item> +
-                <Item>SSLv3</Item> +
-            </Array> +
-        </Arg> +
-    </Call> +
- +
-    <!-- Forward Secrecy --> +
-    <Set name="IncludeCipherSuites"> +
-        <Array type="String"> +
-            <Item>TLS_DHE_RSA.*</Item> +
-            <Item>TLS_ECDHE.*</Item> +
-        </Array> +
-    </Set> +
-  +
-</Configure> +
-</code> +
- +
-Opět můžete použít jíž připravený soubor: +
- +
-<code bash> +
-# Stažení souboru tweak-ssl.xml +
-wget -P /etc/jetty9 \ +
-    https://www.eduid.cz/jetty/tweak-ssl.xml +
-</code> +
- +
-==== idp.xml ==== +
- +
-V adresáři ''/var/lib/jetty9/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: +
- +
-<code xml> +
-<?xml version="1.0"?> +
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd"> +
- +
-<Configure class="org.eclipse.jetty.webapp.WebAppContext"> +
-    <Set name="war"><SystemProperty name="idp.war.path" default="/opt/shibboleth-idp/war/idp.war" /></Set> +
-    <Set name="contextPath"><SystemProperty name="idp.context.path" default="/idp" /></Set> +
-    <Set name="extractWAR">false</Set> +
-    <Set name="copyWebDir">false</Set> +
-    <Set name="copyWebInf">true</Set> +
-</Configure> +
-</code> +
- +
-Již připravený soubor si můžete stáhnout: +
- +
-<code bash> +
-# Stažení souboru idp.xml +
-wget -P /var/lib/jetty9/webapps \ +
-    https://www.eduid.cz/jetty/idp.xml +
-</code> +
- +
-==== start.ini ==== +
- +
-Aby si Jetty nestěžovalo, že používat adresář ''start.d/'' i soubor ''start.ini'' najednou je zastaralé, smažeme soubor ''start.ini''. Tento soubor v adresáři ''/usr/share/jetty9'' je pouze symbolickým odkazem, takže smažeme i soubor, kam tento odkaz směruje: +
- +
-<code bash> +
-# Smazání souboru a symbolického odkazu start.ini +
-rm /usr/share/jetty9/start.ini /etc/jetty9/start.ini +
-</code> +
- +
-==== index.jsp ==== +
- +
-V adresáři ''/var/lib/jetty9/webapps/root'' vymažeme výchozí stránky 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!** +
- +
-<code bash> +
-# Smazání statického webu v Jetty +
-rm /var/lib/jetty9/webapps/root/+
- +
-# Vytvoření přesměrování na domovskou stránku +
-echo '<% response.sendRedirect("https://www.example.org"); %>' > \ +
-    /var/lib/jetty9/webapps/root/index.jsp +
-</code> +
- +
-==== Knihovny ==== +
- +
-Jetty potřebuje pro správnou funkčnost tyto ctyři JAR soubory, které je nutné umístit do složky s externími knihovnami ''/usr/share/jetty9/lib/ext'': +
- +
-  * commons-dbcp2-2.1.1.jar ([[https://search.maven.org/remotecontent?filepath=org/apache/commons/commons-dbcp2/2.1.1/commons-dbcp2-2.1.1.jar|JAR ke stažení]], [[https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi|stránka]]) +
-  * commons-pool2-2.4.2.jar ([[https://search.maven.org/remotecontent?filepath=org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2.jar|JAR ke stažení]], [[https://commons.apache.org/proper/commons-pool/download_pool.cgi|stránka]]) +
-  * commons-logging-api-1.1.jar ([[https://search.maven.org/remotecontent?filepath=commons-logging/commons-logging-api/1.1/commons-logging-api-1.1.jar|JAR ke stažení]]), +
-  * mariadb-java-client.jar (JDBC ovladač pro MariaDB). +
- +
-Po stažení prvních tří souborů uvedených výše je umístíme na server do adresáře ''/opt'' a provedeme instalaci následující sérií příkazů. Čtvrtý soubor vyřešíme následně. +
- +
-=== Apache Commons DBCP & Pool === +
- +
-<code bash> +
-# Přesunutí Apache Commons DBCP2 a Pool2 JAR souborů do Jetty: +
-cd /opt +
-mv commons-dbcp2-2.1.1.jar \ +
-   commons-pool2-2.4.2.jar \ +
-   commons-logging-api-1.1.jar \ +
-   /usr/share/jetty9/lib/ext +
-</code> +
- +
-=== JDBC pro MariaDB === +
- +
-JDBC pro MariaDB jsme nainstalovali v [[mariadb|předchozím krkou]] instalací balíčku ''libmariadb-java'', nyní zbývá vytvořit symbolický odkaz v adresáři s externími knihovnami pro Jetty. +
- +
-<code bash> +
-# Vytvoření symbolického odkazu na JDBC +
-ln -s /usr/share/java/mariadb-java-client.jar \ +
-      /usr/share/jetty9/lib/ext/mariadb-java-client.jar +
-</code> +
- +
-===== 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 ''/etc/jetty9'' smažte původní soubor ''jetty-rewrite.xml'' a nahraďte jej novým s následujícím obsahem: +
- +
-<WRAP important 100%> +
-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.// +
-</WRAP> +
- +
-<code 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"> +
- +
-    <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 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> +
- +
-                <!-- Strict-Transport-Security --> +
-                <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> +
- +
-                <!-- X-Content-Type-Options --> +
-                <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> +
- +
-                <!-- X-Xss-Protection --> +
-                <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> +
- +
-                <!-- X-Frame-Options --> +
-                <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> +
- +
-                <!-- Content-Security-Policy --> +
-                <Call name="addRule"> +
-                    <Arg> +
-                        <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"> +
-                            <Set name="pattern">*</Set> +
-                            <Set name="name">Content-Security-Policy</Set> +
-                            <Set name="value">default-src 'self'; style-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self'; frame-ancestors 'none'</Set> +
-                        </New> +
-                    </Arg> +
-                </Call> +
- +
-                <!-- Referrer-Policy --> +
-                <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> +
-</code> +
- +
-Jako v předchozích případech, i tento soubor je již připravený a můžete si ho stánout: +
- +
-<code bash> +
-# Přepsání původního souboru jetty-rewrite.xml novým +
-wget -O /etc/jetty9/jetty-rewrite.xml \ +
-    https://www.eduid.cz/jetty/jetty-rewrite.xml +
-</code> +
- +
-===== Restart ===== +
- +
-Konfigurace je hotová, čili můžeme Jetty restartovat: +
- +
-<code bash> +
-# Restartování Jetty +
-systemctl restart jetty9 +
-</code> +
- +
-Přesvědčíme se, že vše funguje: +
- +
-<code bash> +
-# Kontrola síťových spojení +
-ss -tlpn fgrep java +
-</code> +
- +
-Měli bychom vidět, že port ''80'' poslouchá pouze na adrese ''127.0.0.1'' a port ''443'' na všech adresách: +
- +
-<code bash> +
-# 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))                                                +
-</code> +
- +
-Vyzkoušíme, jestli funguje přesměrování na domovskou stránku naší organizace: +
- +
-<code bash> +
-# Vyzkoušení přesměrování +
-wget -S -O/dev/null http://localhost +
-wget -S -O/dev/null https://`hostname -f` +
-</code> +
- +
----- +
- +
-**Máme-li nainstalováno Jetty, můžete pokračovat instalací [[cs:tech:idp:shibboleth]].** +