Sichere Verbindung (TLS/HTTPS)

Für einen sicheren Betrieb des BPC sollten möglichst nur gesicherte Verbindungen genutzt werden.

Info

Zur Kommunikation mit OpenSearch wird seit BPC 4.1.9 bzw. 4.2.0 in der Voreinstellung HTTPS (Port 9200) verwendet. Für die interne Kommunikation zwischen den OpenSearch Nodes in einem OpenSearch-Cluster wird der Transport Layer genutzt, der den Port 9300 verwendet. Das BPC Frontend kann in der Voreinstellung per HTTP (Port 8181) und HTTPS (Port 8282) aufgerufen werden.

Dabei kommen jeweils von Virtimo selbst signierte Zertifikate zum Einsatz. Diese sind im sogenannten Keystore und Truststore zu finden. Der von Virtimo ausgelieferte Keystore hat den Dateinamen virtimo_keystore.jks und der Truststore den Dateinamen virtimo_truststore.jks.

Diese wurden mit diesem Script erstellt
#!/bin/sh

mkdir certs && cd certs

# ---------------------------------------------------------------------
# ROOT Zertifikat, hat eine Gültigkeitsdauer von 10 Jahren (~ 3650 Tage)
# ----------------------------------------------------------------------

openssl genrsa -out root-ca-key.pem 2048

openssl req \
  -new \
  -x509 \
  -sha256 \
  -key root-ca-key.pem \
  -subj "/DC=com/DC=example/O=Example Com Inc./OU=Example Com Inc. Root CA/CN=Example Com Inc. Root CA" \
  -addext "basicConstraints = critical,CA:TRUE" \
  -addext "keyUsage = critical, digitalSignature, keyCertSign, cRLSign" \
  -addext "subjectKeyIdentifier = hash" \
  -addext "authorityKeyIdentifier = keyid:always,issuer:always" \
  -days 3650 \
  -out root-ca.pem

#openssl pkcs12 -export \
#  -name root-ca \
#  -in root-ca.pem \
#  -inkey root-ca-key.pem \
#  -out root-ca.p12 \
#  -password pass:virtimo

keytool -import \
  -file root-ca.pem \
  -alias root-ca \
  -keystore virtimo_truststore.jks \
  -storepass virtimo \
  -noprompt

# -------------------------------------------------
# Für den Jetty/Karaf/PAX Web mit dem Alias 'karaf'
# -------------------------------------------------

openssl genrsa -out karaf-key-temp.pem 2048

openssl pkcs8 \
  -inform PEM \
  -outform PEM \
  -in karaf-key-temp.pem \
  -topk8 \
  -nocrypt \
  -v1 PBE-SHA1-3DES \
  -out karaf-key.pem

openssl req \
  -new \
  -key karaf-key.pem \
  -subj "/C=DE/L=Berlin/O=Virtimo AG/OU=karaf/CN=karaf.example.com" \
  -out karaf.csr

cat > karaf.extfile << EOF
subjectAltName = DNS:karaf.example.com, DNS:localhost, IP:::1, IP:127.0.0.1
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
basicConstraints = critical,CA:FALSE
EOF

openssl x509 \
  -req \
  -in karaf.csr \
  -out karaf.pem \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days 3650 \
  -extfile karaf.extfile

openssl pkcs12 -export \
  -name karaf \
  -in karaf.pem \
  -inkey karaf-key.pem \
  -out karaf.p12 \
  -password pass:virtimo

keytool \
  -importkeystore \
  -destkeystore virtimo_keystore.jks \
  -deststoretype jks \
  -deststorepass virtimo \
  -srckeystore karaf.p12 \
  -srcstoretype pkcs12 \
  -srcstorepass virtimo \
  -alias karaf

rm karaf.csr
rm karaf.extfile

# -------------------------------------------------------
# Für den OpenSearch Node mit dem Alias 'opensearch_node'
# -------------------------------------------------------

openssl genrsa -out opensearch_node-key-temp.pem 2048

openssl pkcs8 \
  -inform PEM \
  -outform PEM \
  -in opensearch_node-key-temp.pem \
  -topk8 \
  -nocrypt \
  -v1 PBE-SHA1-3DES \
  -out opensearch_node-key.pem

openssl req \
  -new \
  -key opensearch_node-key.pem \
  -subj "/C=DE/L=Berlin/O=Virtimo AG/OU=node/CN=node-0.example.com" \
  -out opensearch_node.csr

cat > opensearch_node.extfile << EOF
subjectAltName = RID:1.2.3.4.5.5, DNS:node-0.example.com, DNS:localhost, IP:::1, IP:127.0.0.1
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
basicConstraints = critical,CA:FALSE
EOF

openssl x509 \
  -req \
  -in opensearch_node.csr \
  -out opensearch_node.pem \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -days 3650 \
  -extfile opensearch_node.extfile

openssl pkcs12 -export \
  -name opensearch_node \
  -in opensearch_node.pem \
  -inkey opensearch_node-key.pem \
  -out opensearch_node.p12 \
  -password pass:virtimo

keytool \
  -importkeystore \
  -destkeystore virtimo_keystore.jks \
  -deststoretype jks \
  -deststorepass virtimo \
  -srckeystore opensearch_node.p12 \
  -srcstoretype pkcs12 \
  -srcstorepass virtimo \
  -alias opensearch_node

rm opensearch_node.csr
rm opensearch_node.extfile

# ---------------------------------------------------------
# Für den OpenSearch ADMIN mit dem Alias 'opensearch_admin'
# ---------------------------------------------------------

openssl req \
  -new \
  -newkey rsa:2048 \
  -keyout opensearch_admin-key.pem \
  -out opensearch_admin.csr \
  -nodes \
  -subj "/C=DE/L=Berlin/O=Virtimo AG/OU=Dev/CN=opensearch_admin"

cat > opensearch_admin.extfile << EOF
basicConstraints = critical,CA:FALSE
keyUsage = critical,digitalSignature,nonRepudiation,keyEncipherment
extendedKeyUsage = critical,clientAuth
authorityKeyIdentifier = keyid,issuer:always
subjectKeyIdentifier = hash
EOF

openssl x509 \
  -req \
  -in opensearch_admin.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -out opensearch_admin.pem \
  -days 3650 \
  -extfile opensearch_admin.extfile

#openssl pkcs12 -export \
#  -name opensearch_admin \
#  -in opensearch_admin.pem \
#  -inkey opensearch_admin-key.pem \
#  -out opensearch_admin.p12 \
#  -password pass:virtimo

rm opensearch_admin.csr
rm opensearch_admin.extfile

# ----------------------------------------------------------------------------------------
# Für den OpenSearch BPC User mit dem Alias 'bpc'. Karaf / OpenSearch Client -> OpenSearch
# Unser OpenSearch ist so konfiguriert, dass der Wert aus CN (= bpc) der Username ist.
# ----------------------------------------------------------------------------------------

openssl req \
  -new \
  -newkey rsa:2048 \
  -keyout opensearch_bpc-key.pem \
  -out opensearch_bpc.csr \
  -nodes \
  -subj "/C=DE/L=Berlin/O=Virtimo AG/OU=client/CN=bpc"

cat > opensearch_bpc.extfile << EOF
basicConstraints = critical,CA:FALSE
keyUsage = critical,digitalSignature,nonRepudiation,keyEncipherment
extendedKeyUsage = critical,clientAuth
authorityKeyIdentifier = keyid,issuer:always
subjectKeyIdentifier = hash
EOF

openssl x509 \
  -req \
  -in opensearch_bpc.csr \
  -CA root-ca.pem \
  -CAkey root-ca-key.pem \
  -CAcreateserial \
  -out opensearch_bpc.pem \
  -days 3650 \
  -extfile opensearch_bpc.extfile

openssl pkcs12 -export \
  -name opensearch_bpc \
  -in opensearch_bpc.pem \
  -inkey opensearch_bpc-key.pem \
  -out opensearch_bpc.p12 \
  -password pass:virtimo

keytool \
  -importkeystore \
  -destkeystore virtimo_keystore.jks \
  -deststoretype jks \
  -deststorepass virtimo \
  -srckeystore opensearch_bpc.p12 \
  -srcstoretype pkcs12 \
  -srcstorepass virtimo \
  -alias opensearch_bpc

rm opensearch_bpc.csr
rm opensearch_bpc.extfile

Die Keys/Zertifikate in diesen Containern müssen durch eigene ersetzt bzw. erweitert werden. Siehe dazu OpenSearch Dokumentation.

Das OpenSearch Security Plugin stellt die Funktionalitäten zur Verfügung. Die umfangreichen Konfigurationsmöglichkeiten sind in der OpenSearch Security Dokumention nachzulesen.

Für die Erstellung von Zertifikaten und dem Arbeiten mit den Keystore/Truststore-Dateien können die Kommandozeilentools openssl und keytool verwendet werden. Wesentlich komfortabler geht dies mit dem KeyStore Explorer.

Wo kommt der Keystore zum Einsatz?

Karaf

In der karaf/etc/org.ops4j.pax.web.cfg wird der Keystore über folgende Einstellungen referenziert:

karaf/etc/org.ops4j.pax.web.cfg
org.ops4j.pax.web.ssl.keystore = ${karaf.etc}/virtimo/ssl/virtimo_keystore.jks
org.ops4j.pax.web.ssl.keystore.password = virtimo
org.ops4j.pax.web.ssl.keystore.type = JKS

Die Konfigurationsdatei karaf/etc/org.ops4j.pax.web.cfg wird zur Konfiguration des Webservers, welcher vom Karaf aus gestartet wird, verwendet. In unserem Fall ist dies der Jetty.

OpenSearch

In der opensearch/config/opensearch.yml wird der Keystore über folgende Einstellungen referenziert:

opensearch/config/opensearch.yml
plugins.security.ssl.http.keystore_filepath: virtimo/ssl/virtimo_keystore.jks
plugins.security.ssl.http.keystore_password: virtimo
plugins.security.ssl.http.keystore_type: jks
opensearch/config/opensearch.yml
plugins.security.ssl.transport.keystore_filepath: virtimo/ssl/virtimo_keystore.jks
plugins.security.ssl.transport.keystore_password: virtimo
plugins.security.ssl.transport.keystore_type: jks

Wo kommt der Truststore zum Einsatz?

Karaf

In der karaf/etc/org.ops4j.pax.web.cfg wird der Truststore über folgende Einstellungen referenziert:

karaf/etc/org.ops4j.pax.web.cfg
org.ops4j.pax.web.ssl.truststore = ${karaf.etc}/virtimo/ssl/virtimo_truststore.jks
org.ops4j.pax.web.ssl.truststore.password = virtimo
org.ops4j.pax.web.ssl.truststore.type = JKS

OpenSearch

In der opensearch/config/opensearch.yml wird der Truststore über folgende Einstellungen referenziert:

opensearch/config/opensearch.yml
plugins.security.ssl.http.truststore_filepath: virtimo/ssl/virtimo_truststore.jks
plugins.security.ssl.http.truststore_password: virtimo
plugins.security.ssl.http.truststore_type: jks
opensearch/config/opensearch.yml
plugins.security.ssl.transport.truststore_filepath: virtimo/ssl/virtimo_truststore.jks
plugins.security.ssl.transport.truststore_password: virtimo
plugins.security.ssl.transport.truststore_type: jks

Verwendung des Keystore

Das Passwort für den Keystore virtimo_keystore.jks ist virtimo.

Folgende Keys/Zertifikate befinden sich im Keystore virtimo_keystore.jks.

Alias Passwort

karaf

virtimo

opensearch_bpc

virtimo

opensearch_node

virtimo

Es ist zwingend erforderlich, dass das Keystore Passwort mit denen der enthaltenen Aliase übereinstimmt. Andernfalls kommt es zu nicht nachvollziehbaren Problemen.

Folgend eine Übersicht von wo die Aliase referenziert werden.

Alias 'karaf'

Wird im Karaf zur Auslieferung der BPC-Webseiten über den Webserver 'Jetty' per HTTPS verwendet.

karaf/etc/org.ops4j.pax.web.cfg
org.ops4j.pax.web.ssl.key.alias = karaf
org.ops4j.pax.web.ssl.key.password = virtimo

Die Einstellung org.ops4j.pax.web.ssl.key.alias war in früheren Versionen nicht gesetzt und ist nun Pflicht.

Alias 'opensearch_bpc'

Wird für den Zugriff vom BPC auf das OpenSearch per HTTPS verwendet.

karaf/etc/de.virtimo.bpc.core.cfg
de.virtimo.bpc.core.opensearch.privatekey.alias = opensearch_bpc
de.virtimo.bpc.core.opensearch.privatekey.password = virtimo

In dem Zertifikateintrag steckt auch der Name des Benutzers drin, welcher auf OpenSearch zugreift.

Der Wert im Feld Antragsteller ist auf CN=bpc,OU=client,O=Virtimo AG,L=Berlin,C=DE gesetzt. Dabei wird vom OpenSearch Security Plugin der CN-Wert (bpc) als Benutzer für die Zugriffe verwendet.

Der Benutzer bpc findet sich dementsprechend auch in OpenSearch wieder. In der Konfigurationsdatei opensearch/config/opensearch-security/roles_mapping.yml ist der Benutzer bpc der Rolle all_access zugeordnet.

Alias 'opensearch_node'

Wird für den Zugriff zwischen den OpenSearch Nodes im Cluster verwendet.

opensearch/conf/opensearch.yaml
plugins.security.ssl.http.keystore_alias: opensearch_node
plugins.security.ssl.http.keystore_keypassword: virtimo
opensearch/conf/opensearch.yaml
plugins.security.ssl.transport.keystore_alias: opensearch_node
plugins.security.ssl.transport.keystore_keypassword: virtimo

Verwendung des Truststore

Das Passwort für den Truststore virtimo_truststore.jks ist virtimo.

Folgende Keys/Zertifikate befinden sich im Truststore virtimo_truststore.jks.

Alias Passwort

root-ca

virtimo

Alias 'root-ca'

Ist das vertrauenswürdige Root Zertifikat, mit dem die anderen Zertifikate signiert wurden. Es wird zur Ausführung der OpenSearch Security Tools wie dem securityadmin.sh benötigt (siehe Passwort des OpenSearch 'admin' Benutzers ändern) sowie beim OpenSearch Cluster.

Keystore und Truststore auslagern

Es wird empfohlen, dass angepasste Keystore- und Truststore-Dateien aus den Karaf- und OpenSearch-Ordnern verschoben werden. So dass diese bei Aktualisierungen von Karaf und OpenSearch nicht verloren gehen.

Default Ort Karaf
./bpc/karaf/etc/virtimo/ssl/virtimo_keystore.jks
./bpc/karaf/etc/virtimo/ssl/virtimo_truststore.jks
Default Ort OpenSearch
./bpc/opensearch/config/virtimo/ssl/virtimo_keystore.jks
./bpc/opensearch/config/virtimo/ssl/virtimo_truststore.jks
Empfohlener neuer Ort
./bpc/ssl/virtimo_keystore.jks
./bpc/ssl/virtimo_truststore.jks

Damit Karaf den Keystore und Truststore am neuen Ort findet, müssen in der zentralen Konfigurationsdatei folgende Werte von etc-Dateien überschrieben werden:

Linux (bpc.env.sh)
export ORG_OPS4J_PAX_WEB_ORG_OPS4J_PAX_WEB_SSL_KEYSTORE=../ssl/virtimo_keystore.jks
export ORG_OPS4J_PAX_WEB_ORG_OPS4J_PAX_WEB_SSL_TRUSTSTORE=../ssl/virtimo_truststore.jks
Windows (bpc.env.cmd)
SET ORG_OPS4J_PAX_WEB_ORG_OPS4J_PAX_WEB_SSL_KEYSTORE=../ssl/virtimo_keystore.jks
SET ORG_OPS4J_PAX_WEB_ORG_OPS4J_PAX_WEB_SSL_TRUSTSTORE=../ssl/virtimo_truststore.jks

Damit OpenSearch den Keystore und Truststore am neuen Ort findet, müssen leider symbolische Links verwendet werden:

Linux
# create a symbolic link for OpenSearch
cd bpc/opensearch/config/virtimo && ln -s ../../../ssl ssl
Windows
rem create a symbolic link for OpenSearch (start the shell as administrator)
cd bpc && rmdir /s opensearch\config\virtimo\ssl && mklink /J opensearch\config\virtimo\ssl ssl

Probleme mit der HTTPS Verbindung vom BPC zu OpenSearch?

Um andere Probleme auszuschliessen, kann die Verbindung temporär wieder auf HTTP umgestellt werden. Hier die notwendigen Schritte für OpenSearch und Karaf. Nach den Anpassungen müssen beide Systeme neu gestartet werden.

OpenSearch

In der opensearch/config/opensearch.yml das OpenSearch Security Plugin deaktivieren (die Einstellung gibt es bereits in der Datei).

opensearch/config/opensearch.yml
plugins.security.disabled: true

Karaf

In der karaf/etc/de.virtimo.bpc.core.cfg das OpenSearch Schema von https zu http ändern.

karaf/etc/de.virtimo.bpc.core.cfg
de.virtimo.bpc.core.opensearch.scheme = http

Zugriff auf OpenSearch per HTTPS testen

Basic Auth

Diese Art existiert noch, es sollte aber wie in der Voreinstellung, der Weg über das Zertifikat gegangen werden (siehe unten).

karaf/etc/de.virtimo.bpc.core.cfg (dies nur als Hinweis bzw. zum Verständnis)
de.virtimo.bpc.core.opensearch.username = admin
de.virtimo.bpc.core.opensearch.password = admin

Exemplarischer Aufruf per CURL

curl --insecure -u admin:admin 'https://localhost:9200'

Diesen admin Benutzer mit dem Passwort admin legt das OpenSearch Security Plugin an. Siehe Passwort des OpenSearch 'admin' Benutzers ändern.

Zertifikat

so erfolgt in der Voreinstellung auch der Zugriff auf OpenSearch vom Karaf/BPC aus.

karaf/etc/de.virtimo.bpc.core.cfg (dies nur als Hinweis bzw. zum Verständnis)
de.virtimo.bpc.core.opensearch.privatekey.alias = opensearch_bpc
de.virtimo.bpc.core.opensearch.privatekey.password = virtimo

Exemplarischer Aufruf per CURL

curl --insecure --cert opensearch_bpc.pem 'https://localhost:9200'

CURL kann leider nichts mit einem Java Keystore anfangen. Generierung des zuvor verwendeten opensearch_bpc.pem aus dem Keystore Alias opensearch_bpc.

Möglichkeit 1: opensearch_bpc.pem per Shell Befehle
keytool -importkeystore \
  -srckeystore virtimo_keystore.jks \
  -srcstoretype JKS \
  -srcalias opensearch_bpc \
  -destkeystore opensearch_bpc.p12 \
  -deststoretype PKCS12 \
  -srcstorepass virtimo \
  -deststorepass virtimo

openssl pkcs12 \
  -in opensearch_bpc.p12 \
  -nocerts \
  -nodes \
  -out opensearch_bpc-key.pem \
  -password pass:virtimo

openssl pkcs12 \
  -in opensearch_bpc.p12 \
  -nokeys \
  -out opensearch_bpc-cert.pem \
  -password pass:virtimo

cat opensearch_bpc-key.pem opensearch_bpc-cert.pem > opensearch_bpc.pem

rm opensearch_bpc.p12
rm opensearch_bpc-key.pem
rm opensearch_bpc-cert.pem
Möglichkeit 2: opensearch_bpc.pem per KeyStore Explorer
- den Keystore 'virtimo_keystore.jks' öffnen
- Kontextmenü auf dem Eintrag 'opensearch_bpc'
- Exportieren -> Schlüsselpaar exportieren
- Im Export Dialog: Format = PEM, Passwort = KEINES -> Export

Passwort des OpenSearch 'admin' Benutzers ändern

  1. Wir befinden uns im OpenSearch Verzeichnis

    cd opensearch
  2. Benötigte OpenSearch Security Plugin Tools ausführbar machen

    chmod +x ./plugins/opensearch-security/tools/hash.sh
    chmod +x ./plugins/opensearch-security/tools/securityadmin.sh
  3. Hash des neuen Passwortes generieren

    ./plugins/opensearch-security/tools/hash.sh -p sehr_starkes_admin_pw
    
    **************************************************************************
    ** This tool will be deprecated in the next major release of OpenSearch **
    ** https://github.com/opensearch-project/security/issues/1755           **
    **************************************************************************
    $2y$12$5VMnjOnHEoZucsTzxFmdZu3qbddy0tJIGmHPcPep8phE965Dq1ZBK
  4. Den Hash des admin Benutzers in der config/opensearch-security/internal_users.yml ersetzen

    admin:
      hash: "$2y$12$5VMnjOnHEoZucsTzxFmdZu3qbddy0tJIGmHPcPep8phE965Dq1ZBK"
      reserved: true
      backend_roles:
        - "admin"
      description: "Demo admin user"
  5. In der config/opensearch.yml den bpc Benutzer temporär als admin-Benutzer hinzufügen (letzte Zeile mit CN=bpc, …​).

    plugins.security.authcz.admin_dn:
      - "CN=opensearch_admin,OU=Dev,O=Virtimo AG,L=Berlin,C=DE"
      - "CN=bpc,OU=client,O=Virtimo AG,L=Berlin,C=DE"
  6. OpenSearch neu starten

  7. In OpenSearch die internen Benutzer aktualisieren

    ./plugins/opensearch-security/tools/securityadmin.sh \
      --ignore-clustername \
      --type internalusers \
      --file config/opensearch-security/internal_users.yml \
      --keystore config/virtimo/ssl/virtimo_keystore.jks \
      --keystore-alias opensearch_bpc \
      --keystore-password virtimo \
      --truststore config/virtimo/ssl/virtimo_truststore.jks
  8. Test ob das neue admin Passwort korrekt gesetzt wurde

    curl --insecure -u admin:sehr_starkes_admin_pw 'https://localhost:9200'
  9. Die Änderungen unter 5. wieder rückgängig machen und OpenSearch nochmals durchstarten

Passwörter Maskieren

Sie können die Passwörter für org.ops4j.pax.web.ssl.keystore.password und auch org.ops4j.pax.web.ssl.key.password auch als "obfuscated" Zeichenkette angeben. Dies hat den Vorteil, dass das Passwort nicht im Klartext vorliegt.

Um eine maskierte Form eines Passwortes zu erhalten, können Sie folgendes ausführen:

Beispiel: Verschleierung des Passwortes password
> java -cp INSTALLATIONSVERZEICHNIS/karaf/system/org/eclipse/jetty/jetty-util/9.4.22.v20191022/jetty-util-9.4.22.v20191022.jar org.eclipse.jetty.util.security.Password "password"

password
OBF:1v2j1uum1xtv1zej1zer1xtn1uvk1v1v
MD5:5f4dcc3b5aa765d61d8327deb882cf99

In dem Beispiel kann OBF:1v2j1uum1xtv1zej1zer1xtn1uvk1v1v synonym für password in die Konfiguration eingesetzt werden.

Es kann sein, dass die Jetty Versionsnummer in Ihrer Installation abweicht. Diese können Sie auf der Karaf-Konsole wie folgt in Erfahrung bringen:

feature:list | grep jetty

Es handelt sich nur um eine Verschleierung/Maskierung des Passworts, es handelt sich nicht um eine Verschlüsselung.

Secure Flag für Cookies aktivieren

Für den BPC Session Cookie kann das Secure Flag gesetzt werden. Wenn dies aktiv ist, schickt der Browser den Session-Cookie nur über gesicherte Verbindungen zum Server. Dies erhöht die Sicherheit und verhindert das mitlesen des Session-Cookies im Netzwerk. Zum Aktivieren des Secure Flags setzen Sie in der Datei karaf/etc/de.virtimo.bpc.core.cfg bitte folgenden Wert:

de.virtimo.bpc.core.cookieSecure = true

Sollte das BPC nicht über eine gesicherte Verbindung bereitgestellt werden, dann darf diese Option nicht aktiviert werden. Ansonsten kann sich der Client nach der Anmeldung nicht authentifizieren.


Keywords: