Verschlüsseln des Datenverkehrs zwischen Cluster-Workerknoten

Wichtig

Das Init-Beispielskript, auf das in diesem Artikel verwiesen wird, leitet sein gemeinsames Verschlüsselungsgeheimnis aus dem Hash des in DBFS gespeicherten Keystores ab. Wenn Sie das Geheimnis rotieren, indem Sie die Keystoredatei im DBFS aktualisieren, müssen alle ausgeführten Cluster neu gestartet werden. Andernfalls können die Authentifizierung der Spark-Worker beim Spark-Treiber aufgrund eines inkonsistenten gemeinsamen Geheimnisses fehlschlagen, was zu einer Verlangsamung von Aufträgen führt. Darüber hinaus kann jeder Benutzer mit DBFS-Zugriff das Geheimnis mithilfe eines Notebooks abrufen, da das gemeinsame Geheimnis im DBFS gespeichert ist.

Anforderungen

  • Für dieses Feature ist der Premium-Plan erforderlich. Wenden Sie sich für weitere Informationen an Ihr Databricks-Kundenberatungsteam.

Funktionsweise des Init-Skripts

Wichtig

Das Init-Beispielskript, auf das in diesem Artikel verwiesen wird, leitet sein gemeinsames Verschlüsselungsgeheimnis aus dem Hash des in DBFS gespeicherten Keystores ab. Wenn Sie das Geheimnis rotieren, indem Sie die Keystoredatei im DBFS aktualisieren, müssen alle ausgeführten Cluster neu gestartet werden. Andernfalls können die Authentifizierung der Spark-Worker beim Spark-Treiber aufgrund eines inkonsistenten gemeinsamen Geheimnisses fehlschlagen, was zu einer Verlangsamung von Aufträgen führt. Darüber hinaus kann jeder Benutzer mit DBFS-Zugriff das Geheimnis mithilfe eines Notebooks abrufen, da das gemeinsame Geheimnis im DBFS gespeichert ist.

Benutzerabfragen und Transformationen werden in der Regel über einen verschlüsselten Kanal an Ihre Cluster gesendet. Standardmäßig werden die zwischen Workerknoten in einem Cluster ausgetauschten Daten nicht verschlüsselt. Wenn Ihre Umgebung erfordert, dass Daten jederzeit verschlüsselt werden, unabhängig davon, ob sie ruhen oder übertragen werden, können Sie ein Initialisierungsskript erstellen, das Ihre Cluster für die Verschlüsselung des Datenverkehrs zwischen Workerknoten konfiguriert, indem Sie die AES-256-Bit-Verschlüsselung über eine TLS 1.3-Verbindung verwenden.

Hinweis

Obwohl AES kryptografischen Routinen ermöglicht, die Hardwarebeschleunigung zu nutzen, gibt es im Vergleich zu unverschlüsseltem Datenverkehr einen Leistungsabfall. Dieser Leistungsabfall kann dazu führen, dass Abfragen in einem verschlüsselten Cluster je nach Datenmenge, die zwischen Knoten gemischt wird, länger dauern.

Zum Aktivieren der Verschlüsselung des Datenverkehrs zwischen Workerknoten müssen Spark-Konfigurationsparameter über ein Init-Skript festgelegt werden. Sie können ein clusterspezifisches Initialisierungsskript für einen einzelnen Cluster verwenden oder ein clusterspezifisches Initialisierungsskript zu Ihren Clusterrichtlinien hinzufügen, wenn alle Cluster in Ihrem Arbeitsbereich die Worker-zu-Worker-Verschlüsselung verwenden sollen.

Kopieren Sie einmal die Keystore-Datei in ein Verzeichnis in DBFS. Erstellen Sie dann das Init-Skript, das die Verschlüsselungseinstellungen anwendet.

Das Init-Skript muss die folgenden Aufgaben ausführen:

  1. Erhalten Sie die JKS-Keystore-Datei und das Kennwort.
  2. Legen Sie die Spark-Executorkonfiguration fest.
  3. Legen Sie die Spark-Treiberkonfiguration fest.

Hinweis

Die JKS-Keystoredatei, die zum Aktivieren von SSL/HTTPS verwendet wird, wird für jeden Arbeitsbereich dynamisch generiert. Das Kennwort der JKS-Keystore-Datei ist hartcodiert und nicht zum Schutz der Vertraulichkeit des Keystores vorgesehen.

Im Folgenden finden Sie ein Beispiel-Init-Skript, das diese drei Aufgaben implementiert, um die Konfiguration der Clusterverschlüsselung zu generieren.

init-Beispielskript

#!/bin/bash

set -euo pipefail

keystore_dbfs_file="/dbfs/<keystore-directory>/jetty_ssl_driver_keystore.jks"

## Wait till keystore file is available via Fuse

max_attempts=30
while [ ! -f ${keystore_dbfs_file} ];
do
  if [ "$max_attempts" == 0 ]; then
    echo "ERROR: Unable to find the file : $keystore_dbfs_file .Failing the script."
    exit 1
  fi
  sleep 2s
  ((max_attempts--))
done
## Derive shared internode encryption secret from the hash of the keystore file
sasl_secret=$(sha256sum $keystore_dbfs_file | cut -d' ' -f1)

if [ -z "${sasl_secret}" ]; then
  echo "ERROR: Unable to derive the secret.Failing the script."
  exit 1
fi

# The JKS keystore file used for enabling SSL/HTTPS
local_keystore_file="$DB_HOME/keys/jetty_ssl_driver_keystore.jks"
# Password of the JKS keystore file. This jks password is hardcoded and is not intended to protect the confidentiality
# of the keystore. Do not assume the keystore file itself is protected.
local_keystore_password="gb1gQqZ9ZIHS"

## Updating spark-branch.conf is only needed for driver

if [[ $DB_IS_DRIVER = "TRUE" ]]; then
  driver_conf=${DB_HOME}/driver/conf/spark-branch.conf
  echo "Configuring driver conf at $driver_conf"

  if [ ! -e $driver_conf ] ; then
    touch $driver_conf
  fi

cat << EOF >>  $driver_conf
  [driver] {
    // Configure inter-node authentication
  "spark.authenticate" = true
  "spark.authenticate.secret" = "$sasl_secret"
  // Configure AES encryption
  "spark.network.crypto.enabled" = true
  "spark.network.crypto.saslFallback" = false
  // Configure SSL
  "spark.ssl.enabled" = true
  "spark.ssl.keyPassword" = "$local_keystore_password"
  "spark.ssl.keyStore" = "$local_keystore_file"
  "spark.ssl.keyStorePassword" = "$local_keystore_password"
  "spark.ssl.protocol" ="TLSv1.3"
  "spark.ssl.standalone.enabled" = true
  "spark.ssl.ui.enabled" = true
  }
EOF
  echo "Successfully configured driver conf at $driver_conf"
fi

# Setting configs in spark-defaults.conf for the spark master and worker

spark_defaults_conf="$DB_HOME/spark/conf/spark-defaults.conf"
echo "Configuring spark defaults conf at $spark_defaults_conf"
if [ ! -e $spark_defaults_conf ] ; then
  touch $spark_defaults_conf
fi

cat << EOF >>  $spark_defaults_conf
spark.authenticate true
spark.authenticate.secret $sasl_secret
spark.network.crypto.enabled true
spark.network.crypto.saslFallback false

spark.ssl.enabled true
spark.ssl.keyPassword $local_keystore_password
spark.ssl.keyStore $local_keystore_file
spark.ssl.keyStorePassword $local_keystore_password
spark.ssl.protocol TLSv1.3
spark.ssl.standalone.enabled true
spark.ssl.ui.enabled true
EOF

echo "Successfully configured spark defaults conf at $spark_defaults_conf"

Sobald die Initialisierung der Treiber- und Workerknoten abgeschlossen ist, wird der gesamte Datenverkehr zwischen diesen Knoten mithilfe der Keystore-Datei verschlüsselt.

Notebookbeispiel: Installieren eines Initialisierungsskripts zur Verschlüsselung

Das folgende Notebook kopiert die Keystore-Datei und generiert das Init-Skript in DBFS. Sie können das Init-Skript verwenden, um neue Cluster mit aktivierter Verschlüsselung zu erstellen.

Installieren eines Notebooks für das Verschlüsselungs-Init-Skript

Notebook abrufen

Deaktivieren der Verschlüsselung zwischen Workerknoten

Um die Verschlüsselung zwischen Workerknoten zu deaktivieren, entfernen Sie das Init-Skript aus der Clusterkonfiguration, und starten Sie dann den Cluster neu.