7.3 使用SASL认证
1. JAAS配置
Kafka使用Java认证和授权服务(JAAS)进行SASL配置。
为broker配置JAAS
KafkaServer
是每个KafkaServer/Broker使用JAAS文件中的部分名称。本节为broker提供了SASL配置选项,包括进行broker之间通信所需的任何SASL客户端连接。客户端部分用于验证与zookeeper的SASL连接。它还允许broker在zookeeper节点上设置SASL ACL。并锁定这些节点,以便只有broker可以修改它。所有的broker必须有相同的principal名称。如果要使用客户端以外的名称,设置zookeeper.sasl.client(例如,-Dzookeeper.sasl.client = ZkClient)。
默认情况下,Zookeeper使用“zookeeper”作为服务名称。如果你需要修改,设置zookeeper.sasl.client.user(例如,-Dzookeeper.sasl.client.username=zk)
Kafka客户端的JAAS配置
客户端可以使用客户端配置属性sasl.jaas.config或使用broker类似的静态JAAS配置文件配置JAAS。
JAAS配置使用客户端配置属性
客户端可以将JAAS配置指定为生产者或消费者属性,而不创建物理配置文件。 此模式还使同一个JVM中的不同生产者和消费者通过为每个客户端指定不同的属性来使用不同的凭据。 如果指定了静态JAAS配置系统属性java.security.auth.login.config和客户端属性sasl.jaas.config,将使用客户端属性。
请参阅GSSAPI(Kerberos),PLAIN或SCRAM的配置例子。
使用静态配置文件的JAAS配置
使用静态JAAS配置文件来配置客户端上的SASL认证。
添加一个名为KafkaClient的客户端登录部分的JAAS配置文件。 在KafkaClient中为所选机制配置登录模块,如设置GSSAPI(Kerberos),PLAIN或SCRAM的示例中所述。 例如,GSSAPI凭据可以配置为:
KafkaClient { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/etc/security/keytabs/kafka_client.keytab" principal="[email protected]"; };
将JAAS配置文件位置作为JVM参数传递给每个客户端JVM。 例如:
-Djava.security.auth.login.config=/etc/kafka/kafka_client_jaas.conf
2. SASL配置
SASL可以使用PLAINTEXT或SSL作为传输层,分别使用安全协议SASL_PLAINTEXT或SASL_SSL。 如果使用SASL_SSL,则还必须配置SSL。
SASL机制
Kafka支持一下的SASL机制:
- GSSAPI (Kerberos)
- PLAIN
- SCRAM-SHA-256
- SCRAM-SHA-512
为Kafka broker配置SASL
在server.properteis配置一个SASL端口,SASL_PLAINTEXT或SASL_SSL至少增加一个到
listeners
,用逗号分隔:listeners=SASL_PLAINTEXT://host.name:port
如果你只配置一个SASL端口(如果你需要broker使用SASL互相验证),那么需要确保broker之间设置相同的SASL协议:
security.inter.broker.protocol=SASL_PLAINTEXT (or SASL_SSL)
选择一个或多个支持的机制,并通过以下的步骤为机器配置SASL。在broker之间启用多个机制:
为Kafka客户端配置SASL
SASL仅支持新的java生产者和消费者,不支持老的API。
要在客户端上配置SASL验证,选择在broker中启用的客户端身份验证的SASL机制,并按照以下步骤配置所选机制的SASL。
3. 使用SASL/Kerberos认证
预备知识
Kerberos
如果你已在使用Kerberos(如,使用Active Directory),则无需安装重新安装。否则,你将需要安装一个,Linux供应商有Kerberos安装和配置的简短说明(Ubuntu,Radhat)。请注意,如果你使用的是Oracle Java,你需要下载java版本的
JCE策略文件
,将它们复制到$JAVA_HOME/jre/lib/security
中(注意:必须替换!!).创建Kerberos Principals
如果你使用的是公司的Kerberos或Active Directory服务器,请向Kerberos管理员询问群集中每个broker的principal以及将使用Kerberos验证(通过客户端和工具)访问Kafka的每个操作系统用户。
如果你自己安装Kerberos,你需要通过以下命令创建你自己的principal。
sudo /usr/sbin/kadmin.local -q 'addprinc -randkey kafka/{hostname}@{REALM}' sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{keytabname}.keytab kafka/{hostname}@{REALM}"
确保使用主机名可以访问所有主机 - Kerberos要求所有的
host
都可以用其FQDN
解析所有主机。
配置Broker
添加一个JAAS文件,类似下面的每个kafka broker的配置目录。这个例子我们姑且命名为
kafka_server_jaas.conf
(注意,每个broker都应该有自己的密钥表)。```
KafkaServer {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/etc/security/keytabs/kafka_server.keytab"
principal="kafka/[email protected]";
};
// Zookeeper client authentication
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/etc/security/keytabs/kafka_server.keytab"
principal="kafka/[email protected]";
};
```
JAAS文件中的KafkaServer部分告诉broker哪个principal要使用,以及存储该principal的keytab的位置。它允许broker使用本节中指定的keytab进行登录。更多细节参见zookeeper的SASL配置。
通过JAAS和krb5文件位置(可选的)作为JVM参数传递到每个broker。(
更多细节
):-Djava.security.krb5.conf=/etc/kafka/krb5.conf -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
确保在JAAS文件的keytabs配置文件可被启动的Broker的操作系统员读取。
在server.properties中配置SASL端口和SASL机制,例如:
listeners=SASL_PLAINTEXT://host.name:port security.inter.broker.protocol=SASL_PLAINTEXT sasl.mechanism.inter.broker.protocol=GSSAPI sasl.enabled.mechanisms=GSSAPI
我们还必须在server.properties配置服务器名称,应与broker的principal名匹配,在上面的例子中,principal是"kafka/[email protected]", 所以:
sasl.kerberos.service.name=kafka
配置Kafka客户端
在客户端上配置SASL认证
客户端(生产者,消费者,connect,等等)用自己的principal进行集群认证(通常用相同名称作为运行客户端的用户)。因此,获取或根据需要创建这些principal。然后为每个客户端配置JAAS配置属性。JVM中的不同客户端通过指定不同的principal可以作为不同的用户运行。producer.properties或consumer.properties中的属性sasl.jaas.config描述了像生产者和消费者之类的客户端如何连接到Kafka Broker的。 以下是使用keytab的客户端的示例配置(推荐用于长时间运行的进程):
sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \ useKeyTab=true \ storeKey=true \ keyTab="/etc/security/keytabs/kafka_client.keytab" \ principal="[email protected]";
对于像kafka-console-consumer或kafka-console-producer这样的命令行工具,kinit可以与“useTicketCache=true"一起使用,如:
sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \ useTicketCache=true;
客户端的JAAS配置可以作为JVM参数,类似于broker。 客户端使用名为
KafkaClient
的login部分。 此选项仅允许JVM中所有客户端连接的一个用户。确保JAAS配置中的keytabls配置文件能被启动kafka客户端的操作系统用户读取。
可以将krb5文件位置作为JVM参数传递给每个客户端JVM(有关详细信息,请参阅此处):
-Djava.security.krb5.conf=/etc/kafka/krb5.conf
在 producer.properties 或 consumer.properties中配置以下属性:
security.protocol=SASL_PLAINTEXT (or SASL_SSL) sasl.mechanism=GSSAPI sasl.kerberos.service.name=kafka
使用SASL/PLAIN认证
SASL/PLAIN是一种简单的
用户名/密码
的认证机制,通常与TLS加密一起使用,以实现安全的认证。Kafka支持SASL/PLAIN的默认实现,可作为生产者的扩展使用。username用作ACL等配置已认证的
Principal
。配置Kafka Brokers
在每个Kafka broker的config目录下添加一个类似于下面的修改后的JAAS文件,我们姑且将其称为kafka_server_jaas.conf。
KafkaServer { org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="admin-secret" user_admin="admin-secret" user_alice="alice-secret"; };
此配置定义了2个用户(admin 和 alice)。 在
KafkaServer
中,username
和password
是broker用于初始化连接到其他的broker,在这个例子中,admin是broker之间通信的用户。user_userName
定义了所有连接到broker和broker验证的所有的客户端连接包括其他broker的用户密码。将JAAS配置文件位置作为JVM参数传递给每个Kafka broker:
-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
在server.properties中配置SASL端口和SASL机制。 例如:
listeners=SASL_SSL://host.name:port security.inter.broker.protocol=SASL_SSL sasl.mechanism.inter.broker.protocol=PLAIN sasl.enabled.mechanisms=PLAIN
配置kafka客户端
在客户端上配置SASL身份验证:
为producer.properties或consumer.properties中的每个客户端配置JAAS。登录模块展示了客户端如何连接Broker的(和生产者和消费者一样)。 以下是PLAIN机制的客户端的示例配置:
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ username="alice" \ password="alice-secret";
客户端选择用户名和密码为客户端配置连接的用户。 在此示例中,客户端以用户alice连接到broker。也可以通过在
sasl.jaas.config
中指定不同的用户名和密码,JVM中的不同客户端可以根据不同的用户来进行连接。客户端的JAAS配置可以指定为类似于这里描述的broker作为JVM参数。客户端使用的命名为
KafkaClient
。 此选项仅允许来自JVM的所有客户端连接中的一个用户。在producer.properties或consumer.properties中配置以下属性:
security.protocol=SASL_SSL sasl.mechanism=PLAIN
在生产者中使用SASL/PLAIN
SASL/PLAIN应仅用SSL作为传输层,以确保在没有加密的情况下不会在线上明文传输。
Kafka中SASL/PLAIN的默认实现是在JAAS配置文件中的用户名和密码,如下所示。为了避免在磁盘上存储密码,你可以自己用javax.security.auth.spi.LoginModule实现,从外部源获取用户名和密码。登录模块应该提供Subject的用户名作为公共证书和密码作为私人凭证。 可以使用默认实现org.apache.kafka.common.security.plain.PlainLoginModule作为参考。
在生产者系统中,外部认证服务器可以实现密码验证。Kafka broker可以与这些服务器集成(通过添加自己实现
javax.security.sasl.SaslServer
)。在这个包路径org.apache.kafka.common.security.plain
中,包括在kafka的默认的实现,可以作为一个参考的实例。必须在JVM中安装和注册新的Providers(提供者)。可以通过将提供程序类添加到CLASSPATH或打包成jar文件并将其添加到JAVA_HOME/lib/ext来安装提供者。
也可以通过添加Providers到安全属性文件
JAVA_HOME/lib/security/java.security
中静态的注册Providers。security.provider.n=providerClassName
其中,providerClassName是新Provider的全名,n是优先排序(较低的数字表明更高的优先权)
此外,你可以在运行时通过在客户端应用程序的开始调用
Security.addProvider
或登录模块中的静态初始化程序来动态注册provider。 例如:Security.addProvider(new PlainSaslServerProvider());
更多细节, 可查看 JCA。
使用 SASL/SCRAM 认证
SCRAM(Salted Challenge Response Authentication Mechanism)是SASL机制家族的一种,
,通过执行用户名/密码认证(如PLAIN和DIGEST-MD5)的传统机制来解决安全问题。 该机制在RFC 5802中定义。Kafka支持SCRAM-SHA-256和SCRAM-SHA-512,可与TLS一起使用执行安全认证。 用户名用作配置ACL等认证的principal。Kafka中的默认SCRAM实现是在Zookeeper中存储SCRAM的证书,适用于Zookeeper在私有网络上的Kafka安装。 有关详细信息,请参阅安全注意事项。创建 SCRAM 证书
Kafka的SCRAM实现使用Zookeeper作为证书存储。通过使用kafka-configs.sh来创建证书。 对于启用的每个SCRAM机制,必须通过使用机制名称添加配置来创建证书。 必须在kafka broker启动之前创建broker之间通信的证书。 客户端证书可以动态创建和更新,并且将使用更新后的证书来验证新的连接。
为用户
alice
创建SCRAM凭证(密码为alice-secret):bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'SCRAM-SHA-256=[iterations=8192,password=alice-secret],SCRAM-SHA-512=[password=alice-secret]' --entity-type users --entity-name alice
如果未指定迭代数,则使用默认迭代数为4096。 创建一个随机salt,由salt,迭代,StoredKey和ServerKey组成的SCRAM标识,都存储在Zookeeper中。 有关SCRAM身份和各个字段的详细信息,请参阅RFC 5802。
以下示例中,需要用户admin进行broker间通信,通过以下命令创建:
bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'SCRAM-SHA-256=[password=admin-secret],SCRAM-SHA-512=[password=admin-secret]' --entity-type users --entity-name admin
可以使用--describe列出现有的证书:
bin/kafka-configs.sh --zookeeper localhost:2181 --describe --entity-type users --entity-name alice
可以使用--delete为一个或多个SCRAM机制删除证书:
bin/kafka-configs.sh --zookeeper localhost:2181 --alter --delete-config 'SCRAM-SHA-512' --entity-type users --entity-name alice
配置Kafka Broker
在每个Kafka broker的config目录下添加一个类似于下面的JAAS文件,我们姑且将其称为kafka_server_jaas.conf:
KafkaServer { org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="admin-secret" };
其中,broker使用KafkaServer中的用户名和密码来和其他broker进行连接。 在这个例子中,admin是broker之间通信的用户。
JAAS配置文件的位置作为JVM参数传递给每个Kafka broker:
``` -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf
在server.properties中配置SASL端口和SASL机制。 例如:
```
3. ```
listeners=SASL_SSL://host.name:port
security.inter.broker.protocol=SASL_SSL
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256 (or SCRAM-SHA-512)
sasl.enabled.mechanisms=SCRAM-SHA-256 (or SCRAM-SHA-512)
```
配置kafka客户端
在客户端上配置SASL认证
为每个客户端配置JAAS配置(在producer.properteis或consumer.properteis)。登录模块展示了客户端(如生产者和消费者)如何连接到broker的。下面是配置了SCRAM机制的客户端的例子。
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \ username="alice" \ password="alice-secret";
客户端使用username和password来配置客户端连接的用户。在这个例子中,客户端使用用户alice连接broker。在JVM中不同的客户端连接不同的用户(通过在sasl.jaas.config中指定不同的用户名和密码)。
客户端的JAAS配置通过指定作为JVM的参数。使用名为KafkaCLient的客户端登录。此选择仅允许来自JVM的所有客户端连接中的一个用户。
在producer.properties或consumer.properties中配置以下参数:
security.protocol=SASL_SSL sasl.mechanism=SCRAM-SHA-256 (or SCRAM-SHA-512)
SASL/SCRAM安全注意事项
在kafka中SASL/SCRAM的默认实现SCRAM证书存储在Zookeeper中,这适用于Zookeeper安全和私有网络生产部署。
Kafka仅支持强散列函数SHA-256和SHA-512,最小迭代次数为4096.强散列函数结合强密码和高迭代数可以防止强制攻击(如果Zookeeper安全性受到威胁)。
SCRAM只能使用TLS加密,以防止拦截SCRAM交换。如果Zookeeper受到威胁,则可以防止字典或暴力攻击,和防止伪装模仿。
可以使用Zookeeper(不安全)安装自定义登录模块来覆盖默认的SASL/SCRAM实现。 详见这里。
更多的安全注意事项,可参考RFC5802。
在broker中启用多个SASL机制
在JAAS文件中的
KafkaServer
中启用所有机制的登录模块配置。例如:KafkaServer { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/etc/security/keytabs/kafka_server.keytab" principal="kafka/[email protected]"; org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="admin-secret" user_admin="admin-secret" user_alice="alice-secret"; };
在server.properties中启用SASL机制
sasl.enabled.mechanisms=GSSAPI,PLAIN,SCRAM-SHA-256,SCRAM-SHA-512
如果需要broker之间通讯,则在server.properteis中指定SASL安全协议和机制。
security.inter.broker.protocol=SASL_PLAINTEXT (or SASL_SSL) sasl.mechanism.inter.broker.protocol=GSSAPI (or one of the other enabled mechanisms)
按照机制 - GSSAPI(Kerberos),PLAIN和SCRAM中的具体步骤来配置启用的SASL机制。
在运行的集群中修改SASL机制
可以按照以下顺序在正在运行的群集中修改SASL机制:
将新SASL机制添加到每个broker上的server.properteis中的sasl.enabled.mechanisms上。更新JAAS配置文件以包括这两个机制,如这里所述。 逐步重启群集节点。
使用新机制重新启动集群。
要改变broker之间的通讯(如果需要),则设置在server.properteis中的sasl.mechanism.inter.broker.protocol为新的机制并逐个重启。
要移除老的机制(如果需要),从server.properties的sasl.enabled.mechanisms和JAAS配置文件中移除旧机制。然后依次重启。