Kafka 支持身份认证和权限控制,主要通过以下几种机制来确保安全性:
1. 身份认证(Authentication)
Kafka支持基于 SASL(Simple Authentication and Security Layer) 和 SSL(Secure Sockets Layer) 的身份认证:
- SASL:支持多种机制,如
PLAIN、SCRAM-SHA-256、SCRAM-SHA-512、GSSAPI(Kerberos)。 - SSL/TLS:可以使用SSL证书对客户端和服务器进行双向认证。
2. 权限控制(Authorization)
Kafka提供基于 ACL(Access Control List,访问控制列表) 的权限管理,权限级别包括:
Read:允许消费者消费消息Write:允许生产者发送消息Create:允许创建主题Describe:允许查看集群或主题的元数据
Kafka使用 Zookeeper 来存储ACL信息,可以通过 kafka-acls.sh 命令行工具管理权限。
3. 数据加密(Encryption)
- SSL/TLS加密:可以加密Kafka的网络通信,防止数据被窃听。
- 磁盘加密:Kafka本身不提供磁盘加密,但可以使用操作系统或文件系统级别的加密机制。
4. 多租户安全
Kafka支持为不同的租户或应用设置独立的权限,确保数据隔离,防止未经授权的访问。
适用场景
- 企业级Kafka集群,需要身份认证和权限控制,防止未经授权的访问。
- 金融、医疗等行业,对数据安全性要求高,需要数据加密和访问控制。
下面是一个使用 Kafka + SASL/SSL 进行身份认证的 Java 生产者和消费者示例。
1. Kafka 服务器端配置(server.properties)
在 Kafka 服务器端,需要启用 SASL_PLAINTEXT 认证机制,并配置 ACL 权限。
listeners=SASL_PLAINTEXT://:9092
advertised.listeners=SASL_PLAINTEXT://localhost:9092
security.inter.broker.protocol=SASL_PLAINTEXT
# 配置认证方式
sasl.mechanism.inter.broker.protocol=PLAIN
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
super.users=User:admin
# 启用ACL权限控制
allow.everyone.if.no.acl.found=false
2. 配置 Kafka 客户端的 jaas.conf
Kafka 需要使用 JAAS(Java Authentication and Authorization Service)来进行身份认证。
创建 kafka_client_jaas.conf 文件:
KafkaClient {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="testuser"
password="testpassword";
};
注意:
username="testuser"和password="testpassword"需要与 Kafka 服务器的 ACL 认证信息匹配。- 这个文件可以通过
-Djava.security.auth.login.config=/path/to/kafka_client_jaas.conf方式加载。
3. Java 生产者代码(Kafka Producer)
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
public class SecureKafkaProducer {
public static void main(String[] args) {
String topic = "secure_topic";
// Kafka 配置
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// SASL 认证配置
props.put("security.protocol", "SASL_PLAINTEXT");
props.put("sasl.mechanism", "PLAIN");
// 创建生产者
Producer<String, String> producer = new KafkaProducer<>(props);
try {
for (int i = 0; i < 5; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "Secure message " + i);
producer.send(record, (metadata, exception) -> {
if (exception == null) {
System.out.println("Sent message: " + record.value() + " to partition " + metadata.partition());
} else {
exception.printStackTrace();
}
});
}
} finally {
producer.close();
}
}
}
4. Java 消费者代码(Kafka Consumer)
import org.apache.kafka.clients.consumer.*;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
public class SecureKafkaConsumer {
public static void main(String[] args) {
String topic = "secure_topic";
// Kafka 配置
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "secure_group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
// SASL 认证配置
props.put("security.protocol", "SASL_PLAINTEXT");
props.put("sasl.mechanism", "PLAIN");
// 创建消费者
Consumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList(topic));
try {
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));
for (ConsumerRecord<String, String> record : records) {
System.out.printf("Received message: key=%s, value=%s, partition=%d, offset=%d%n",
record.key(), record.value(), record.partition(), record.offset());
}
}
} finally {
consumer.close();
}
}
}
5. 运行 Java 代码
- 启动 Kafka,并确保 SASL 配置生效。
- 运行生产者:
java -Djava.security.auth.login.config=kafka_client_jaas.conf SecureKafkaProducer - 运行消费者:
java -Djava.security.auth.login.config=kafka_client_jaas.conf SecureKafkaConsumer
总结
- Kafka 服务器端 需要启用
SASL_PLAINTEXT认证,并配置 ACL 权限。 - 客户端(生产者/消费者) 需要指定
security.protocol和sasl.mechanism。 - JAAS 配置 用于存储 Kafka 认证信息。
这样,Kafka 的身份认证机制就成功生效了。
如果你是 本地开发 环境使用 Kafka 认证机制,建议按以下步骤配置和运行,以便快速测试 SASL_PLAINTEXT 认证。
1. 安装 Kafka 并启用 SASL 认证
确保你已经安装了 Kafka,并且 kafka-server-start.sh 可以正常启动。
修改 config/server.properties,添加如下配置:
# 监听SASL_PLAINTEXT
listeners=SASL_PLAINTEXT://localhost:9092
advertised.listeners=SASL_PLAINTEXT://localhost:9092
security.inter.broker.protocol=SASL_PLAINTEXT
# 启用SASL PLAIN认证
sasl.mechanism.inter.broker.protocol=PLAIN
sasl.enabled.mechanisms=PLAIN
# 配置ACL权限控制
authorizer.class.name=kafka.security.auth.SimpleAclAuthorizer
allow.everyone.if.no.acl.found=false
super.users=User:admin
解释:
listeners&advertised.listeners:Kafka 监听的地址和端口。security.inter.broker.protocol:Kafka 内部通信使用SASL_PLAINTEXT。sasl.enabled.mechanisms=PLAIN:启用 SASL/PLAIN 认证机制。
2. 配置 Kafka 的 JAAS 认证
创建 config/kafka_server_jaas.conf:
KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="admin-secret"
user_admin="admin-secret"
user_testuser="testpassword";
};
解释:
username="admin":Kafka 进程运行的账号。user_testuser="testpassword":为testuser账号设置密码,客户端将使用此账号认证。
然后,在 config/kafka-run-class.sh 末尾追加:
export KAFKA_OPTS="-Djava.security.auth.login.config=/path/to/kafka_server_jaas.conf"
或者 在启动 Kafka 时指定:
export KAFKA_OPTS="-Djava.security.auth.login.config=/path/to/kafka_server_jaas.conf"
bin/kafka-server-start.sh config/server.properties
3. 配置 Kafka ACL 访问控制
创建一个 Kafka 主题:
bin/kafka-topics.sh --create --topic secure_topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
给 testuser 账号赋予生产和消费权限:
bin/kafka-acls.sh --bootstrap-server localhost:9092 --add --allow-principal User:testuser --operation All --topic secure_topic
解释:
--allow-principal User:testuser允许testuser访问secure_topic。
4. 配置 Java 客户端
创建 kafka_client_jaas.conf:
KafkaClient {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="testuser"
password="testpassword";
};
运行 Java 程序时,通过 -Djava.security.auth.login.config 指定此文件。
5. Java 生产者代码
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
public class SecureKafkaProducer {
public static void main(String[] args) {
String topic = "secure_topic";
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// SASL 认证配置
props.put("security.protocol", "SASL_PLAINTEXT");
props.put("sasl.mechanism", "PLAIN");
Producer<String, String> producer = new KafkaProducer<>(props);
try {
for (int i = 0; i < 5; i++) {
ProducerRecord<String, String> record = new ProducerRecord<>(topic, "key-" + i, "Secure message " + i);
producer.send(record, (metadata, exception) -> {
if (exception == null) {
System.out.println("Sent message: " + record.value() + " to partition " + metadata.partition());
} else {
exception.printStackTrace();
}
});
}
} finally {
producer.close();
}
}
}
运行生产者
java -Djava.security.auth.login.config=kafka_client_jaas.conf SecureKafkaProducer
6. Java 消费者代码
import org.apache.kafka.clients.consumer.*;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
public class SecureKafkaConsumer {
public static void main(String[] args) {
String topic = "secure_topic";
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "secure_group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
// SASL 认证配置
props.put("security.protocol", "SASL_PLAINTEXT");
props.put("sasl.mechanism", "PLAIN");
Consumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList(topic));
try {
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));
for (ConsumerRecord<String, String> record : records) {
System.out.printf("Received message: key=%s, value=%s, partition=%d, offset=%d%n",
record.key(), record.value(), record.partition(), record.offset());
}
}
} finally {
consumer.close();
}
}
}
运行消费者
java -Djava.security.auth.login.config=kafka_client_jaas.conf SecureKafkaConsumer
7. 验证
- 生产者 应该能成功发送消息到
secure_topic。 - 消费者 应该能接收到消息。
如果报 org.apache.kafka.common.errors.TopicAuthorizationException,请检查 ACL:
bin/kafka-acls.sh --bootstrap-server localhost:9092 --list
然后为 testuser 赋予权限:
bin/kafka-acls.sh --bootstrap-server localhost:9092 --add --allow-principal User:testuser --operation All --topic secure_topic
总结
在 本地开发 环境下,启用 Kafka SASL_PLAINTEXT 认证的完整流程:
- 配置 Kafka 服务器(
server.properties)开启 SASL 认证。 - 创建
kafka_server_jaas.conf并加载到 Kafka 进程。 - 创建 ACL 规则,给
testuser授权访问secure_topic。 - 创建
kafka_client_jaas.conf,用于 Java 生产者/消费者认证。 - 运行 Java 代码,并用
-Djava.security.auth.login.config指定认证文件。
这样,你的本地 Kafka 就具备了 身份认证(SASL_PLAINTEXT)+ 权限控制(ACL) 机制!如果你还需要 SSL 加密 或 更复杂的认证机制(Kerberos、SCRAM),可以再进一步配置。🎯
5712

被折叠的 条评论
为什么被折叠?



