使用 Kafka ACL 控管存取權

本文說明如何在 Google Cloud Managed Service for Apache Kafka 中,使用 Apache Kafka 存取控制清單 (ACL) 控管存取權。

Apache Kafka ACL 可在 Kafka 叢集中提供精細的存取權控管機制。Managed Service for Apache Kafka 可啟用開箱即用的 StandardAuthorizer,將 ACL 儲存在以 KRaft 為基礎的 Kafka 叢集 metadata 中。

  • 這些 ACL 可控管哪些通過驗證的使用者,能在特定 Kafka 資源上執行特定作業,例如在主題上產生或取用訊息。

  • 這些 ACL 可用於控管與叢集的互動,方法是使用標準 Apache Kafka 用戶端,這類用戶端只會在初始連線時接受叢集層級的 IAM 檢查。詳情請參閱「使用 IAM 控管存取權」。

Kafka ACL 存取權控管的運作方式

用戶端會在叢集內與 Kafka 的標準 ACL 授權程式互動。授權者會評估相關的 Apache Kafka ACL,授權主體要求的特定作業,例如產生主題或從群組取用。用於 ACL 檢查的主體是透過下列其中一種驗證方法衍生而來:

  • SASL:IAM 主體,例如服務帳戶電子郵件地址。

  • mTLS:用戶端憑證中的識別名稱 (DN),可能經過主體對應規則轉換。

如要全面提升安全性,請設定下列項目:

  • 管理存取權的 IAM 權限。詳情請參閱「使用 IAM 控管存取權」。

  • Kafka ACL,可透過開放原始碼 Apache Kafka 用戶端存取叢集內資料及執行作業,與驗證方法無關。

使用 Apache Kafka ACL

Apache Kafka ACL 繫結的格式如下:


Principal P is [Allowed/Denied] Operation O From Host H on any resource matching Resource Pattern RP.

以下是格式的重要資訊:

  • 主體(P):獲得授權的使用者身分。前置字元為 User:

    • 如果是 SASL 驗證,這是 IAM 主體,例如 User:my-service-account@my-project.iam.gserviceaccount.com

    • 如果是 mTLS 驗證,這是指用戶端憑證中的識別名稱 (DN),例如 User:CN=my-client,OU=my-org-unit。確切格式取決於憑證的主體。 主體對應規則可以轉換這個值。

  • 權限類型(允許/拒絕):ACL 繫結是否允許或拒絕存取權。拒絕繫結的優先順序較高。

  • 作業(O):執行的動作,例如讀取、寫入或建立。 如要瞭解哪些作業適用於各種 Kafka 通訊協定的哪些資源,請參閱 Apache Kafka 說明文件中的「通訊協定作業和資源」。

  • 主機(H):發出要求的機器。由於 Managed Service for Apache Kafka 會轉譯用戶端網路位址,因此不支援使用 '*' 以外的主機。

  • 資源模式(RP):用於比對特定資源的模式。資源模式包含資源類型、資源名稱和模式類型 (LITERALPREFIXED)。

預設存取權

Managed Service for Apache Kafka 叢集會使用設為 true 的 Apache Kafka 屬性 allow.everyone.if.no.acl.found 運作。Kafka ACL 的存在與否直接決定資源的存取層級:

  • 如果未針對特定資源 (例如主題) 定義 Kafka ACL,系統會授予所有已驗證主體存取權。這項設定可讓 Managed Service for Apache Kafka 叢集立即運作,不必設定 ACL。

  • 只要為該資源定義任何 Kafka ACL,存取權就會受到限制。只有透過 Kafka ACL 中的 ALLOW 項目明確授予權限的主體,才能存取相符的資源 (除非 DENY 項目明確封鎖)。

Managed Service for Apache Kafka 會授予服務代理叢集的管理存取權。無論叢集中設定的其他 ACL 為何,服務代理都能透過這項存取權執行 Managed Service for Apache Kafka API 要求的作業。Managed Service for Apache Kafka 會修改 StandardAuthorizer 實作項目,修改後,服務代理商會獲得與超級使用者類似的權限,但無法執行讀取和寫入作業。你無法變更這項設定。

Kafka 主體

Managed Service for Apache Kafka 叢集的 Kafka 主體會以 Kafka StandardAuthorizer 前置字元 "User:" 指定。

  • 適用於 SASL/IAM:主體是Google Cloud 帳戶。舉例來說,如要授予服務帳戶 test-kafka-client@test-project.iam.gserviceaccount.com 存取權,請使用 Kafka 主體 "User:test-kafka-client@test-project.iam.gserviceaccount.com"。Kafka ACL 主體必須指定使用者、服務帳戶或個別 IAM 主體,但不得指定群組或主體集。Kafka ACL 不支援解析 Google Cloud 主體的群組成員資格。

  • 如果是 mTLS:主體是從用戶端憑證的主體辨別名稱 (DN) 衍生而來。例如:User:CN=client1,OU=dev,O=MyOrg,L=City,ST=State,C=US。您可以使用 mTLS 主體對應規則,將 DN 轉換為更易於使用的 ACL 主體字串。

如要建立適用於 Google 群組或主體集所有成員的 ACL,可以使用 Proxy 服務帳戶主體和服務帳戶模擬功能:

  1. 建立服務帳戶,做為群組的 Proxy。

  2. 將服務帳戶的服務帳戶權杖建立者角色授予 Google 群組或主體集。請參閱「管理服務帳戶的存取權」一文

  3. 為 Proxy 服務帳戶新增 Kafka ACL。主體範例如下: User:group-proxy@test-project.iam.gserviceaccount.com

  4. 在 Kafka 用戶端使用服務帳戶模擬,以服務帳戶身分向 Kafka 進行驗證。 Google Cloud IAM 會授權個別主體,使其成為允許模擬 Proxy 服務帳戶的群組成員。Kafka 會根據叢集中的現有 ACL 授權 Proxy 服務帳戶。

生產者和消費者的 Kafka 作業

作業是指對資源執行的動作。每個資源都會將作業對應至該資源的一或多個 Kafka 通訊協定要求。舉例來說,topic 資源類型的 READ 作業會對應至 FetchOffsetCommitTxnOffsetCommit Apache Kafka 通訊協定。

如要授予主體製作人主題存取權,請按照下列步驟操作:

  1. 在主題資源上,允許 WRITECREATE 作業。

  2. 如果使用交易 ID,請在交易 ID 資源上允許 WRITE 作業。

如要授予主體消費者主題存取權,請按照下列步驟操作:

  1. 在主題資源中,允許 READ 作業。

  2. 在消費者群組資源中,允許 READ 作業。

如要進一步瞭解 Kafka API 支援的資源有效作業,請參閱 Apache Kafka 說明文件中的「Operations and Resources on Protocols」。

設定 ACL,以預設拒絕存取

代管 Kafka 叢集已設定為 allow.everyone.if.no.acl.found = true。 因此,如果資源未設定任何 ACL,所有主體預設都能存取該資源。

如要設定類似 IAM 的 default-deny 行為,您可以先為叢集中所有資源的管理員使用者設定存取權。因此,每個資源都會取得定義的 ACL,且 allow.everyone.if.no.acl.found 行為會遭到抑制。 根據預設,凡是未獲 ALLOW ACL 明確允許的主體,都會遭到拒絕存取。

舉例來說,如要為服務帳戶 clusterAdmin@test-project.iam.gserviceaccount.com 設定叢集中所有資源的 ACL,請建立下列 ACL 項目。

下列 gcloud CLI 指令會將完整的管理存取權 (--operation=ALL) 授予名為 clusterAdmin@test-project.iam.gserviceaccount.com 的服務帳戶,讓該帳戶能存取特定區域中的特定 Kafka 叢集。這項權限可讓服務帳戶從任何主機對叢集執行任何作業。

gcloud managed-kafka acls add-acl-entry cluster \
    --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` \
    --operation=ALL \
    --permission-type=ALLOW \
    --host=* \
    --cluster=CLUSTER_ID \
    --location=LOCATION

下列 gcloud CLI 指令會授予名為 clusterAdmin@test-project.iam.gserviceaccount.com 的服務帳戶,對特定區域中特定 Kafka 叢集內的所有主題,具有完整管理存取權 (--operation=ALL)。這項權限可讓服務帳戶從任何主機對所有主題執行任何作業。

gcloud managed-kafka acls add-acl-entry allTopics \
    --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` \
    --operation=ALL \
    --permission-type=ALLOW \
    --host=* \
    --cluster=CLUSTER_ID \
    --location=LOCATION

下列 gcloud CLI 指令會將特定區域中特定 Kafka 叢集內所有消費者群組的完整管理存取權 (--operation=ALL) 授予名為 clusterAdmin@test-project.iam.gserviceaccount.com 的服務帳戶。這項權限可讓服務帳戶從任何主機對所有消費者群組執行任何作業。

gcloud managed-kafka acls add-acl-entry allConsumerGroups \
    --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` \
    --operation=ALL \
    --permission-type=ALLOW \
    --host=* \
    --cluster=CLUSTER_ID \
    --location=LOCATION

下列 gcloud CLI 指令會為特定區域中特定 Kafka 叢集內的所有交易 ID,授予名為 clusterAdmin@test-project.iam.gserviceaccount.com 的服務帳戶完整管理存取權 (--operation=ALL)。這項權限可讓服務帳戶對任何主機的所有交易 ID 執行任何作業。

gcloud managed-kafka acls add-acl-entry allTransactionalIds \
    --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` \
    --operation=ALL \
    --permission-type=ALLOW \
    --host=* \
    --cluster=CLUSTER_ID \
    --location=LOCATION

以下是指令的重要資訊:

  • --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com':適用 ACL 的主體。主體是Google Cloud 帳戶,並以 Kafka StandardAuthorizer 前置字元 User: 開頭。

  • --operation=all:要授予的 Kafka 作業,在本例中為完整存取權。

  • --permission-type=ALLOW:這個 ACL 項目會授予存取權。

  • --host='*':主體可從中存取資源的主機。'*' 授予任何主機的存取權。Managed Service for Apache Kafka 僅支援含有主機 '*' 的 ACL。

  • CLUSTER_ID:Managed Service for Apache Kafka 叢集的名稱。

  • LOCATION:Managed Service for Apache Kafka 叢集所在的 Google Cloud 區域,例如 us-central1

設定 ACL

您可以使用 Managed Service for Apache Kafka ACL API,或 Apache Kafka 授權程式 CLI kafka-acls.shAdmin Client 等開放原始碼 Apache Kafka 工具,設定 Apache Kafka ACL。

Managed Service for Apache Kafka 會依據 Kafka 資源模式整理 ACL。資源模式的定義如下:

  • 資源類型:叢集、主題、消費者群組或交易 ID

  • 模式類型:常值或前置字元 (名稱開頭為所提供字串的所有資源)

  • 資源名稱:ACL 項目套用的資源名稱或前置字元。

Managed Service for Apache Kafka ACL 資源代表為單一 Kafka 資源模式設定的所有存取權控管,以重複的 ACL 項目清單形式呈現。ACL 資源的名稱可明確識別 ACL 繫結的資源模式。詳情請參閱「ACL ID」。

您可以管理 ACL 資源層級的 Managed Service for Apache Kafka ACL (資源模式的所有 ACL 項目),也可以為 ACL 資源模式新增及移除個別 ACL 項目,以遞增方式管理。

詳情請參閱「建立代管 Kafka ACL」和「新增代管 Kafka ACL 項目」。

允許從主題讀取資料

如要允許以服務帳戶身分執行的開放原始碼 Apache Kafka 用戶端從 topic-name 主題讀取資料,請使用 managed-kafka acls add-acl-entry 指令建立 Managed Service for Apache Kafka ACL 項目:test-kafka-client@test-project.iam.gserviceaccount.com

gcloud managed-kafka acls add-acl-entry topic/topic-name \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=READ \
    --permission-type=ALLOW \
    --host='*'

以下是關於指令的重要資訊清單:

  • topic/topic-name:指定要授予存取權的 Managed Service for Apache Kafka 主題。請將 topic-name 替換成主題的實際名稱。前置字串 topic/ 表示這個 ACL 項目適用於特定 (字面) 主題資源模式。

  • LOCATION:Managed Service for Apache Kafka 叢集所在的 Google Cloud 區域,例如 us-central1

  • CLUSTER_ID:Managed Service for Apache Kafka 叢集的名稱。

  • --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com':適用 ACL 的主體。主體是Google Cloud 帳戶,並以 Kafka StandardAuthorizer 前置字元 User: 開頭。

  • --operation=READ:要授予的 Kafka 作業,在本例中為 READ

  • --permission-type=ALLOW:表示這個 ACL 項目授予存取權。

  • --host='*':指定主體可從哪個主機存取資源。'*' 授予任何主機的存取權。 Managed Service for Apache Kafka 僅支援主機為 '*' 的 ACL。

如要移除讀取權限,可以使用 remove-acl-entry 指令,並採用相同參數。

gcloud managed-kafka acls remove-acl-entry topic/topic-name \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=READ \
    --permission-type=ALLOW \
    --host='*'

允許寫入具有相同前置字串的所有主題

如要允許以服務帳戶身分執行的開放原始碼 Apache Kafka 用戶端寫入名稱開頭為前置字元 topic-prefix 的所有主題,請新增 Managed Kafka ACL 項目,如下所示:test-kafka-client@test-project.iam.gserviceaccount.com

gcloud managed-kafka acls add-acl-entry topicPrefixed/topic-prefix \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=WRITE \
    --permission-type=ALLOW \
    --host='*'

以下是關於指令的重要資訊清單:

  • topicPrefixed/topic-prefix:指定要授予存取權的 Managed Service for Apache Kafka 資源模式。將 topic-prefix 替換為主題的實際前置字元。topicPrefixed/ 前置字串表示這個 ACL 項目適用於前置字串資源模式:所有符合指定前置字串的主題。

  • PROJECT:Managed Service for Apache Kafka 叢集所在的 Google Cloud 專案 ID。

  • LOCATION:Managed Service for Apache Kafka 叢集所在的 Google Cloud 區域,例如 us-central1

  • CLUSTER_ID:Managed Service for Apache Kafka 叢集的名稱。

  • --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com':ACL 適用的主體。主體是Google Cloud 帳戶,並以 Kafka StandardAuthorizer 前置字元 User: 開頭。

  • --operation=WRITE:要授予的 Kafka 作業,在本例中為 WRITE

  • --permission-type=ALLOW:這個 ACL 項目會授予存取權。

  • --host='*':主體可從中存取資源的主機。'*' 授予任何主機的存取權。Managed Service for Apache Kafka 僅支援含有主機 '*' 的 ACL。

如要移除這個服務帳戶的寫入權限,請移除 ACL 項目:

gcloud managed-kafka acls remove-acl-entry topicPrefixed/topic-prefix \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=WRITE \
    --permission-type=ALLOW \
    --host='*'

拒絕修改所有主題

如要防止以服務帳戶 test-kafka-client@test-project.iam.gserviceaccount.com 執行的開放原始碼 Apache Kafka 用戶端修改叢集中的所有主題,您可以建立 Managed Service for Apache Kafka ACL 資源,並列出要拒絕所有主題 ALTERALTER_CONFIGSDELETE 作業的資源 AclEntry。這種方法會在單一設定中定義所需狀態。

或者,您也可以使用 gcloud managed-kafka acls add-acl-entry 指令,以命令式方式新增三項個別的 ACL 項目,達到相同結果。這個方法會執行指令,拒絕存取各項作業 ALTERALTER_CONFIGSDELETE,如下所示:

gcloud managed-kafka acls add-acl-entry allTopics \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=ALTER \
    --permission-type=DENY \
    --host='*'
gcloud managed-kafka acls add-acl-entry allTopics \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=ALTER_CONFIGS \
    --permission-type=DENY \
    --host='*'
gcloud managed-kafka acls add-acl-entry allTopics \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=DELETE \
    --permission-type=DENY \
    --host='*'

下列資訊適用於每個 add-acl-entry 指令:

  • allTopics:指定這項 ACL 適用於 Managed Service for Apache Kafka 叢集內的所有主題。

  • LOCATION:Managed Service for Apache Kafka 叢集所在的 Google Cloud 區域,例如 us-central1

  • CLUSTER_ID:Managed Service for Apache Kafka 叢集的名稱。

  • --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com': 指定 ACL 適用的主體。主體是Google Cloud 帳戶,並以 Kafka StandardAuthorizer 前置字元 User: 開頭。

  • --operation:指定遭拒的 Kafka 作業:

    • ALTER:包括變更分區數量或複寫因子的動作。

    • ALTER_CONFIGS:包括修改主題層級設定。

    • DELETE:包括刪除主題。

  • --permission-type=DENY:表示這些 ACL 項目會封鎖指定作業的存取權。

  • --host='*':指定無論要求來源主機為何,都適用這項拒絕。Managed Service for Apache Kafka 僅支援含有主機 '*' 的 ACL。

如要移除這些限制,請針對每個新增項目使用 remove-acl-entry 指令,並使用相同參數。舉例來說,如要重新允許刪除主題:

gcloud managed-kafka acls remove-acl-entry allTopics \
    --cluster=CLUSTER_ID \
    --location=LOCATION
    --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \
    --operation=DELETE \
    --permission-type=DENY \
    --host='*'

排解 ACL 問題

根據預設,Apache Kafka Standard Authorizer 會在授權遭拒時寫入稽核記錄。如果收到 Kafka 授權錯誤,可以搜尋叢集記錄中的 StandardAuthorizerData logAuditMessage,確認遭拒的主體、資源和作業。

舉例來說,以下是叢集記錄範例。

org.apache.kafka.metadata.authorizer.StandardAuthorizerData logAuditMessage\n
INFO: Principal = User:556291496362-compute@developer.iam.gserviceaccount.com is
Denied operation = DESCRIBE from host = 172.16.0.20 on resource = Topic:LITERAL:t1
for request = Metadata with resourceRefCount = 1 based on rule DefaultDeny

後續步驟

Apache Kafka® 是 The Apache Software Foundation 或其關聯企業在美國與/或其他國家/地區的註冊商標。