Refernece
Kafka 配置 SSL 加密和认证
- 生成证书。
- 创建证书签名请求。
- 将证书签名请求发送到证书颁发机构 (CA)。
- 登录到 CA 并为请求签名。
- 通过
scp
将签名的证书发回给 Broker 节点。 - 通过
scp
将 CA 的公共证书发送给 Broker节点。 - 获取所有证书后,将证书放入证书存储(keystore)。
生成证书和密钥
- 开启 SSL 加密,首先需要为服务器生成证书和密钥,可以通过Java的
$JAVA_HOME/bin/keytool
(Key and Certificate Management Tool
)命令生成。# `-alias` 对 keystore 存储的 item(密钥/证书) 的访问都要通过唯一的别名来进行,例如删除某个证书。别名不区分大小写,即 caroot 和 CARoot 指的是同一个 item。 $ keytool -keystore server.keystore.jks -alias kafkaserver -validity {validity} -genkey -keyalg RSA -destkeystoretype pkcs12 -ext SAN=DNS:{FQDN},IP:{IPADDRESS1} # 注意下面这项要与机器的完全限定域名(FQDN)相同,Client 会拿(CN)与(DNS)域名进行比较以确保它确实连接到所需的服务器,而不是恶意的服务器。 # 因此需要保证公用名(CN)与服务器的完全限定域名(FQDN) 精确相匹配, 您的名字与姓氏是什么? [Unknown]: server1.bjidc
- keystore: 是一个用来存储证书和密钥的文件,其中包含一个公私密钥对、一个标识该机器的证书,因此需要妥善保管,一般以
jks(Java KeyStore)
,crt
,key
结尾,主流证书格式之间是可以相互转换的,详细参考
- keystore: 是一个用来存储证书和密钥的文件,其中包含一个公私密钥对、一个标识该机器的证书,因此需要妥善保管,一般以
生成server.keystore.jks
后,集群中的每一台机器就拥有了一个公私密钥对、一个标识该机器的证书,但是,这个证书,是未签名的,攻击者同样可以创建这样一个证书,并用来假装是任何机器。因此,还需要为集群中的每个机器的证书进行签名,以防止这种伪造行为。
创建 Certificate Authority
- CA(Certificate Authority): 证书颁发机构,CA 负责签名证书,就像公安部出入境管理机构颁发护照,会给每本护照盖章,盖章后才会被其他部门认可。同样,CA 给证书签名,并加密,并保证签名证书很难伪造。因此,只要 CA 是真实的和值得信赖的,Client 就就能确信他们正连接到正确的机器。
$ man openssl
# req PKCS#10 X.509 Certificate Signing Request (CSR) Management.
$ openssl req --help
# -new new request.
# -x509 output a x509 structure instead of a cert. req.
# -keyout ca-key file to send the key to
# -out output file
# -days number of days a certificate generated by -x509 is valid for.
$ openssl req -new -x509 -keyout ca-key -out ca-cert -days 365
生成的 CA 是一个公私密钥对和证书,用来给其它证书签名,然后需要将生成的 CA 添加到 Client 和 Server 的truststore
,这样 Client 和 Server 就会信任这个 CA,并认可由该 CA 签名的证书。
$ keytool -keystore client.truststore.jks -alias CARoot -import -file ca-cert
$ keytool -keystore server.truststore.jks -alias CARoot -import -file ca-cert
当部署 SSL 到一个 Kafka 集群上时,可以用一个 CA 为集群中的所有证书签名,并使所有信任该 CA 的机器共享同一个truststore
,这样所有的机器都可以进行认证了。
签名证书
# 首先将第一步存储再`keystore`中的证书导出来
# -keystore 密钥库文件的位置
# -file 导出的证书文件
$ keytool -keystore server.keystore.jks -alias kafkaserver -certreq -file cert-file
# 然后通过 CA 签名
# -in 需要签名的证书文件
# -out 签名后的证书文件
$ openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed -days {validity} -CAcreateserial -passin pass:{ca-password}
# 把 CA 的证书导入到 keystore
$ keytool -keystore server.keystore.jks -alias CARoot -import -file ca-cert
# 签名后的证书导入到 keystore
$ keytool -keystore server.keystore.jks -alias kafkaserver -import -file cert-signed
证书签名流程:
配置 Kafka Broker
# 如果 broker 间的通信未启用 SSL,PLAINTEXT 和 SSL 端口都得有。
listeners=PLAINTEXT://server1.bjidc:9092,SSL://server1.bjidc:9093
ssl.keystore.location=/usr/local/kafka/ssl/server.keystore.jks
ssl.keystore.password=123456
ssl.key.password=123456
ssl.truststore.location=/usr/local/kafka/ssl/server.truststore.jks
ssl.truststore.password=123456
# required 客户端必须进行认证, requested 虽然需要认证,但没有证书的 client 仍然可以连接
ssl.client.auth=required
ssl.enabled.protocols=TLSv1.2,TLSv1.1,TLSv1
ssl.keystore.type=JKS
ssl.truststore.type=JKS
# 设置为 SSL 开启 SSL 加密
security.inter.broker.protocol=PLAINTEXT
配置 Kafka Client
security.protocol=SSL
ssl.truststore.location=/usr/local/kafka/ssl/client.truststore.jks
ssl.truststore.password=123456
ssl.keystore.location=/usr/local/kafka/ssl/client.keystore.jks
ssl.keystore.password=123456
ssl.key.password=123456
ssl.truststore.type=JKS
ssl.keystore.type=JKS
keytool 的使用
# 查看证书库中的证书
$ keytool -list -keystore server.keystore.jks
# 删除证书
$ keytool -delete -alias CARoot -keystore server.truststore.jks