====== 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 [[mariadb]].** ---- ===== Instalace ===== //Jetty// nainstalujeme následujícím příkazem: # Instalace Jetty apt install --no-install-recommends jetty9 Nastavíme proměnnou //JAVA_HOME// pro současnou i budoucí relace: # Nastavení proměnné JAVA_HOME eval $(echo "export JAVA_HOME=/usr" | tee -a /root/.bashrc) ===== 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: [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 /usr/share/jetty9/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 pro Jetty. 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 /etc/jetty9/keystore Pak již zbývá jen nastavit práva ''640'' a skupinu ''jetty''. # Změna práv ke keystoru chmod 640 /etc/jetty9/keystore chgrp jetty /etc/jetty9/keystore 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: # --------------------------------------- # 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 is PKCS#12 formatted jetty.sslContext.trustStoreType=PKCS12 # 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 /etc/jetty9/start.d \ https://www.eduid.cz/jetty/idp.ini # Otevřeme konfigurační soubor idp.ini vim /etc/jetty9/start.d/idp.ini 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'': jetty.sslContext.keyStorePassword= ___HESLO___ jetty.sslContext.trustStorePassword= ___HESLO___ jetty.sslContext.keyManagerPassword= ___HESLO___ ==== 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: .*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 /etc/jetty9 \ https://www.eduid.cz/jetty/tweak-ssl.xml ==== 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: false false true Již připravený soubor si můžete stáhnout: # Stažení souboru idp.xml wget -P /var/lib/jetty9/webapps \ https://www.eduid.cz/jetty/idp.xml ==== 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: # Smazání souboru a symbolického odkazu start.ini rm /usr/share/jetty9/start.ini /etc/jetty9/start.ini ==== 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!** # 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 ==== Knihovny ==== Shibboleth IdP 4.0.0 bez viditelných oznámení — podobně jako řada 3 od verze 3.4.0 — 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 ''/usr/share/jetty9/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í. JDBC pro MariaDB jsme nainstalovali v [[mariadb|předchozím kroku]] instalací balíčku ''libmariadb-java''. # 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 ===== 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: 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 /etc/jetty9/jetty-rewrite.xml \ https://www.eduid.cz/jetty/jetty-rewrite.xml ===== Restart ===== Konfigurace je hotová, čili můžeme Jetty restartovat: # Restartování Jetty systemctl restart jetty9 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` ---- **Máme-li nainstalováno Jetty, můžete pokračovat instalací [[shibboleth]].**