一.背景

kafka提供了多种安全认证机制,主要分为SSL和SASL2大类。其中SASL/PLAIN是基于账号密码的认证方式,比较常用。最近做了个kafka的鉴权,发现官网上讲的不是很清楚,网上各种博客倒是很多,但是良莠不齐,巨多坑。经过一天的研究,终于搞定了,特在此记录下。

二.环境

操作系统:linux

kafka版本:kafka_2.12-0.11.0.1

zookeeper版本:zookeeper-3.5.1-alpha

三.认证步骤

3.1.Zookeeper配置和启动

1.为zookeeper添加SASL支持,在配置文件zoo.cfg添加

authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
requireClientAuthScheme=sasl
jaasLoginRenew=3600000

2.新建zk_server_jaas.conf文件,为Zookeeper添加账号认证信息

这个文件你放在哪里随意,只要后面zkEnv配置正确的路径就好了。我是放在/home路径下。zk_server_jaas.conf文件的内容如下

Server {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="cluster"
password="clusterpasswd"
user_kafka="kafkapasswd";
};

username和paasword是zk集群之间的认证密码。

user_kafka="kafkapasswd"定义了一个用户"kafka",密码是"kafkapasswd",本次测试用户是kafka broker。

3.导入kafka的相关jar

由上一步可发现,认证方式使用的是Kafka的认证类org.apache.kafka.common.security.plain.PlainLoginModule。因此zk需要依赖几个jar包。

在/home下新建zk_sasl_dependency目录,从kafka/lib目录下复制以下几个jar包到该目录下。根据kafka版本不同,几个jar包的版本可能不一样

kafka-clients-0.11.0.1.jar
lz4-1.3.0.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
snappy-java-1.1.2.6.jar

4.修改zkEnv.sh

在zkEnv.sh添加

for i in /home/zk_sasl_dependency/*.jar;
do
CLASSPATH="$i:$CLASSPATH"
done
SERVER_JVMFLAGS=" -Djava.security.auth.login.config=/home/zk_server_jaas.conf "

关于这一步,网上的配置五花八门,但是原理都是jar包导入和认证信息配置。

在zk启动的时候导入/home/zk_sasl_dependency/的jar包,SERVER_JVMFLAGS配置jvm参数,导入zk的sasl认证信息。

5.启动zk服务端

执行./zkServer.sh start启动zk。如果启动异常查看日志排查问题。

3.2kafka配置和启动

1.新建kafka_server_jaas.conf,为kafka添加认证信息

KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="cluster"
password="cluster"
user_cluster=“clusterpasswd”
user_kafka="kafkapasswd" ;
};
Client{
org.apache.kafka.common.security.plain.PlainLoginModule required
username="kafka"
password="kafkapasswd";
};

KafkaServer,第一行指定了认证方法为PLAIN,usernam和password是kafka的多个broker之间进行认证的账号密码。

user_kafka="kafkapasswd"设置了用户kafka,密码为kafkapswd,用于客户端的生产者和消费者连接认证。

网上的说法是 Client,是kafka作为用户使用zk的认证信息,这里的username和password一定要和zk_server_jaas.conf的配置对的上。

但是我试验发现 user_cluster=“clusterpasswd”才是真正进行认证的信息,这个Client好像一点用没有,删掉也可以正常启动server,kafka服务也是正常的,费解啊!

2.在kafka的配置文件开启SASL认证

在server.properties添加如下信息

listeners=SASL_PLAINTEXT://(IP):9092
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=PLAIN
sasl.enabled.mechanisms=PLAIN
allow.everyone.if.no.acl.found=true

3.在server启动脚本JVM参数

我是直接在

export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"

添加了认证信息,修改后为

export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G -Djava.security.auth.login.config=/home/kafka_server_jaas.conf"

4.启动kafka服务端

./kafka-server-start.sh ../config/server.properties

kafka服务端正常启动后,应该会有类似下面这行的日志信息,说明认证功能开启成功

Registered broker 0 at path /brokers/ids/0 with addresses: EndPoint((IP),9092,ListenerName(SASL_PLAINTEXT),SASL_PLAINTEXT) (kafka.utils.ZkUtils)

3.3kafka的SASL认证功能认证和使用

1.使用kafka脚本认证

我们使用kafka自带的脚本进行认证。

1.新建kafka_client_jaas.conf,为客户端添加认证信息

在/home下新建kafka_client_jaas.conf,添加以下信息

KafkaClient {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="kafka"
password="kafkapasswd";
};

2.修改客户端配置信息

修改producer.properties和consumer.properties,添加认证机制

security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN

3.修改客户端启动脚本

修改kafka-console-producer.sh,配置认证文件kafka_client_jaas.conf,将

export KAFKA_HEAP_OPTS="-Xmx512M"
```修改为

export KAFKA_HEAP_OPTS="-Xmx512M -Djava.security.auth.login.config=/home/kafka_client_jaas.conf"

kafka-console-consumer.sh的修改类似。
4.客户端启动并认证
启动consumer

./bin/kafka-console-consumer.sh --bootstrap-server (IP):9092 --topic test --from-beginning --consumer.config config/consumer.properties

启动producer

./bin/kafka-console-producer.sh --broker-list (IP):9092 --topic test --producer.config configoducer.properties

producer端发送消息,consumer端成功接收到消息。
##2.Java客户端认证
```java
package com.zte.sdn.oscp.jms.kafka; import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.junit.Test; import java.util.Collections;
import java.util.Properties; public class KafkaTest { @Test
public void testProduct() throws Exception {
System.setProperty("java.security.auth.login.config", "F:/kafka_client_jaas.conf"); Properties props = new Properties();
props.put("bootstrap.servers", "IP:9092");
props.put("acks", "all");
props.put("retries", 0);
props.put("batch.size", 16384);
props.put("linger.ms", 1);
props.put("buffer.memory", 33554432);
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("security.protocol", "SASL_PLAINTEXT");
props.put("sasl.mechanism", "PLAIN"); Producer<String, String> producer = new KafkaProducer<>(props);
while (true){
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
producer.send(new ProducerRecord<>("kafkatest", Integer.toString(i), Integer.toString(i)));
}
System.out.println(System.currentTimeMillis()-startTime);
Thread.sleep(5000);
}
} @Test
public void testConsumer() throws Exception {
System.setProperty("java.security.auth.login.config", "F:/kafka_client_jaas.conf"); Properties props = new Properties();
props.put("bootstrap.servers", "(IP):9092");
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
props.put("group.id", "kafka_test_group");
props.put("session.timeout.ms", "6000");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("security.protocol", "SASL_PLAINTEXT");
props.put("sasl.mechanism", "PLAIN"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("kafkatest"));
while (true) {
long startTime = System.currentTimeMillis();
ConsumerRecords<String, String> records = consumer.poll(1000);
System.out.println(System.currentTimeMillis() - startTime);
System.out.println("recieve message number is " + records.count());
for (ConsumerRecord<String, String> record : records) {
System.out.printf("offset = %d, key = %s, value = %s, partition = %d %n",
record.offset(),
record.key(),
record.value(),
record.partition());
}
}
}
}

3.4客户端认证时延问题

认证时发现生产者和消费者和kafka的broker建立连接都有一定时延。在生产者的日志发现时延主要发生在

2018-12-17 10:55:46[DEBUG][kafka-producer-network-thread | producer-1]-NetworkClient.java: 762 - Initiating connection to node (IP):9092 (id: 0 rack: null)
2018-12-17 10:55:50[DEBUG][kafka-producer-network-thread | producer-1]-SaslClientAuthenticator.java: 209 - Set SASL client state to SEND_HANDSHAKE_REQUEST

难道客户端连接服务端时,认证时间需要这么长??

Kafka的安全认证机制SASL/PLAINTEXT的更多相关文章

  1. zookeeper acl认证机制及dubbo、kafka集成、zooviewer/idea zk插件配置

    ZooKeeper的ACL机制 zookeeper通过ACL机制控制znode节点的访问权限. 首先介绍下znode的5种操作权限:CREATE.READ.WRITE.DELETE.ADMIN 也就是 ...

  2. HTTP认证机制

    HTTP的询问/应答机制 如下图: 一个实例的图: 1.客户端请求资源 2.服务器对用户进行询问,在WWW-Authenticate首部中指明在哪里,如何进行认证 3.客户端会在Authenticat ...

  3. Kafka Kerberos 安全认证

    本主要介绍在 Kafka 中如何配置 Kerberos 认证,文中所使用到的软件版本:Java 1.8.0_261.Kafka_2.12-2.6.0.Kerberos 1.15.1. 1. Kerbe ...

  4. Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结

    Atitit HTTP认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结 1.1. 最广泛使用的是基本验证 ( ...

  5. WPS 认证机制

    WPS 认证机制 WPS(Wi-Fi Protected Setup,Wi-Fi保护设置)(有的叫做AOSS.有的叫做QSS,不过功能都一致.)是由Wi-Fi联盟组织实施的认证项目,主要致力于简化无线 ...

  6. 基于Token的WEB后台认证机制

    几种常用的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合RES ...

  7. 【转】跟我学Kafka之NIO通信机制

    from:云栖社区 玛德,今天又被人打脸了,小看人,艹,确实,相对比起来,在某些方面差一点,,,,该好好捋捋了,强化下短板,规划下日程,,,引以为耻,铭记于心. 跟我学Kafka之NIO通信机制   ...

  8. HTTP中的摘要认证机制

    引子: 指定和服务器端交互的HTTP方法,URL地址,即其他请求信息: Method:表示http请求方法,一般使用"GET","POST". url:表示请求 ...

  9. Kafka文件的存储机制

    Kafka文件的存储机制 同一个topic下有多个不同的partition,每个partition为一个目录,partition命名的规则是topic的名称加上一个序号,序号从0开始. 每一个part ...

随机推荐

  1. opencv图像直方图均衡化及其原理

    直方图均衡化是什么有什么用 先说什么是直方图均衡化,通俗的说,以灰度图为例,原图的某一个像素为x,经过某个函数变为y.形成新的图.新的图的灰度值的分布是均匀的,这个过程就叫直方图均衡化. 图像直方图均 ...

  2. JMS入门简介

    一.JMS是什么 1.JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中 ...

  3. Vue小事例

    login <!DOCTYPE html><html lang="ZH-cn"> <head> <meta charset="U ...

  4. Logback配置文件这么写,TPS提高10倍

    通过阅读本篇文章将了解到 1.日志输出到文件并根据LEVEL级别将日志分类保存到不同文件 2.通过异步输出日志减少磁盘IO提高性能 3.异步输出日志的原理 配置文件logback-spring.xml ...

  5. Source Maps简介

    提高网站性能最简单的方式之一是合并压缩JavaScript和CSS文件.但是当你需要调试这些压缩文件中的代码时,那将会是一场噩梦.不过也不用担心,souce maps将会帮你解决这一问题. Sourc ...

  6. 从原理层面掌握@ModelAttribute的使用(使用篇)【一起学Spring MVC】

    每篇一句 每个人都应该想清楚这个问题:你是祖师爷赏饭吃的,还是靠老天爷赏饭吃的 前言 上篇文章 描绘了@ModelAttribute的核心原理,这篇聚焦在场景使用上,演示@ModelAttribute ...

  7. 讲解开源项目:5分钟搭建私人Java博客系统

    本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和运行 Tale 项目.示例均在 Windows 操作系统下演示 本文作者:HelloGitHub-秦人 HelloGitHub 推出的< ...

  8. MongoDB实现评论榜

    Mongodb很适合做这件事,api的调用仅仅是使用到了入门级别的CRUD,理清楚了思路,编码也会顺风顺水,所以你会发现我在这篇博客中说的比编码还多 评论榜预期的功能 就像是StackOverFlow ...

  9. 第五章 函数day2

    5.2函数小高级 5.2.1 函数当参数 1 函数也可以当返回值 def v(dar): v = dar() def n (): print(444) v(n) # 实例2 def v(): prin ...

  10. Codeforces 976F

    题意略. 思路:为了保证每个点都有至少k条边覆盖,我们可以让二分图的左半边与源点s相连,连容量为indegree[i] - k的边(如果正着想不好想,我们可以想它的反面, 限制它反面的上限,从而保证我 ...