目录
2.1. 为每个 kafka broker 生成 ssl 密钥和证书
2.1.1. 主机名验证(host name verification)
一. 前言
ssl(secure sockets layer)是一种网络协议,提供了一种在客户端和服务器之间建立安全连接的方法。启用 ssl 后,kafka 集群中的所有数据传输,包括生产者、消费者与 broker 之间的消息交互都会被加密,确保敏感信息在网络传输过程中不被窃听或篡改。
二. 使用 ssl 的加密和身份验证
apache kafka 允许客户端使用 ssl 对流量进行加密和身份验证。默认情况下,ssl 是禁用的,但如果需要,可以打开。以下段落详细解释了如何设置自己的 pki 基础设施,使用它来创建证书,并配置 kafka 来使用这些证书。
2.1. 为每个 kafka broker 生成 ssl 密钥和证书
部署一个或多个支持 ssl 的 broker 程序的第一步是为每个服务器生成一个 public/priate 密钥对。由于 kafka 希望所有密钥和证书都存储在密钥库中,因此我们将使用 java 的 keytool 命令来完成此任务。该工具支持两种不同的密钥存储格式,一种是 java 特定的 jks 格式(目前已弃用),另一种是 pkcs12。pkcs12 是 java 9 版本的默认格式,为了确保无论使用的 java 版本如何都使用此格式,以下所有命令都明确指定 pkcs12 格式。
> keytool -keystore {keystorefile} -alias localhost -validity {validity} -genkey -keyalg rsa -storetype pkcs12
您需要在上面的命令中指定两个参数:
- keystorefile:存储此 broker 的密钥(以及后来的证书)的密钥库文件。密钥库文件包含该 broker 的私钥和公钥,因此需要保持安全。理想情况下,这一步骤是在密钥将在其上使用的kafka broker 上运行的,因为该密钥永远不应该被传输/离开其目的服务器。
- validity:密钥的有效时间,以天为单位。请注意,这与证书的有效期不同,该有效期将在签署证书时确定。您可以使用同一密钥申请多个证书:如果您的密钥的有效期为10年,但您的ca 只会签署有效期为一年的证书,那么您可以在一段时间内将同一密钥与10个证书一起使用。
要获得可与刚创建的私钥一起使用的证书,需要创建证书签名请求。当由受信任的 ca 签名时,此签名请求会生成实际证书,然后可以将该证书安装在密钥库中并用于身份验证。
要生成证书签名请求,请对迄今为止创建的所有服务器密钥库运行以下命令。
> keytool -keystore server.keystore.jks -alias localhost -validity {validity} -genkey -keyalg rsa -destkeystoretype pkcs12 -ext san=dns:{fqdn},ip:{ipaddress1}
此命令假定您要将主机名信息添加到证书中,如果不是这样,则可以省略扩展参数 -ext san=dns:{fqdn},ip:{ipaddress1}。有关此方面的更多信息,请参见下文。
2.1.1. 主机名验证(host name verification)
主机名验证(如果启用)是根据服务器的实际主机名或 ip 地址检查连接到的服务器提供的证书中的属性的过程,以确保您确实连接到了正确的服务器。
进行此检查的主要原因是为了防止中间人攻击。对于 kafka,此检查已被默认禁用很长一段时间,但从 kafka 2.0.0 起,客户端连接和 broker 间连接默认启用服务器的主机名验证。
可以通过将 ssl.endpoint.identification.agorithm 设置为空字符串来禁用服务器主机名验证。
对于动态配置的 broker 监听器,可以使用 kafka-configs.sh 禁用主机名验证:
> bin/kafka-configs.sh --bootstrap-server localhost:9093 --entity-type brokers --entity-name 0 --alter --add-config "listener.name.internal.ssl.endpoint.identification.algorithm="
2.1.2. 注意(note)
通常情况下,禁用主机名验证没有什么好的理由,除了这是“让它正常工作”的最快方法,然后承诺“稍后有更多时间时修复它”!
在正确的时间进行主机名验证并不是那么困难,但一旦集群启动并运行,就会变得非常困难——帮自己一个忙,现在就做!
如果启用了主机名验证,客户端将根据以下两个字段之一验证服务器的完全限定域名(fqdn)或 ip 地址:
- 通用名称(cn)。
- 使用者备选名称(san)。
虽然 kafka 同时检查这两个字段,但自2000年以来,使用通用名称字段进行主机名验证的做法一直受到反对,如果可能的话,应该避免使用。此外,san 字段更加灵活,允许在证书中声明多个 dns 和 ip 条目。
另一个优点是,如果 san 字段用于主机名验证,则出于授权目的,可以将通用名称设置为更有意义的值。由于我们需要在签名证书中包含 san 字段,因此在生成签名请求时会指定该字段。它也可以在生成密钥对时指定,但不会自动复制到签名请求中。
要添加 san 字段,请将以下参数 -ext san=dns:{fqdn},ip:{ipaddress} 附加到 keytool 命令:
> keytool -keystore server.keystore.jks -alias localhost -validity {validity} -genkey -keyalg rsa -destkeystoretype pkcs12 -ext san=dns:{fqdn},ip:{ipaddress1}
发表评论