返回文章列表

Kafka安全驗證機制詳解

本文探討 Kafka 的安全驗證機制,包含 SASL/PLAIN、SASL/SCRAM、OAUTHBEARER、委派令牌和重新驗證等,並提供詳細的設定步驟、程式碼範例以及安全考量,協助開發者保護 Kafka 叢集安全。

資安 系統設計

Kafka 提供多種安全驗證機制,本文將詳細介紹 SASL/PLAIN、SASL/SCRAM、OAUTHBEARER、委派令牌及重新驗證等機制,並說明其設定方式及安全考量。SASL/PLAIN 簡單易用,但安全性較低,建議搭配 SSL/TLS 使用。SASL/SCRAM 則更安全,避免明文密碼傳輸。OAUTHBEARER 根據 OAuth 2.0,使用 Bearer Token 進行驗證,安全性更高,但需整合第三方 OAuth 伺服器。委派令牌簡化了 Kafka Connect 等框架的安全組態,避免直接分發 SSL 金鑰或 Kerberos keytab。重新驗證機制則確保活動連線都與有效憑證關聯,提升安全性並支援密碼輪換。

SASL驗證機制在Kafka中的應用與設定

Kafka支援多種SASL(Simple Authentication and Security Layer)驗證機制,包括PLAIN和SCRAM,來確保叢集的安全性與使用者驗證。本文將介紹如何在Kafka中設定和使用這些機制。

SASL/PLAIN驗證機制

SASL/PLAIN是一種簡單的驗證機制,但由於它在網路上傳輸明文密碼,因此需要與SSL/TLS加密結合使用,以確保傳輸過程的安全。

設定SASL/PLAIN

  1. 伺服器端設定

    • 在Kafka Broker的設定檔中,需要指定SASL/PLAIN的JAAS(Java Authentication and Authorization Service)設定檔路徑。
    • 使用htpasswd工具來管理使用者密碼。
    listener.name.external.plain.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
    password.files="/path/to/htpassword.props,/path/to/oldhtpassword.props";
    listener.name.external.plain.sasl.server.callback.handler.class=com.example.PasswordVerifier
    
  2. 客戶端設定

    • 客戶端需要實作AuthenticateCallbackHandler介面,以便在連線建立時動態載入密碼。
    • 使用PasswordConfig類別來載入和處理密碼組態。
    @Override
    public void handle(Callback[] callbacks) throws IOException {
        Properties props = Utils.loadProps(passwdFile);
        PasswordConfig config = new PasswordConfig(props);
        String user = config.getString("username");
        String password = config.getPassword("password").value();
        for (Callback callback : callbacks) {
            if (callback instanceof NameCallback)
                ((NameCallback) callback).setName(user);
            else if (callback instanceof PasswordCallback) {
                ((PasswordCallback) callback).setPassword(password.toCharArray());
            }
        }
    }
    

安全考量

  • 由於SASL/PLAIN傳輸明文密碼,建議僅在SASL_SSL加密傳輸層上啟用PLAIN機制。
  • 避免在設定檔中使用明文密碼,考慮使用外部安全密碼儲存或加密密碼。

SASL/SCRAM驗證機制

SASL/SCRAM是一種更安全的驗證機制,避免在網路上傳輸明文密碼,並使用加鹽的雜湊函式儲存密碼。

設定SASL/SCRAM

  1. 建立SCRAM使用者

    • 使用kafka-configs.sh工具在ZooKeeper啟動後、Broker啟動前建立初始使用者。
    $ bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config \
    'SCRAM-SHA-512=[iterations=8192,password=Alice-password]' \
    --entity-type users --entity-name Alice
    
  2. Broker設定

    • 在Broker設定中啟用SCRAM機制,並指定用於Broker間通訊的使用者名稱和密碼。
    sasl.enabled.mechanisms=SCRAM-SHA-512
    sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512
    listener.name.external.scram-sha-512.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
    username="kafka" password="kafka-password";
    
  3. 客戶端設定

    • 客戶端需要組態為使用Broker上啟用的SASL機制,並提供正確的使用者名稱和密碼。
    sasl.mechanism=SCRAM-SHA-512
    sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
    username="Alice" password="Alice-password";
    

管理SCRAM使用者

  • 可以使用kafka-configs.sh工具的--add-config--delete-config選項來新增或刪除SCRAM使用者。

Kafka 安全驗證機制:SCRAM 與 OAUTHBEARER 詳解

Kafka 提供了多種安全驗證機制,包括 SCRAM(Salted Challenge Response Authentication Mechanism)與 OAUTHBEARER(根據 OAuth 2.0 的 Bearer Token 驗證)。這兩種機制各有其特點和應用場景,本文將探討其組態與安全性考量。

SCRAM 驗證機制

SCRAM 是一種根據使用者名稱和密碼的挑戰-回應驗證機制,能夠在不直接傳輸密碼的情況下完成驗證。其核心原理是使用單向加密雜湊函式對密碼進行處理,並結合隨機鹽值以增強安全性。

SCRAM 的優勢與組態

  1. 安全性優勢:SCRAM 使用 SHA-256 和 SHA-512 等強雜湊演算法,避免了弱演算法(如 SHA-1)的使用。同時,預設的高迭代次數(4,096)和隨機鹽值進一步提升了安全性。

  2. 組態範例:要刪除使用者的 SCRAM 組態,可以使用以下命令:

    $ bin/kafka-configs.sh --zookeeper localhost:2181 --alter --delete-config \
    'SCRAM-SHA-512' --entity-type users --entity-name Alice
    
  3. 安全考量:雖然 SCRAM 提供了密碼保護,但仍需採取額外措施保護在握手過程中傳輸的金鑰以及儲存在 ZooKeeper 中的金鑰。建議與 SASL_SSL 安全協定結合使用,並啟用 ZooKeeper 的 SSL 加密。

OAUTHBEARER 驗證機制

OAUTHBEARER 是根據 OAuth 2.0 的驗證機制,利用 Bearer Token 實作身份驗證。它避免了長期密碼相關的安全漏洞,具有較高的安全性。

OAUTHBEARER 的優勢與組態

  1. 安全性優勢:OAUTHBEARER 使用具有時效性和資源存取限制的 OAuth 2.0 Bearer Token,從而降低了安全風險。

  2. 內建實作限制:Kafka 的內建 OAUTHBEARER 實作使用未經驗證的 JSON Web Tokens(JWTs),不適合生產環境。建議透過自定義回呼函式與第三方 OAuth 伺服器整合,以實作安全的驗證。

  3. 客戶端組態範例

    sasl.mechanism=OAUTHBEARER
    sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule \
       required unsecuredLoginStringClaim_sub="Alice";
    
  4. 伺服器端 token 驗證範例

    @Override
    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
       for (Callback callback : callbacks) {
          if (callback instanceof OAuthBearerValidatorCallback) {
             OAuthBearerValidatorCallback cb = (OAuthBearerValidatorCallback) callback;
             try {
                cb.token(validatedToken(cb.tokenValue()));
             } catch (OAuthBearerIllegalTokenException e) {
                OAuthBearerValidationResult r = e.reason();
                cb.error(errorStatus(r), r.failureScope(), r.failureOpenIdConfig());
             }
          } 
          // 其他 callback 處理
       }
    }
    

安全考量

由於 OAUTHBEARER 客戶端會透過網路傳送 OAuth 2.0 Bearer Token,因此必須啟用 TLS 加密以防止 token 被竊取。建議使用具有時效性的 token 以進一步降低安全風險。

Kafka 安全機制深度解析:委派令牌與重新驗證

Kafka 作為一個高效能的分散式訊息佇列系統,其安全性一直是使用者關注的重點。除了基本的 SSL/TLS 加密和 SASL 認證機制外,Kafka 還提供了委派令牌(Delegation Tokens)和重新驗證(Reauthentication)等進階安全功能,以滿足更複雜的安全需求。

委派令牌:簡化安全組態的機制

委派令牌是一種在 Kafka broker 和客戶端之間分享的秘密,用於提供輕量級的安全組態機制,而無需將 SSL 金鑰儲存或 Kerberos keytab 分發給客戶端應用程式。這種機制特別適用於 Kafka Connect 等框架,可以簡化工作節點(worker)的安全組態。

建立與更新委派令牌

客戶端在透過 Kafka broker 認證後,可以為相同的使用者主體(User Principal)建立委派令牌,並將這些令牌分發給工作節點,以便它們可以直接與 Kafka broker 進行認證。每個委派令牌由一個令牌識別碼(Token Identifier)和一個根據雜湊的訊息認證碼(HMAC)組成,作為分享秘密。

建立委派令牌的命令如下:

$ bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 \
--command-config admin.props --create --max-life-time-period -1 \
--renewer-principal User:Bob

更新委派令牌的命令如下:

$ bin/kafka-delegation-tokens.sh --bootstrap-server localhost:9092 \
--command-config admin.props --renew --renew-time-period -1 --hmac c2VjcmV0

內容解密:

  1. --create 引數用於建立新的委派令牌,--max-life-time-period -1 表示令牌的有效期不受限制。
  2. --renewer-principal User:Bob 指定 User:Bob 為令牌更新者。
  3. --renew 引數用於更新現有的委派令牌,--renew-time-period -1 表示更新後的令牌有效期不受限制。
  4. --hmac c2VjcmV0 指定了令牌的 HMAC 值。

組態委派令牌

為了建立和驗證委派令牌,所有 broker 都必須使用相同的 master key 進行組態,該組態選項為 delegation.token.master.key。這個金鑰只能透過重新啟動所有 broker 來輪換。在更新 master key 之前,應刪除所有現有的令牌,因為它們將無法使用。更新金鑰後,應在所有 broker 上建立新的令牌。

至少需要啟用 SASL/SCRAM 機制之一,以支援使用委派令牌進行認證。客戶端應組態為使用 SCRAM,並將令牌識別碼作為使用者名稱,將令牌 HMAC 作為密碼。

組態範例:

sasl.mechanism=SCRAM-SHA-512
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule \
required tokenauth="true" username="MTIz" password="c2VjcmV0";

內容解密:

  1. sasl.mechanism=SCRAM-SHA-512 指定了 SASL 認證機制為 SCRAM-SHA-512。
  2. tokenauth="true" 表示啟用委派令牌認證。
  3. username="MTIz"password="c2VjcmV0" 分別指定了令牌識別碼和 HMAC 值。

安全考量

與內建的 SCRAM 實作一樣,委派令牌僅在 ZooKeeper 安全的佈署中才適合用於生產環境。與 SCRAM 相關的所有安全考量也適用於委派令牌。broker 用於產生令牌的 master key 必須受到保護,可以使用加密或外部安全密碼儲存來儲存。短期的委派令牌可以用來限制在令牌被洩露時的風險。

重新驗證:加強連線安全性

Kafka broker 在客戶端建立連線時執行客戶端認證。客戶端憑證由 broker 驗證,如果憑證在當時有效,則連線認證成功。一些安全機制(如 Kerberos 和 OAuth)使用具有有限生命週期的憑證。Kafka 使用後台登入執行緒在舊憑證到期前取得新憑證,但預設情況下,新憑證僅用於驗證新連線。使用舊憑證認證的現有連線將繼續處理請求,直到由於請求逾時、閒置逾時或網路錯誤而斷開連線。

設定重新驗證

Kafka broker 支援使用 SASL 的連線重新驗證,組態選項為 connections.max.reauth.ms。當此選項設定為正整數時,Kafka broker 將確定 SASL 連線的會話生命週期,並在 SASL 交握期間通知客戶端。會話生命週期是憑證剩餘生命週期或 connections.max.reauth.ms 中的較小者。任何未在此間隔內重新驗證的連線都將由 broker 終止。

重新驗證的好處

  1. 保證有效憑證:對於像 GSSAPI 和 OAUTHBEARER 這樣使用具有有限生命週期憑證的 SASL 機制,重新驗證保證所有活動連線都與有效的憑證相關聯。
  2. 限制憑證洩露風險:短期憑證限制了憑證被洩露時的風險。
  3. 支援密碼輪換:對於像 PLAIN 和 SCRAM 這樣根據密碼的 SASL 機制,可以透過新增定期登入來支援密碼輪換。重新驗證限制了使用舊密碼認證的連線上處理請求的時間。
  4. 強制重新驗證connections.max.reauth.ms 強制所有 SASL 機制(包括那些具有非到期憑證的機制)進行重新驗證。這限制了在憑證被復原後,它與活動連線相關聯的時間。