在分散式系統中,Kafka 的安全性至關重要。本文說明如何透過 TLS 加密和 SASL 驗證機制,確保 Kafka 叢集的資料傳輸安全及客戶端身份驗證。首先,建立 CA 憑證並簽署 brokers 和 clients 的憑證,接著設定 key store 和 trust store,並在 brokers 和 clients 的設定檔中指定其路徑和密碼。除了 TLS 設定,本文也詳細介紹了 SASL/GSSAPI 和 SASL/PLAIN 兩種驗證機制的設定步驟,包含 JAAS 設定檔的組態和安全性考量。最後,提供一個自定義密碼驗證器的 Java 範例,示範如何整合第三方密碼伺服器,強化 Kafka 的安全性。
Kafka TLS 設定
在 Kafka 中設定 TLS(Transport Layer Security)是確保資料傳輸安全的關鍵步驟。本文將詳細介紹如何建立必要的憑證、設定 key store 和 trust store,以及如何在 Kafka brokers 和 clients 中啟用 TLS。
建立 CA 憑證和 Key Store
首先,我們需要建立一個自簽名的 CA(Certificate Authority)憑證,並使用它來簽署 brokers 和 clients 的憑證。
匯出 CA 的公開憑證: 將 CA 的公開憑證匯出到
server.ca.crt,這個檔案將被包含在 trust stores 和 certificate chains 中。建立 brokers 的 key store: 使用以下指令建立 brokers 的 key store,並使用自簽名的 CA 簽署其憑證。
$ keytool -genkey -keyalg RSA -keysize 2048 -keystore server.ks.p12 \ -storepass server-ks-password -keypass server-ks-password -alias server \ -storetype PKCS12 -dname "CN=Kafka,O=Confluent,C=GB" -validity 365 $ keytool -certreq -file server.csr -keystore server.ks.p12 -storetype PKCS12 \ -storepass server-ks-password -keypass server-ks-password -alias server $ keytool -gencert -infile server.csr -outfile server.crt \ -keystore server.ca.p12 -storetype PKCS12 -storepass server-ca-password \ -alias ca -ext SAN=DNS:broker1.example.com -validity 365 $ cat server.crt server.ca.crt > serverchain.crt $ keytool -importcert -file serverchain.crt -keystore server.ks.p12 \ -storepass server-ks-password -keypass server-ks-password -alias server \ -storetype PKCS12 -noprompt內容解密:
- 首先,使用
keytool指令產生一個 RSA 金鑰對,並將其儲存在server.ks.p12檔案中。 - 然後,產生一個憑證簽署請求(CSR),並將其儲存在
server.csr檔案中。 - 使用 CA 的私鑰簽署 broker 的 CSR,產生簽署後的憑證
server.crt。 - 將 broker 的憑證和 CA 的憑證串聯起來,形成
serverchain.crt。 - 最後,將憑證鏈匯入 broker 的 key store 中。
- 首先,使用
設定 Trust Store
為了讓 brokers 和 clients 能夠驗證彼此的身份,需要建立 trust store 並匯入 CA 的公開憑證。
為 brokers 建立 trust store:
$ keytool -import -file server.ca.crt -keystore server.ts.p12 \ -storetype PKCS12 -storepass server-ts-password -alias server -noprompt內容解密:
將 CA 的公開憑證匯入 brokers 的 trust store 中,以便 brokers 能夠驗證 clients 的身份。
為 clients 建立 trust store:
$ keytool -import -file server.ca.crt -keystore client.ts.p12 \ -storetype PKCS12 -storepass client-ts-password -alias ca -noprompt內容解密:
將 CA 的公開憑證匯入 clients 的 trust store 中,以便 clients 能夠驗證 brokers 的身份。
設定 Clients 的 Key Store
如果需要啟用 TLS client authentication,則需要為 clients 建立 key store。
- 建立 clients 的 key store:
# Generate self-signed CA key-pair for clients keytool -genkeypair -keyalg RSA -keysize 2048 -keystore client.ca.p12 \ -storetype PKCS12 -storepass client-ca-password -keypass client-ca-password \ -alias ca -dname CN=ClientCA -ext bc=ca:true -validity 365 # Create key store for clients keytool -genkey -keyalg RSA -keysize 2048 -keystore client.ks.p12 \ -storepass client-ks-password -keypass client-ks-password -alias client \ -storetype PKCS12 -dname "CN=Metrics App,O=Confluent,C=GB" -validity 365 # ... (其他指令省略)內容解密:
為 clients 建立一個自簽名的 CA,並使用它來簽署 clients 的憑證。然後,建立 clients 的 key store,並將簽署後的憑證匯入其中。
設定 Kafka Brokers 和 Clients
最後,需要在 Kafka brokers 和 clients 的設定檔中指定 key store 和 trust store 的位置和密碼。
brokers 設定:
ssl.keystore.location=/path/to/server.ks.p12 ssl.keystore.password=server-ks-password ssl.key.password=server-ks-password ssl.keystore.type=PKCS12 ssl.truststore.location=/path/to/server.ts.p12 ssl.truststore.password=server-ts-password ssl.truststore.type=PKCS12 ssl.client.auth=required內容解密:
指定 brokers 的 key store 和 trust store 的位置和密碼,並啟用 TLS client authentication。
clients 設定:
ssl.truststore.location=/path/to/client.ts.p12 ssl.truststore.password=client-ts-password ssl.truststore.type=PKCS12 ssl.keystore.location=/path/to/client.ks.p12 ssl.keystore.password=client-ks-password ssl.key.password=client-ks-password ssl.keystore.type=PKCS12內容解密:
指定 clients 的 trust store 和 key store 的位置和密碼。
安全考量
- 定期更新憑證:Key stores 和 trust stores 需要定期更新,以避免憑證過期導致的 TLS 連線問題。
- 限制 Cipher Suites:可以透過限制 cipher suites 來加強安全性,只允許使用強加密演算法。
- 啟用 Hostname Verification:預設情況下,Kafka 會啟用 hostname verification,以防止 man-in-the-middle 攻擊。
Kafka 安全機制:TLS 與 SASL 設定詳解
在現代分散式系統中,安全性是不可忽視的重要議題。Apache Kafka 作為一個高效能的分散式訊息佇列系統,提供了多種安全機制來保護資料傳輸的安全性和驗證客戶端的身份。本文將探討 Kafka 中的 TLS 和 SASL 機制,以及如何進行相關設定。
TLS 加密傳輸
TLS(Transport Layer Security)是一種廣泛使用的加密通訊協定,用於在網路上提供安全的資料傳輸。在 Kafka 中,TLS 可以用來加密 Broker 之間的通訊以及客戶端與 Broker 之間的通訊。
TLS 的重要性
- 資料加密:TLS 可以確保資料在傳輸過程中不被竊取或篡改。
- 身份驗證:透過 TLS,客戶端可以驗證 Broker 的身份,防止中間人攻擊。
- 符合安全標準:某些組織需要遵守特定的安全標準,如 FIPS 140-2,TLS 可以幫助滿足這些要求。
TLS 設定注意事項
- 金鑰儲存管理:預設情況下,金鑰儲存檔案存放在檔案系統上,因此需要限制對這些檔案的存取許可權。
- 憑證復原:如果私鑰被洩露,可以使用標準的 Java TLS 功能來啟用憑證復原。
- 短暫金鑰:使用短暫金鑰可以減少私鑰洩露的風險。
- 防禦 DoS 攻擊:由於 TLS 握手過程消耗較多資源,因此需要設定連線配額和限制來保護 Broker 的可用性。
SASL 驗證機制
SASL(Simple Authentication and Security Layer)是一種用於驗證的框架,Kafka 支援多種 SASL 機制,包括 GSSAPI、PLAIN、SCRAM 和 OAUTHBEARER。
SASL 的優勢
- 多樣化的驗證方式:SASL 支援多種驗證機制,可以根據不同的安全需求進行選擇。
- 與 TLS 結合使用:SASL 可以與 TLS 結合,提供加密和驗證雙重保障。
SASL 設定詳解
GSSAPI(Kerberos)驗證:
- 使用 Kerberos 進行驗證,需要設定 JAAS 組態檔案,指定 keytab 檔案路徑和 principal。
- 需要確保 DNS 服務的安全性,因為 Kerberos 需要進行主機名稱查詢。
sasl.enabled.mechanisms=GSSAPI listener.name.external.gssapi.sasl.jaas.config= \ com.sun.security.auth.module.Krb5LoginModule required \ useKeyTab=true storeKey=true \ keyTab="/path/to/broker1.keytab" \ principal="kafka/[email protected]";PLAIN 驗證:
- 使用使用者名稱和密碼進行驗證,通常需要與自定義的伺服器端回呼(callback)結合使用,以從外部密碼儲存中驗證密碼。
SCRAM-SHA-256 和 SCRAM-SHA-512:
- 提供內建的使用者名稱和密碼驗證機制,無需額外的密碼儲存。
OAUTHBEARER:
- 使用 OAuth bearer tokens 進行驗證,通常需要與自定義的回呼結合使用,以取得和驗證由標準 OAuth 伺服器頒發的 tokens。
自定義 SASL 機制
Kafka 允許開發者透過自定義回呼處理器(callback handlers)來擴充套件 SASL 機制,以整合第三方驗證伺服器。這種靈活性使得 Kafka 可以適應各種不同的安全基礎設施和驗證需求。
自定義回呼處理器的作用
- 登入回呼處理器:用於自定義登入過程,例如取得用於驗證的憑據。
- 伺服器回呼處理器:用於驗證客戶端的憑據,例如使用外部密碼伺服器驗證密碼。
- 客戶端回呼處理器:用於注入客戶端憑據,而不是將其包含在 JAAS 組態中。
Kafka 安全驗證機制:SASL/GSSAPI 與 SASL/PLAIN 設定
Kafka 提供了多種安全驗證機制,包括 SASL/GSSAPI 和 SASL/PLAIN,以確保叢集和客戶端之間的通訊安全。本文將探討這兩種機制的組態方法及其安全性考量。
SASL/GSSAPI 設定
SASL/GSSAPI 是一種根據 Kerberos 的驗證機制,適合需要高度安全性的生產環境。以下是設定步驟:
Keytab 檔案設定:Keytab 檔案必須可被 broker 程式讀取。
sasl.mechanism.inter.broker.protocol=GSSAPI sasl.kerberos.service.name=kafka客戶端組態:客戶端需組態自己的 keytab 和 principal,並指定連線的服務名稱。
sasl.mechanism=GSSAPI sasl.kerberos.service.name=kafka sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \ useKeyTab=true storeKey=true \ keyTab="/path/to/alice.keytab" \ principal="[email protected]";安全性考量:
- 使用 SASL_SSL 以保護驗證流程和連線後的資料傳輸。
- 避免使用弱加密演算法,如 DES-MD5。
- 限制 keytab 檔案的存取許可權。
此圖示說明瞭 SASL/GSSAPI 的工作流程
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 此圖示說明瞭 SASL/GSSAPI 的工作流程
rectangle "Kerberos 驗證" as node1
rectangle "Ticket" as node2
rectangle "驗證成功" as node3
node1 --> node2
node2 --> node3
@enduml
SASL/PLAIN 設定
SASL/PLAIN 是一種簡單的使用者名稱/密碼驗證機制,通常與 TLS 結合使用以提供安全的驗證。
Broker 組態:
sasl.enabled.mechanisms=PLAIN sasl.mechanism.inter.broker.protocol=PLAIN listener.name.external.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ username="kafka" password="kafka-password" \ user_kafka="kafka-password" \ user_Alice="Alice-password";客戶端組態:
sasl.mechanism=PLAIN sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ username="Alice" password="Alice-password";自定義伺服器回呼處理器:為了提高安全性,可以使用自定義的伺服器回呼處理器來整合第三方密碼伺服器。
內容解密:
上述設定展示瞭如何組態 Kafka 使用 SASL/PLAIN 進行驗證。其中,broker 的 JAAS 組態包含了所有客戶端的帳號和密碼,而客戶端只需提供自己的使用者名稱和密碼。
自定義密碼驗證器範例
以下是一個自定義的密碼驗證器範例,用於驗證儲存在檔案中的加密密碼:
public class PasswordVerifier extends PlainServerCallbackHandler {
private final List<String> passwdFiles = new ArrayList<>();
@Override
public void configure(Map<String, ?> configs, String mechanism, List<AppConfigurationEntry> jaasEntries) {
Map<String, ?> loginOptions = jaasEntries.get(0).getOptions();
String files = (String) loginOptions.get("password.files");
Collections.addAll(passwdFiles, files.split(","));
}
@Override
protected boolean authenticate(String user, char[] password) {
return passwdFiles.stream().anyMatch(file -> authenticate(file, user, password));
}
private boolean authenticate(String file, String user, char[] password) {
try {
String cmd = String.format("htpasswd -vb %s %s %s", file, user, new String(password));
return Runtime.getRuntime().exec(cmd).waitFor() == 0;
} catch (Exception e) {
return false;
}
}
}
內容解密:
此自定義驗證器使用 Apache 工具 htpasswd 生成的密碼檔案進行驗證。它支援多個密碼檔案,以便於密碼輪換。