返回文章列表

Kafka TLS 與 SASL 安全設定

本文介紹如何設定 Kafka 的 TLS 和 SASL 安全機制,包含建立憑證、設定 key store 和 trust store,以及如何在 brokers 和 clients 中啟用 TLS。同時也涵蓋了 SASL/GSSAPI 和 SASL/PLAIN

資安 系統設計

在分散式系統中,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 的憑證。

  1. 匯出 CA 的公開憑證: 將 CA 的公開憑證匯出到 server.ca.crt,這個檔案將被包含在 trust stores 和 certificate chains 中。

  2. 建立 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
    

    內容解密:

    1. 首先,使用 keytool 指令產生一個 RSA 金鑰對,並將其儲存在 server.ks.p12 檔案中。
    2. 然後,產生一個憑證簽署請求(CSR),並將其儲存在 server.csr 檔案中。
    3. 使用 CA 的私鑰簽署 broker 的 CSR,產生簽署後的憑證 server.crt
    4. 將 broker 的憑證和 CA 的憑證串聯起來,形成 serverchain.crt
    5. 最後,將憑證鏈匯入 broker 的 key store 中。

設定 Trust Store

為了讓 brokers 和 clients 能夠驗證彼此的身份,需要建立 trust store 並匯入 CA 的公開憑證。

  1. 為 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 的身份。

  2. 為 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。

  1. 建立 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 的位置和密碼。

  1. 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。

  2. 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 的位置和密碼。

安全考量

  1. 定期更新憑證:Key stores 和 trust stores 需要定期更新,以避免憑證過期導致的 TLS 連線問題。
  2. 限制 Cipher Suites:可以透過限制 cipher suites 來加強安全性,只允許使用強加密演算法。
  3. 啟用 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 的重要性

  1. 資料加密:TLS 可以確保資料在傳輸過程中不被竊取或篡改。
  2. 身份驗證:透過 TLS,客戶端可以驗證 Broker 的身份,防止中間人攻擊。
  3. 符合安全標準:某些組織需要遵守特定的安全標準,如 FIPS 140-2,TLS 可以幫助滿足這些要求。

TLS 設定注意事項

  • 金鑰儲存管理:預設情況下,金鑰儲存檔案存放在檔案系統上,因此需要限制對這些檔案的存取許可權。
  • 憑證復原:如果私鑰被洩露,可以使用標準的 Java TLS 功能來啟用憑證復原。
  • 短暫金鑰:使用短暫金鑰可以減少私鑰洩露的風險。
  • 防禦 DoS 攻擊:由於 TLS 握手過程消耗較多資源,因此需要設定連線配額和限制來保護 Broker 的可用性。

SASL 驗證機制

SASL(Simple Authentication and Security Layer)是一種用於驗證的框架,Kafka 支援多種 SASL 機制,包括 GSSAPI、PLAIN、SCRAM 和 OAUTHBEARER。

SASL 的優勢

  1. 多樣化的驗證方式:SASL 支援多種驗證機制,可以根據不同的安全需求進行選擇。
  2. 與 TLS 結合使用:SASL 可以與 TLS 結合,提供加密和驗證雙重保障。

SASL 設定詳解

  1. 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]";
    
  2. PLAIN 驗證

    • 使用使用者名稱和密碼進行驗證,通常需要與自定義的伺服器端回呼(callback)結合使用,以從外部密碼儲存中驗證密碼。
  3. SCRAM-SHA-256 和 SCRAM-SHA-512

    • 提供內建的使用者名稱和密碼驗證機制,無需額外的密碼儲存。
  4. OAUTHBEARER

    • 使用 OAuth bearer tokens 進行驗證,通常需要與自定義的回呼結合使用,以取得和驗證由標準 OAuth 伺服器頒發的 tokens。

自定義 SASL 機制

Kafka 允許開發者透過自定義回呼處理器(callback handlers)來擴充套件 SASL 機制,以整合第三方驗證伺服器。這種靈活性使得 Kafka 可以適應各種不同的安全基礎設施和驗證需求。

自定義回呼處理器的作用

  1. 登入回呼處理器:用於自定義登入過程,例如取得用於驗證的憑據。
  2. 伺服器回呼處理器:用於驗證客戶端的憑據,例如使用外部密碼伺服器驗證密碼。
  3. 客戶端回呼處理器:用於注入客戶端憑據,而不是將其包含在 JAAS 組態中。

Kafka 安全驗證機制:SASL/GSSAPI 與 SASL/PLAIN 設定

Kafka 提供了多種安全驗證機制,包括 SASL/GSSAPI 和 SASL/PLAIN,以確保叢集和客戶端之間的通訊安全。本文將探討這兩種機制的組態方法及其安全性考量。

SASL/GSSAPI 設定

SASL/GSSAPI 是一種根據 Kerberos 的驗證機制,適合需要高度安全性的生產環境。以下是設定步驟:

  1. Keytab 檔案設定:Keytab 檔案必須可被 broker 程式讀取。

    sasl.mechanism.inter.broker.protocol=GSSAPI
    sasl.kerberos.service.name=kafka
    
  2. 客戶端組態:客戶端需組態自己的 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]";
    
  3. 安全性考量

    • 使用 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 結合使用以提供安全的驗證。

  1. 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";
    
  2. 客戶端組態

    sasl.mechanism=PLAIN
    sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
        username="Alice" password="Alice-password";
    
  3. 自定義伺服器回呼處理器:為了提高安全性,可以使用自定義的伺服器回呼處理器來整合第三方密碼伺服器。

內容解密:

上述設定展示瞭如何組態 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 生成的密碼檔案進行驗證。它支援多個密碼檔案,以便於密碼輪換。