第 13 章 使用 Kerberos(GSSAPI)身份验证


AMQ Streams 支持使用 Kerberos(GSSAPI)身份验证协议来保护对 Kafka 集群的单点登录访问。GSSAPI 是一个用于 Kerberos 功能的 API 打包程序,使应用程序免受底层实施的变化。

Kerberos 是一种网络身份验证系统,允许客户端和服务器使用对称加密和受信任的第三方 - Kerberos 密钥分发中心(KDC)相互身份验证。

13.1. 设置 AMQ 流以使用 Kerberos(GSSAPI)身份验证

此流程演示了如何配置 AMQ Streams,以便 Kafka 客户端可以使用 Kerberos(GSSAPI)身份验证访问 Kafka 和 ZooKeeper。

该流程假定已在 Red Hat Enterprise Linux 主机上设置了 Kerberos krb5 资源服务器。

该流程演示了如何配置:

  1. 服务主体
  2. Kafka 代理使用 Kerberos 登录
  3. zookeeper 使用 Kerberos 登录
  4. 使用 Kerberos 身份验证访问 Kafka 的生产者和消费者客户端

该说明描述了在单个主机上为单个 ZooKeeper 和 Kafka 安装设置的 Kerberos,并为制作者和消费者客户端设置额外的配置。

先决条件

要配置 Kafka 和 ZooKeeper 以验证和授权 Kerberos 凭证,您需要:

  • 访问 Kerberos 服务器
  • 每个 Kafka 代理主机上的 Kerberos 客户端

有关设置 Kerberos 服务器的步骤以及代理主机上的客户端的详情,请查看 RHEL 设置配置中的示例 Kerberos

如何部署 Kerberos 取决于您的操作系统。红帽建议在 Red Hat Enterprise Linux 中设置 Kerberos 时使用 Identity Management(IdM)。Oracle 或 IBM JDK 的用户必须安装 Java 加密扩展(JCE)。

添加用于身份验证的服务主体

从您的 Kerberos 服务器,为 ZooKeeper、Kafka 代理以及 Kafka 制作者和消费者客户端创建服务主体(用户)。

服务主体必须使用 SERVICE-NAME/FULLY-QUALIFIED-HOST-NAME@DOMAIN-REALM 格式

  1. 通过 Kerberos KDC 创建服务主体,以及存储主要密钥的 keytab。

    例如:

    • zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM
    • kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM
    • producer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM
    • consumer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM

      ZooKeeper 服务主体必须具有与 Kafka config/server.properties 文件中的 zookeeper.connect 配置相同的主机名:

      zookeeper.connect=node1.example.redhat.com:2181

      如果主机名不同,则使用 localhost,身份验证将失败。

  2. 在主机上创建目录并添加 keytab 文件:

    例如:

    /opt/kafka/krb5/zookeeper-node1.keytab
    /opt/kafka/krb5/kafka-node1.keytab
    /opt/kafka/krb5/kafka-producer1.keytab
    /opt/kafka/krb5/kafka-consumer1.keytab
  3. 确保 kafka 用户可以访问该目录:

    chown kafka:kafka -R /opt/kafka/krb5

将 ZooKeeper 配置为使用 Kerberos 登录

将 ZooKeeper 配置为使用 Kerberos 密钥分发中心(KDC)通过之前为 zookeeper 创建的用户主体和 keytab 进行身份验证。

  1. 创建或修改 opt/kafka/config/jaas.conf 文件以支持 ZooKeeper 客户端和服务器操作:

    Client {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true 1
        storeKey=true 2
        useTicketCache=false 3
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab" 4
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM"; 5
    };
    
    Server {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        useTicketCache=false
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab"
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    
    QuorumServer {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab"
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    
    QuorumLearner {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        keyTab="/opt/kafka/krb5/zookeeper-node1.keytab"
        principal="zookeeper/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    1
    设置为 true,从 keytab 获取主密钥。
    2
    设置为 true 以存储主体密钥。
    3
    设置为 true,从票据缓存中获取 Ticket Granting Ticket(TGT)。
    4
    keyTab 属性指向从 Kerberos KDC 复制的 keytab 文件的位置。位置和文件必须可由 kafka 用户读取。
    5
    principal 属性配置为与 KDC 主机上创建的完全限定主体名称匹配,其格式为 SERVICE-NAME/FULLY-QUALIFIED-HOST-NAME@DOMAIN-NAME
  2. 编辑 opt/kafka/config/zookeeper.properties 以使用更新的 JAAS 配置:

    # ...
    
    requireClientAuthScheme=sasl
    jaasLoginRenew=3600000 1
    kerberos.removeHostFromPrincipal=false 2
    kerberos.removeRealmFromPrincipal=false 3
    quorum.auth.enableSasl=true 4
    quorum.auth.learnerRequireSasl=true 5
    quorum.auth.serverRequireSasl=true
    quorum.auth.learner.loginContext=QuorumLearner 6
    quorum.auth.server.loginContext=QuorumServer
    quorum.auth.kerberos.servicePrincipal=zookeeper/_HOST 7
    quorum.cnxn.threads.size=20
    1
    控制登录续订的频率(毫秒),可调整该频率以适应票据续订间隔。默认值为 1 小时。
    2
    指示主机名是否用作登录主体名称的一部分。如果对群集中的所有节点使用单个 keytab,这设置为 true。但是,建议为每个代理主机生成一个单独的 keytab 和完全限定主体来进行故障排除。
    3
    控制是否从 Kerberos 协商的主要名称中分离域名。建议将此设置设置为 false
    4
    为 ZooKeeper 服务器和客户端启用 SASL 身份验证机制。
    5
    RequireSasl 属性控制仲裁事件(如 master 选举)是否需要 SASL 身份验证。
    6
    loginContext 属性标识用于验证指定组件配置的 JAAS 配置中的登录上下文名称。loginContext 名称与 opt/kafka/config/jaas.conf 文件中相关部分的名称对应。
    7
    控制用于组成用于识别的主要名称的命名约定。占位符 _HOST 在运行时自动解析为由 server.1 属性定义的主机名。
  3. 使用 JVM 参数启动 ZooKeeper 以指定 Kerberos 登录配置:

    su - kafka
    export EXTRA_ARGS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties

    如果您不使用默认服务名称(zookeeper),请使用 -Dzookeeper.sasl.client.username=NAME 参数添加名称。

    注意

    如果您使用 /etc/krb5.conf 位置,在启动 ZooKeeper、Kafka 或者 Kafka 制作者和消费者时,您不需要指定 -Djava.security.krb5.conf=/etc/krb5.conf

将 Kafka 代理服务器配置为使用 Kerberos 登录

配置 Kafka,以使用 Kerberos 密钥分发中心(KDC)通过之前为 kafka 创建的用户主体和 keytab 进行身份验证。

  1. 使用以下元素修改 opt/kafka/config/jaas.conf 文件:

    KafkaServer {
        com.sun.security.auth.module.Krb5LoginModule required
        useKeyTab=true
        storeKey=true
        keyTab="/opt/kafka/krb5/kafka-node1.keytab"
        principal="kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
    KafkaClient {
        com.sun.security.auth.module.Krb5LoginModule required debug=true
        useKeyTab=true
        storeKey=true
        useTicketCache=false
        keyTab="/opt/kafka/krb5/kafka-node1.keytab"
        principal="kafka/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    };
  2. 通过修改 config/server.properties 文件中的监听程序配置,使监听器使用 SASL/GSSAPI 登录,在 Kafka 集群中配置每个代理。

    将 SASL 协议添加到监听器的安全协议映射中,并删除任何不需要的协议。

    例如:

    # ...
    broker.id=0
    # ...
    listeners=SECURE://:9092,REPLICATION://:9094 1
    inter.broker.listener.name=REPLICATION
    # ...
    listener.security.protocol.map=SECURE:SASL_PLAINTEXT,REPLICATION:SASL_PLAINTEXT 2
    # ..
    sasl.enabled.mechanisms=GSSAPI 3
    sasl.mechanism.inter.broker.protocol=GSSAPI 4
    sasl.kerberos.service.name=kafka 5
    ...
    1
    配置了两个侦听器:一个用于与客户端通用通信的安全监听程序(支持 TLS 用于通信),以及用于代理间通信的复制监听器。
    2
    对于启用 TLS 的监听程序,协议名称为 SASL_PLAINTEXT。对于非 TLS 的连接器,协议名称为 SASL_PLAINTEXT。如果不需要 SSL,您可以删除 ssl.* 属性。
    3
    用于 Kerberos 验证的 SASL 机制为 GSSAPI
    4
    用于代理间通信的 Kerberos 身份验证.
    5
    指定了用于身份验证请求的服务名称,以便将其与可能使用相同的 Kerberos 配置的其他服务区分开来。
  3. 使用 JVM 参数启动 Kafka 代理,以指定 Kerberos 登录配置:

    su - kafka
    export KAFKA_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Djava.security.auth.login.config=/opt/kafka/config/jaas.conf"; /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

    如果之前配置了 broker 和 ZooKeeper 集群,并使用基于非 Kerberos 的身份验证系统,则可以启动 ZooKeeper 和代理集群,并检查日志中的配置错误。

    在启动代理和 Zookeeper 实例后,集群现在被配置用于 Kerberos 身份验证。

配置 Kafka 制作者和消费者客户端以使用 Kerberos 身份验证

配置 Kafka 制作者和消费者客户端,以使用 Kerberos 密钥分发中心(KDC)通过之前为 producer1consumer1 创建的用户主体和 keytab 进行身份验证。

  1. 将 Kerberos 配置添加到制作者或使用者配置文件。

    例如:

    /opt/kafka/config/producer.properties

    # ...
    sasl.mechanism=GSSAPI 1
    security.protocol=SASL_PLAINTEXT 2
    sasl.kerberos.service.name=kafka 3
    sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \ 4
        useKeyTab=true  \
        useTicketCache=false \
        storeKey=true  \
        keyTab="/opt/kafka/krb5/producer1.keytab" \
        principal="producer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    # ...

    1
    Kerberos(GSSAPI)身份验证配置.
    2
    Kerberos 使用 SASL 纯文本(用户名/密码)安全协议。
    3
    在 Kerberos KDC 中配置的 Kafka 的服务主体(用户)。
    4
    使用 jaas.conf 中定义的相同属性配置 JAAS。

    /opt/kafka/config/consumer.properties

    # ...
    sasl.mechanism=GSSAPI
    security.protocol=SASL_PLAINTEXT
    sasl.kerberos.service.name=kafka
    sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
        useKeyTab=true  \
        useTicketCache=false \
        storeKey=true  \
        keyTab="/opt/kafka/krb5/consumer1.keytab" \
        principal="consumer1/node1.example.redhat.com@EXAMPLE.REDHAT.COM";
    # ...

  2. 运行客户端以验证您可以从 Kafka 代理发送和接收消息。

    制作者客户端:

    export KAFKA_HEAP_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true"; /opt/kafka/bin/kafka-console-producer.sh --producer.config /opt/kafka/config/producer.properties  --topic topic1 --bootstrap-server node1.example.redhat.com:9094

    消费者客户端:

    export KAFKA_HEAP_OPTS="-Djava.security.krb5.conf=/etc/krb5.conf -Dsun.security.krb5.debug=true"; /opt/kafka/bin/kafka-console-consumer.sh --consumer.config /opt/kafka/config/consumer.properties  --topic topic1 --bootstrap-server node1.example.redhat.com:9094
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.