Migrace Jetty na Shibboleth plugin
Na této stránce se nachází návod, jak migrovat z Jetty instalovaného ze zdrojových kódů na Jetty Base Plugin od Shibbolethu. Plugin zjednodušuje správu verzí Jetty pomocí symbolických odkazů a poskytuje předpřipravenou konfigurační strukturu pro provoz Shibboleth IdP.
Příprava
Předpokládáme, že při instalaci Jetty ze zdrojových kódů jste postupovali dle našeho návodu Jetty.
Zastavíme původní službu jetty.service a smažeme ji:
# Zastavíme Jetty systemctl stop jetty.service # Smažeme jetty.service a override.conf rm /etc/systemd/system/jetty.service /etc/systemd/system/jetty.service.d/override.conf
Instalace
Vývojáři z Konsorcia Shibboleth zjednodušili provoz Shibbolethu, pokud se rozhodnete používat jimi doporučený webový server Jetty. Nyní se Jetty instaluje pomocí skriptů dodaných Shibbolehtem. Pro tzv. JettyBasePluginu je nutný Shibboleth IdP verze alespoň 5.1.
# Přepnutí do adresáře /opt/shibboleth-idp cd /opt/shibboleth-idp # Instalace pluginu Jetty ./bin/plugin.sh -I net.shibboleth.idp.plugin.jetty # Stažení Jetty verze 12.1.6 ./bin/downloadjetty.sh 12.1.6 # Použití Jetty verze 12.1.6 ./bin/setjettyversion.sh 12.1.6 # Nastavení Jetty na major verzi 12 (pro konfiguraci) ./bin/setjettybase.sh 12
Tím je instalace hotová a přesuneme se ke konfiguraci.
Konfigurace
Konfigurace Jetty pro běh Shibboleth IdP je velice přímočará – stačí stáhnout již připravené konfigurační soubory a v některých z nich provést drobné změny.
Keystore
Pro jednoduchost použijeme stávající keystore.
cp /opt/jetty-idp/etc/keystore.p12 /opt/shibboleth-idp/credentials/idp-userfacing.p12 chown jetty /opt/shibboleth-idp/credentials/idp-userfacing.p12 chmod 600 /opt/shibboleth-idp/credentials/idp-userfacing.p12
shibboleth.ini
Konfigurační soubor /opt/shibboleth-idp/jetty-base/start.d/shibboleth.ini je víceméně připravený, stačí v něm provést několik změn:
jetty.ssl.host=0.0.0.0z původní hodnoty127.0.0.1,jetty.ssl.port=443z původní hodnoty8443,jetty.http.port=80z původní hodnoty8080,jetty.sslContext.keyStorePassword=heslo z předchozího kroku, když jste generovali keystore,jetty.sslContext.trustStorePassword=heslo z předchozího kroku, když jste generovali keystore,jetty.sslContext.keyManagerPassword=heslo z předchozího kroku, když jste generovali keystore,jetty.httpConfig.sendServerVersion=falsetento řádek ve výchozí konfiguraci chybí,etc/tweak-ssl.xmltento řádek ve výchozí konfiguraci chybí.
- shibboleth.ini
# Setup common for running an IdP or a Hub (for SP4) # Enable our "comprehensive" module --module=shibboleth # Route access logging through standard SLF4J logging API etc/jetty-requestlog.xml # Do not expose contexts to web. jetty.server.default.showContexts=false ################################## ## Network/Host/Port configuration ################################## ## TLS host and port to bind to jetty.ssl.host=0.0.0.0 jetty.ssl.port=443 # Non-TLS host and port to bind to jetty.http.host=127.0.0.1 jetty.http.port=80 ###################################### ## Keystore properties for TLS support ###################################### # Keystore file path (relative to $jetty.base) jetty.sslContext.keyStorePath=../credentials/idp-userfacing.p12 jetty.sslContext.trustStorePath=../credentials/idp-userfacing.p12 # Keystore type #jetty.sslContext.keyStoreType=PKCS12 #jetty.sslContext.trustStoreType=PKCS12 # Keystore passwords jetty.sslContext.keyStorePassword=changeit jetty.sslContext.trustStorePassword=changeit jetty.sslContext.keyManagerPassword=changeit # Deny SSL renegotiation jetty.sslContext.renegotiationAllowed=false # Skip SNI hostcheck jetty.ssl.sniHostCheck=false # Suppress node name in JSESSIONID values # This assumes a non-clustered Jetty deploy jetty.sessionIdManager.workerName= jetty.httpConfig.sendServerVersion=false etc/tweak-ssl.xml
Předpřipravený soubor shibboleth.ini pro Jetty můžete stáhnout od nás.
# Stažení připraveného souboru shibboleth.ini wget -O /opt/shibboleth-idp/jetty-base/start.d/shibboleth.ini \ 'https://www.eduid.cz/_export/code/cs/tech/idp/5/shibboleth-new?codeblock=3'
shibboleth.mod
Do souboru /opt/shibboleth-idp/jetty-base/modules/shibboleth.mod přidáme podporu pro HTTP2 a modul rewrite starající se o posílání dodatečných hlaviček definovaných v jetty-rewrite-rules.xml níže.
- shibboleth.mod
[description] Configure Jetty for use as a Shibboleth IdP and/or SP Hub container. [tags] shibboleth [depend] ee11-annotations ee11-deploy ee11-jsp ee11-jstl ee11-plus ee11-servlets ee11-webapp resources server ext http https ssl rewrite http2 [files] tmp/
Hotový soubor shibboleth.mod můžete stáhnout od nás.
# Stažení připraveného souboru shibboleth.mod wget -O /opt/shibboleth-idp/jetty-base/modules/shibboleth.mod \ https://www.eduid.cz/_export/code/cs/tech/idp/5/shibboleth-new?codeblock=5
tweak-ssl.xml
Konfiguračním souborem /opt/shibboleth-idp/jetty-base/etc/tweak-ssl.xml nastavíme moderní šifrování pro Jetty.
- tweak-ssl.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> <Item>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</Item> <Item>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</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> <!-- Include modern protocols --> <Call name="setIncludeProtocols"> <Arg> <Array type="java.lang.String"> <Item>TLSv1.3</Item> <Item>TLSv1.2</Item> </Array> </Arg> </Call> <!-- Forward Secrecy --> <Set name="IncludeCipherSuites"> <Array type="String"> <Item>TLS_AES_128_GCM_SHA256</Item> <Item>TLS_AES_256_GCM_SHA384</Item> <Item>TLS_CHACHA20_POLY1305_SHA256</Item> <Item>TLS_ECDHE.*</Item> </Array> </Set> </Configure>
Soubor tweak-ssl.xml pro jednoduchost stáhněte od nás.
# Stažení připraveného souboru tweak-ssl.xml wget -O /opt/shibboleth-idp/jetty-base/etc/tweak-ssl.xml \ 'https://www.eduid.cz/_export/code/cs/tech/idp/5/shibboleth-new?codeblock=7'
jetty-rewrite-rules.xml
V souboru /opt/shibboleth-idp/jetty-base/etc/jetty-rewrite-rules.xml nastavíme bezpečnostní hlavičky jako HSTS a další.
- jetty-rewrite-rules.xml
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd"> <Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer"> <!-- Strict-Transport-Security --> <Call name="addRule"> <Arg> <New class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule"> <Set name="pattern">*</Set> <Set name="headerName">Strict-Transport-Security</Set> <Set name="headerValue">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="headerName">X-Content-Type-Options</Set> <Set name="headerValue">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="headerName">X-Xss-Protection</Set> <Set name="headerValue">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="headerName">X-Frame-Options</Set> <Set name="headerValue">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="headerName">Content-Security-Policy</Set> <Set name="headerValue">default-src 'self'; style-src 'self'; script-src 'self' 'unsafe-inline'; img-src 'self'; font-src; 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="headerName">Referrer-Policy</Set> <Set name="headerValue">no-referrer-when-downgrade</Set> </New> </Arg> </Call> </Configure>
Soubor jetty-rewrite-rules.xml je k dispozici u nás.
# Stažení připraveného souboru jetty-rewrite-rules.xml wget -O /opt/shibboleth-idp/jetty-base/etc/jetty-rewrite-rules.xml \ https://www.eduid.cz/_export/code/cs/tech/idp/5/shibboleth-new?codeblock=9
index.jsp
Vytvoříme adresář /opt/shibboleth-idp/jetty-base/webapps/root/ a v něm soubor index.jsp s přesměrováním na hlavní stránku naší organizace.
# Vytvoříme adresář webapps/root/ mkdir -p /opt/shibboleth-idp/jetty-base/webapps/root/ # Vytvořime soubor index.jsp echo '<% response.sendRedirect("https://www.example.org/"); %>' \ > /opt/shibboleth-idp/jetty-base/webapps/root/index.jsp
mariadb-java-client.jar
V Jetty musíme vytvořit symbolický odkaz na knihovnu pro komunikaci s databází MariaDB.
# Vytvoření adresáře pro externí knihovny mkdir /opt/shibboleth-idp/jetty-base/lib/ext # Vytvoření symbolického odkazu na knihovnu pro databázi MariaDB ln -s /usr/share/java/mariadb-java-client.jar \ /opt/shibboleth-idp/jetty-base/lib/ext/
jetty.service
Součástí rozšíření IdP pro Jetty je i soubor /opt/shibboleth-idp/jetty-base/jetty.service pro systemd, který je nutné drobně upravit. Musíme změnit skupinu na jetty a přidat sekci [Install].
- jetty.service
[Unit] Documentation=https://www.eclipse.org/jetty/documentation/ Description=Jetty Server After=network-online.target Wants=network-online.target [Service] Type=forking # Set to your chosen values. User=jetty Group=jetty # Allow binding to port 80/443. AmbientCapabilities=CAP_NET_BIND_SERVICE Restart=no TimeoutSec=45 KillMode=process WorkingDirectory=/opt/shibboleth-idp/jetty-base ExecStart=/opt/shibboleth-idp/bin/runjetty.sh start ExecStop=/bin/kill ${MAINPID} SuccessExitStatus=130 143 [Install] WantedBy=multi-user.target
Případně můžete soubor jetty.service stáhnout následujícím příkazem.
# Stažení jetty.service wget -O /opt/shibboleth-idp/jetty-base/jetty.service \ 'https://www.eduid.cz/_export/code/cs/tech/idp/5/shibboleth-new?codeblock=13'
Nyní je nutné vytvořit symbolický odkaz do systemd.
# Vytvoření symbolického odkazu do systemd ln -s /opt/shibboleth-idp/jetty-base/jetty.service \ /etc/systemd/system/
Práva
Nyní vytvoříme pracovní adresář a nastavíme odpovídající práva.
# Vytvoření pracovního adresáře pro Jetty mkdir /opt/shibboleth-idp/jetty-dist/jetty-tmp # Nastavení práv k pracovnímu adresáři pro Jetty chown jetty /opt/shibboleth-idp/jetty-dist/jetty-tmp # Nastavení práv k runjetty.sh chown jetty /opt/shibboleth-idp/bin/runjetty.sh # Nastavení práv k adresáři s logy chown jetty /opt/shibboleth-idp/logs/
Spuštění
Nyní můžeme spustit Jetty.
# Znovunačtení systemd konfigurace systemctl daemon-reload # Spouštět Jetty po startu operačního systému systemctl enable jetty # Spuštění Jetty systemctl start jetty
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))