加密叢集 Worker 節點之間的流量
重要
本文所參考的 Init 指令碼範例會從儲存在 DBFS 中的金鑰儲存區雜湊衍生其共用加密機密。 如果您藉由更新 DBFS 中的金鑰儲存區檔案來輪替機密,則必須重新啟動所有執行中的叢集。 否則,Spark 背景工作角色可能會因為共用機密不一致而無法向 Spark 驅動程式驗證,導致工作變慢。 此外,由於共用機密儲存在 DBFS 中,任何具有 DBFS 存取權的使用者都可以使用筆記本來擷取機密。
需求
- 此功能需要進階版方案。 如需更多資訊,請聯絡您的 Databricks 客戶團隊。
Init 指令碼的運作方式
重要
本文所參考的 Init 指令碼範例會從儲存在 DBFS 中的金鑰儲存區雜湊衍生其共用加密機密。 如果您藉由更新 DBFS 中的金鑰儲存區檔案來輪替機密,則必須重新啟動所有執行中的叢集。 否則,Spark 背景工作角色可能會因為共用機密不一致而無法向 Spark 驅動程式驗證,導致工作變慢。 此外,由於共用機密儲存在 DBFS 中,任何具有 DBFS 存取權的使用者都可以使用筆記本來擷取機密。
使用者查詢和轉換通常會透過加密通道傳送至您的叢集。 不過,預設情況下,叢集中 Worker 節點之間交換的資料不會加密。 如果您的環境要求資料無論在靜止或傳輸中都要隨時加密,您可以建立一個 Init 指令碼,設定叢集使用 AES 256 位元加密 TLS 1.3 連線,加密 Worker 節點之間的流量。
注意
雖然 AES 可讓加密常式利用硬體加速的優勢,但相較於未加密的流量,仍會造成效能上的損失。 此懲罰可能會導致查詢在加密叢集上花費較長的時間,具體需視節點之間隨機顯示的資料量而定。
啟用 Worker 節點之間的流量加密,需要透過 Init 指令碼設定 Spark 設定參數。 如果您希望工作區中的所有叢集都使用 Worker-to-Worker 加密,您可以針對單一叢集使用叢集範圍的初始指令碼,或在叢集政策中加入叢集範圍的初始指令碼。
預付方案,將金鑰儲存區檔案複製到 DBFS 中的目錄。 然後建立套用加密設定的 Init 指令碼。
此 Init 指令碼必需執行下列工作:
- 取得 JKS 金鑰儲存區檔案和密碼。
- 設定 Spark 執行程式設定。
- 設定 Spark 驅動程式設定。
注意
用於啟用 SSL/HTTPS 的 JKS 金鑰儲存區檔案會針對每個工作區動態產生。 JKS 金鑰儲存區檔案的密碼已寫死,不是用來保護金鑰儲存區的機密性。
以下是實作這三項工作的 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"
驅動程式和 Worker 節點的初始化完成後,這些節點之間的所有流量都會使用金鑰儲存區檔案加密。
筆記本範例:安裝加密 Init 指令碼
下列筆記本會複製金鑰儲存區檔案,並在 DBFS 中產生 Init 指令碼。 您可以使用 Init 指令碼來建立已啟用加密的新叢集。
安裝加密 Init 指令碼筆記本
停用 Worker 節點之間的加密
若要停用 Worker 節點之間的加密,請從叢集設定中移除 Init 指令碼,然後重新啟動叢集。