编辑导读:本篇内容将进一步介绍 Kafka 中的认证、鉴权等概念。AutoMQ 是与 Apache Kafka 100% 完全兼容的新一代 Kafka,可以帮助用户降低 90%以上的 Kafka 成本并且进行极速地自动弹性。作为 Kafka 生态的忠实拥护者,我们也会持续致力于传播 Kafka 技术,欢迎关注我们。
我们在此前的文章《AutoMQ SASL 安全身份认证配置教程》[1]介绍过 Apache Kafka (以下简称 Kafka)服务端和客户端的 SASL 认证协议配置,并在《AutoMQ SSL 安全协议配置教程》[2]详细介绍了如何利用 SSL(TLS) 实现 Kafka 或 AutoMQ 的安全通信。本文将进一步概述 Kakfa 中的认证方法和鉴权策略,并通过一个例子来说明我们在真实应用场景中如何对 Kafka 或者 AutoMQ 集群开启身份认证和鉴权。
注意,本文默认 Kafka 集群是以 Kraft 模式工作的。
Listener、安全协议、认证与鉴权的关系
先回顾一下 listener 的作用。listener 是 Kafka 服务端定义监听地址(域名/IP + 端口)和安全协议的实体。一般情况下,我们可以利用多 listener 来差异化设置:
-
broker 与 broker 之间,controller 与 broker 之间,client 与 broker 之间的通信安全协议;
-
内网(局域网或 VPC 内部)访问 broker、外网访问 broker 时的通信安全协议;
我们可以将 listener name 跟安全协议进行映射,举例来说,Kafka 支持以下安全协议:
我们可以设置 client 与 broker 之间使用 SASL_SSL 协议保证加密性,而集群节点之间使用 SASL_PLAINTEXT 减少 CPU 加密解密的消耗:
listeners=EXTERNAL://:9092,BROKER://10.0.0.2:9094
advertised.listeners=EXTERNAL://broker1.example.com:9092,BROKER://broker1.local:9094
listener.security.protocol.map=EXTERNAL:SASL_SSL,BROKER:SASL_PLAINTEXT
inter.broker.listener.name=BROKER
下图展示了 Listener、安全协议、认证与鉴权之间的关系
安全协议决定了服务端和客户端之间的认证(Authentication)协议,而鉴权(Authorization)基本独立于认证,只校验通过认证的主体对请求中涉及的资源是否有操作权限。下文将详细介绍认证方法和鉴权规则。
认证
认证主体
先简单介绍一下认证主体的概念。
认证主体是对 client 的身份标识,对应一个 KafkaPrincipal 对象[5]。当 client 通过认证协议完成认证后,broker 侧会将该 KafkaPrincipal 对象塞入 RequestContext,并向上传递,以供后续鉴权。一个 KafkaPrincipal 对象主要包括主体类型(目前仅有"User"这一类别)以及一个名称(可以简单理解为 client 声明的用户名)。
认证协议
安全协议到认证协议之间的映射为:
-
PLAINTEXT:无认证;
-
SSL:无认证/mTLS;
-
SASL_PLAINTEXT: SASL;
-
SASL_SSL: SASL;
其中 SSL 如果想要利用 mTLS 进行认证,需要在 broker 侧开启对 client 的 SSL 验证:
ssl.client.auth=required
利用证书中的“DistinguishedName”字段[4]识别认证主体。由于认证通常涉及到用户的管理,这种通过证书进行认证的方式在增删用户时显得比较“笨重”(尤其是动态增删用户的场景),并不是主流的认证方式。
SASL 认证协议又可以进一步细分为以下认证机制:
-
GSSAPI:借助第三方 Kerberos[3](一种基于 ticket 的加密认证协议)服务器进行认证认证;
-
PLAIN:简单账密认证,注意它跟前文的 PLAINTEXT 不是一个概念;
-
SCRAM-SHA-256/512:基于 SCRAM 算法,由 Kafka 节点基于 record 自认证;
-
OAUTHBEARER:借助第三方 OAuth 服务器认证;
Kafka broker 允许同时启用多种 SASL 认证,例如同时启用 SCRAM-SHA-256/512 + PLAIN:
sasl.enabled.mechanisms=SCRAM-SHA-256,PLAIN,SCRAM-SHA-512
Broker 侧还需要额外的 JAAS 配置,在《AutoMQ SASL 安全身份认证配置教程》中已经提及,这里不再赘述。
需要注意的是,Kafka 提供了默认的 SASL/PLAIN 实现,需要在每个节点配置中显示声明账密信息。这种静态认证方式同样不利于用户的动态管理,可以通过集成外部的账密认证服务器来提供动态能力。
鉴权
鉴权是基于认证主体,检查是否有权限操作请求的资源。
鉴权配置
重要的配置包括:
-
authorizer.class.name:指定鉴权器,默认为空。Kraft 模式下可以填写官方提供的 “org.apache.kafka.metadata.authorizer.StandardAuthorizer”,基于 ACL(access control list)规则认证;
-
super.users:设置超级用户,默认为空。格式为 User:{userName}。这里指定的用户将不受 ACL 约束,直接拥有所有资源的所有操作权限;
-
allow.everyone.if.no.acl.found:指定资源没有任意 ACL 约束时的默认权限,默认为 false。false 表示仅允许 super user 操作,true 表示允许任意用户操作。
鉴权规则
Kafka 是基于 ACL(access control list) 规则限制用户对资源的访问的。一条 ACL 规则包含两部分:
-
ResourcePattern:声明资源及其匹配方式,包含:
-
ResourceType:资源类型,包括 TOPIC、GROUP(消费者组)、CLUSTER 等;
-
ResourceName:资源名称;
-
PatternType:资源匹配方式,包括 LITERAL(全文匹配) 和 PREFIXED(前缀匹配);
-
-
AccessControlEntry:用户限制信息,包括:
-
Principal:认证主体,其实就是个用户名;
-
Host:用户主机地址;
-
AclOperation:操作行为,包括 Read、Write、CREATE、DELETE 等;
-
AclPermissionType:允许/禁止。
-
一句话串联上述规则信息就是:
允许/禁止 来自 {Host} 的用户 {Principal} 对匹配类型为 {PatternType} 、名称为 {ResourceName} 的资源进行 {AclOperation} 操作。
当同时满足:
-
存在某条 ACL 允许用户操作
-
不存在任何一条 ACL 禁止用户操作
时,允许用户对资源进