Kafka认证基本概念
一直以来,我们公司内网的Kafka集群都是在裸奔,只要知道端口号,任何人都能连上集群操作一番。直到有个主题莫名消失,才引起我们的警觉,是时候该考虑为它添加一套认证策略了。 认证和授权就是一对孪生兄弟,不过本文只讨论认证,对授权感兴趣的朋友快献上赞赞,点赞越多,更新越快,哈哈。
该如何为Kafka添加认证策略呢,我们考察了Kafka支持的认证方式如下:
- SASL/GSSAPI (Kerberos) - starting at version 0.9.0.0
- SASL/PLAIN - starting at version 0.10.0.0
- SASL/SCRAM-SHA-256 and SASL/SCRAM-SHA-512 - starting at version 0.10.2.0
- SASL/OAUTHBEARER - starting at version 2.0
因为我们的集群采用的是kraft模式部署,因此无需考虑ZooKeeper的认证问题。上面四种方式分别在不同的版本引入Kafka,考量使用哪个认证方式请先确认好你们的Kafka集群版本是否支持。
我在之前的文章中提到过4种安全协议,不要与这里的认证方式混淆,安全协议是配置到监听器端口上,声明了经过端口的流量是否需要认证和加密。
回顾四种安全协议:
- PLAINTEXT => 不需要认证,非加密通道传输
- SSL => 无需认证,使用SSL加密通道
- SASL_PLAINTEXT => 使用SASL认证,非加密通道传输
- SASL_SSL => 使用SASL认证并且SSL加密通道传输
既然我们讨论认证,那么留给我们的选择只有SASL_PLAINTEXT、SASL_SSL,也就是使用SASL认证有关的协议,其次考虑是否要走加密通道。如果走加密通道性能肯定是有损耗,因此大部分情况下都会选择认证不加密的方式,那我们只能选择SASL_PLAINTEXT这种安全协议。如果对于加密通道感兴趣的朋友多,后续也发文介绍一下,不过目前我们内部没有这个需求,现在只介绍认证策略。
何为SASL?
SASL全称是简单验证和安全层 (Simple Authentication and Security Layer, SASL),是一种网络协议,正式规范可以查看RFC 2222。简单来说,它是专为解决客户端与服务端的身份认证的协议。既然SASL是协议,那么上面的GSSAPI、PLAIN、SCRAM、OAUTHBEARER就是对该协议的4种实现。
GSSAPI
要使用GSSAPI,前提是有一套Kerberos服务。Kerberos是大数据生态中身份认证的一个组件,如果你们公司有大数据相关的部门,并且已经依托Kerberos搭建了身份认证系统,那么在此基础上接入Kafka的认证。如果没有的话,不建议使用该方式认证,因为这样会增加系统运维的复杂程度。
PLAIN
PLAIN是最简单的一种认证方式,只需要在节点启动前配置好用户名和密码。缺点是要修改用户名或密码只能重启集群。
SCRAM
为了解决PLAIN修改密码需要重启的问题,0.10.2.0版本中加入了SCRAM认证方式。允许在集群启动后添加删除用户或修改用户名及密码。
OAUTHBEARER
OAuth 2是一个授权框架,通常用于第三方应用程序获得对HTTP服务的有限访问。SASL/OAUTHBEARER使得该框架可以在SASL环境下使用,这样就不局限于HTTP协议了。从Kafka文档中了解到,该认证方式目前不建议用于生产环境,因此我们就不再叙述。
经过调研,我们认为PLAIN、SCRAM比较符合我们目前的情况,后面我们就分别演示这两种认证方式的配置方法。
什么是JAAS?
SASL在配置用到了JAAS,那什么是JAAS,它有什么作用呢?
JAAS全称是Java认证和授权服务(Java Authentication and Authorization Service),因为Kafka使用Jvm系语言开发,采用Java平台的方案也是水到渠成的事情。 我们不是为Kafka开发登录插件,因此无需深入了解JAAS,只需知道jaas配置文件的格式 与如何使用它即可。
1. Jaas配置文件的格式
下面是一个配置文件的例子:
ini
段名 {
模块名1 控制标志 选项1=值1 选项2=值2;
模块名2 控制标志 选项1=值1 选项2=值2;
};
段名
:登录上下文或安全域的名称。模块名
:登录模块的完全限定类名。控制标志
:指定登录模块的行为。常见的控制标志包括 "required"、"requisite"、"sufficient" 和 "optional"。选项X
:传递给登录模块的特定选项。
JAAS配置可以包含多个段,每个段代表不同的安全上下文或登录场景。可以在单个段中指定多个登录模块,JAAS会按照指定的顺序使用它们。
Kafka 示例:
ini
KafkaClient {
org.apache.kafka.common.security.plain.PlainLoginModule required username="your_kafka_username" password="your_kafka_password";
};
这个 JAAS 配置文件定义了一个名为 KafkaClient
的登录上下文。它使用了 Kafka 提供的 PlainLoginModule
,这是一种简单的用户名密码认证方式。在这个例子中,需要提供 Kafka 集群中的有效用户名和密码。
一般来说,Kafka JAAS 配置包括以下几个主要部分:
- 登录上下文名称:
- 在上述例子中,登录上下文的名称为
KafkaClient
。可以根据需要命名不同的登录上下文。
- 在上述例子中,登录上下文的名称为
- 登录模块和选项:
org.apache.kafka.common.security.plain.PlainLoginModule
是 Kafka 提供的一个用于用户名密码认证的登录模块。required
表示该模块是必需的,登录将失败(并且将不会尝试其他模块)如果它不成功。
- 模块特定选项:
- 在这个例子中,
username
和password
是PlainLoginModule
的特定选项,用于指定 Kafka 集群中的用户名和密码。
- 在这个例子中,
2. 指定读取Jaas配置文件路径
Java程序通过JVM参数的指定Jaas配置文件:
shell
KAFKA_OPTS=-Djava.security.auth.login.config==/opt/bitnami/kafka/config/kafka-server-jaas.conf
如果你是一个Java程序员,那么对于如何指定JVM参数就是小意思,即便不是Java程序员那也是小意思~
下面解释一下这段配置:
- Kafka提供了一个指定jvm参数的环境变量
KAFKA_OPTS
,Kafka启动脚本会把该参数传递给Kafka程序。 -D
是在命令行中指定jvm参数的前缀。java.security.auth.login.config
是具体参数。/opt/bitnami/kafka/config/kafka-server-jaas.conf
jaas配置文件的绝对路径。==
用于覆盖JVM默认的参数。
下篇文章我们采用SASL/PLAIN认证方式实战搭建Kafka集群。