Inštalácia a nastavenie Jetty

Inštalácia Jetty:

apt install --no-install-recommends jetty9

Ďalej nastavíme premennú “JAVA_HOME”:

eval $(echo "export JAVA_HOME=/usr" | tee -a /root/.bashrc)

Môžeme skontrolovať nastavenie premennej a verziu java:

echo $JAVA_HOME
java -version

Vytvoríme súbor idp.mod - modul pre Shibboleth IdP, ktorý obsahuje potrebné závislosti pre funkčnosť IdP.

nano /usr/share/jetty9/modules/idp.mod

Obsah súboru:

[description]
Shibboleth IdP

[depend]
annotations
deploy
ext
http
http2
https
jsp
jstl
plus
requestlog
resources
rewrite
server
servlets
ssl

[files]
tmp/

Pre webový server budeme potrebovať verejný certifikát vydaný verejnou certifikačnou autoritou (ďalej CA). Vygenerujeme si žiadosť o certifikát (nachádzame sa v domovskom adresári používateľa “root”):

Vytvoríme adresár, v ktorom budeme následne pracovať:

mkdir ssl_cert
cd ssl_cert

Pre vygenerovanie certificate request použijeme príkaz:

openssl req -new -newkey rsa:2048 -nodes -keyout demoidp.key -out demoidp.csr

Spustí sa proces:

Generating a RSA private key
.....................+++++
..........................................+++++
writing new private key to 'demoidp.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

V adresári “/root/ssl_cert” by sa mali nachádzať vygenerované súbory:

demoidp.csr
demoidp.key

Súbor demoidp.csr je určený pre verejnú CA, ktorá následne po jeho obdržaní vygeneruje SSL certifikát.

Certifikát, ktorý sme dostali od verejnej CA premenujeme na: “demoidp.crt”.

V adresári “/root/ssl_cert” máme spolu sústredené súbory:

demoidp.csr
demoidp.key
demoidp.crt - skopírovaný a premenovaný certifikát od verejnej CA
intermediate.crt - medziľahlý certifikát od verejnej CA doručený spolu s SSL certifikátom (koreňový certifikát verejnej CA nepotrebujeme)

V prípade, že verejná CA používa medziľahlý certifikát potrebujeme ho zlúčiť s SSL certifikátom vygenerovaným pre webový server:

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

Vygenerujeme si heslo, ktore budeme potrebovať v ďalších krokoch (heslo si poznačíme):

openssl rand -hex 20

Vytvorený súbor “jetty-cert.txt” ďalej prevedieme do formátu PKCS#12. Budeme vyzvaný na zadanie hesla - zadáme heslo, ktoré sme si vygenerovali:

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

V adresári “/root/ssl_cert” by sa mali spolu nachádzať súbory:

demoidp.csr
demoidp.key
demoidp.crt
intermediate.crt
jetty-cert.txt
jetty.pkcs12

Vygenerujeme súbor keystore, ktorý pomocou príkazu umiestnime do adresára /etc/jetty9.

Počas procesu generovania keystore zadáme vo všetkých troch prípadoch heslo, ktoré sme si predtým vygenerovali a už ho použili v prípade vytvárania súboru vo formáte PKCS#12.

keytool -importkeystore -srckeystore jetty.pkcs12 \
    -srcstoretype PKCS12 -destkeystore /etc/jetty9/keystore

Proces prebieha nasledovne:

Importing keystore jetty.pkcs12 to /etc/jetty9/keystore...
Enter destination keystore password:
Re-enter new password:
Enter source keystore password:
Entry for alias 1 successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Nastavíme potrebné oprávnenia k súboru keystore:

chmod 640 /etc/jetty9/keystore
chgrp jetty /etc/jetty9/keystore

V adresári /etc/jetty9/start.d vytvoríme konfiguračný súbor idp.ini .

nano /etc/jetty9/start.d/idp.ini

S obsahom:

# --------------------------------------- 
# 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=vygenerované heslo
# Truststore password
jetty.sslContext.trustStorePassword=vygenerované heslo
# KeyManager password
jetty.sslContext.keyManagerPassword=vygenerované heslo
 
# 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

# Set max age in seconds for a Strict-Transport-Security response header
jetty.ssl.stsMaxAgeSeconds=15768000

# Hide Jetty version
jetty.httpConfig.sendServerVersion=false
 
etc/tweak-ssl.xml

A doplníme vygenerované heslo, ktoré sme už použili v predchádzajúcich krokoch a poznačili sme si ho.

V adresári /etc/jetty9 vytvoríme nový súbor tweak-ssl.xml . Budú v ňom definované zakázané a povolené šifry a protokoly:

nano /etc/jetty9/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>
                <!-- To be disabled once IE 11 & Windows 8.1 is EoL in Jan 2023
                <Item>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384.*</Item>
                <Item>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256.*</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_ECDHE.*</Item>
            <Item>TLS_AES.*</Item>
            <Item>TLS_CHACHA20.*</Item>
        </Array>
    </Set>
 
</Configure>

V adresári /var/lib/jetty9/webapps vytvoríme konfiguračný súbor idp.xml potrebný pre beh Shibboleth IdP.

nano /var/lib/jetty9/webapps/idp.xml

S obsahom:

<?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>

Aby sme predišli hláseniam aplikácie Jetty, že používať adresár start.d/ a súbor start.ini súčasne je zastaralé, zmažeme súbor start.ini spolu s jeho symbolickým odkazom:

rm /usr/share/jetty9/start.ini /etc/jetty9/start.ini

V adresári /var/lib/jetty9/webapps/root odstránime predvolenú stránku a do súboru *index.jsp* uvedieme presmerovanie na stránku našej organizácie.

rm /var/lib/jetty9/webapps/root/*

echo '<% response.sendRedirect("https://www.example.org"); %>' > \
    /var/lib/jetty9/webapps/root/index.jsp

Pre správnu funkčnosť potrebuje Jetty pridať link (vytvoriť symbolický odkaz) na JDBC konektor/mariadb-java-client.jar do zložky s externými knižnicami /usr/share/jetty9/lib/ext:

ln -s /usr/share/java/mariadb-java-client.jar \
      /usr/share/jetty9/lib/ext/mariadb-java-client.jar

Pre zvýšenie bezpečnosti používateľov, ktorí budú zadávať do prihlasovacej stránky svoje mená a heslá je vhodné vytvoriť nové bezpečnostné opatrenie pomocou súboru jetty-rewrite.xml.

Najskôr zmažeme pôvodný súbor:

rm /etc/jetty9/jetty-rewrite.xml

Vytvoríme nový súbor:

nano /etc/jetty9/jetty-rewrite.xml

S obsahom:

<?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 is set via ssl module
                <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'</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>

Týmto krokom je hotová konfigurácia pre Jetty.

Reštartujeme Jetty:

systemctl restart jetty9

Kontrolu sieťových spojeni pre porty 80/HTTP a 443/HTTPS urobíme pomocou príkazu:

ss -tlpn | fgrep java

Mali by sme dostať výsledok:

LISTEN   0        50          [::ffff:127.0.0.1]:80                    *:*       users:(("java",pid=945,fd=59))
LISTEN   0        50                           *:443                   *:*       users:(("java",pid=945,fd=51))

Test funkčnosti presmerovania:

wget -S -O/dev/null http://localhost
wget -S -O/dev/null https://`hostname -f`

Môžete pokračovať Inštalácia a nastavenie Shibboleth IdP