クラスター ワーカー ノード間のトラフィックを暗号化する
重要
この記事で参照されている init スクリプトの例では、DBFS に格納されているキーストアのハッシュから共有暗号化シークレットが引き出されます。 DBFS でキーストア ファイルを更新してシークレットをローテーションする場合は、実行中のすべてのクラスターを再起動する必要があります。 そうしないと、一貫性のない共有シークレットが原因で、Spark ワーカーによる Spark ドライバーを使用した認証が失敗し、ジョブの速度が低下する可能性があります。 その上、共有シークレットが DBFS に格納されるため、DBFS へのアクセス権を持つすべてのユーザーが、ノートブックを使用してシークレットを取得できます。
必要条件
- この機能を使用するには、Premium プランが必要です。 詳細については、Databricks アカウント チームにお問い合わせください。
init スクリプトのしくみ
重要
この記事で参照されている init スクリプトの例では、DBFS に格納されているキーストアのハッシュから共有暗号化シークレットが引き出されます。 DBFS でキーストア ファイルを更新してシークレットをローテーションする場合は、実行中のすべてのクラスターを再起動する必要があります。 そうしないと、一貫性のない共有シークレットが原因で、Spark ワーカーによる Spark ドライバーを使用した認証が失敗し、ジョブの速度が低下する可能性があります。 その上、共有シークレットが DBFS に格納されるため、DBFS へのアクセス権を持つすべてのユーザーが、ノートブックを使用してシークレットを取得できます。
ユーザー クエリと変換は、通常、暗号化されたチャンネルを使用してクラスターに送信されます。 ただし、既定では、クラスターのワーカー ノード間で交換されるデータは暗号化されません。 環境の要件として、保存時や転送時にデータを常時暗号化する必要がある場合は、TLS 1.3 接続で AES 256 ビット暗号化を使用して、ワーカー ノード間のトラフィックを暗号化するようにクラスターを構成する init スクリプトを作成できます。
Note
AES では、ハードウェア アクセラレーションを利用するために、暗号化ルーチンが有効にされますが、暗号化されていないトラフィックと比較してパフォーマンスの点でペナルティが発生します。 このペナルティにより、ノード間でシャッフルされるデータ量によっては、暗号化されたクラスターではクエリに時間がかかる可能性があります。
ワーカー ノード間のトラフィックの暗号化を有効にする場合は、init スクリプトを使用して Spark 構成パラメーターを設定する必要があります。 ワークスペース内のすべてのクラスターでワーカー間暗号化を使用する場合は、1 つのクラスターに対してクラスター スコープの init スクリプトを使用するか、またはクラスター ポリシーにクラスター スコープの init スクリプトを追加します。
キーストア ファイルを DBFS 内のディレクトリに、一度、コピーします。 次に、暗号化設定を適用する init スクリプトを作成します。
init スクリプトでは、次のタスクを実行する必要があります。
- JKS キーストア ファイルとパスワードを取得します。
- Spark エグゼキューターの構成を設定します。
- Spark ドライバーの構成を設定します。
Note
SSL/HTTPS の有効化に使用される JKS キーストア ファイルは、ワークスペースごとに動的に生成されます。 JKS キーストア ファイルのパスワードはハードコーディングされます。また、キーストアの機密性を保護するためのものではありません。
クラスター暗号化構成を生成するための、これら 3 つのタスクを実装する init スクリプトの例を次に示します。
init スクリプトの例
#!/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"
ドライバーノードとワーカー ノードの初期化が完了すると、これらのノード間のすべてのトラフィックがキーストア ファイルを使用して暗号化されます。
ノートブックの例: 暗号化 init スクリプトをインストールする
次のノートブックでは、キーストア ファイルがコピーされ、DBFS で init スクリプトが生成されます。 init スクリプトを使用して、暗号化を有効にした新しいクラスターを作成できます。
暗号化 init スクリプト ノートブックをインストールする
ワーカー ノード間の暗号化を無効にする
ワーカー ノード間の暗号化を無効にするには、クラスター構成から init スクリプトを削除してから、クラスターを再起動します。