一、
生成server broker证书仓库:
# 生成server证书仓库,alias指明一个公钥私钥对的入口名 keytool -keystore server.jks -alias server -validity 365 -genkey -keyalg RSA -storetype pkcs12 echo 01 > serial.txt touch index.txt
二、
生成自签名证书(ca、根证书):
# ca.cfg参考kafka官方文档 openssl req -x509 -config ca.cfg -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM
ca.cfg参考官网给出的:
HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ ca ] default_ca = CA_default # The default ca section [ CA_default ] base_dir = . certificate = $base_dir/cacert.pem # The CA certifcate private_key = $base_dir/cakey.pem # The CA private key new_certs_dir = $base_dir # Location for new certs after signing database = $base_dir/index.txt # Database index file serial = $base_dir/serial.txt # The current serial number default_days = 1000 # How long to certify for default_crl_days = 30 # How long before next CRL default_md = sha256 # Use public key default MD preserve = no # Keep passed DN ordering x509_extensions = ca_extensions # The extensions to add to the cert email_in_dn = no # Don't concat the email in the DN copy_extensions = copy # Required to copy SANs from CSR to cert #################################################################### [ req ] default_bits = 4096 default_keyfile = cakey.pem distinguished_name = ca_distinguished_name x509_extensions = ca_extensions string_mask = utf8only #################################################################### [ ca_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = DE stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Test Province localityName = Locality Name (eg, city) localityName_default = Test Town organizationName = Organization Name (eg, company) organizationName_default = Test Company organizationalUnitName = Organizational Unit (eg, division) organizationalUnitName_default = Test Unit commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = Test Name emailAddress = Email Address emailAddress_default = test@test.com #################################################################### [ ca_extensions ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always, issuer basicConstraints = critical, CA:true keyUsage = keyCertSign, cRLSign #################################################################### [ signing_policy ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ signing_req ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment
有了ca后,生成服务端ca证书仓库,并把ca加到服务端ca仓库中:
keytool -keystore server.ca.jks -alias ca -import -file cacert.pem
三、
签名服务端证书:
# 生成服务端签名请求 keytool -certreq -keystore server.jks -alias server -file server.csr # 用ca签名server.csr。policy、extensions 这些从ca.cfg里面的配置取 openssl ca -config ca.cfg -policy signing_policy -extensions signing_req -out server.pem -infiles server.csr # 把服务端证书加入证书仓库 # 注意要先导入cacert再导入server证书,否则报:keytool error: java.lang.Exception: Failed to establish chain from reply # alias用server这个入口,与之前的秘钥配成一对 keytool -keystore server.jks -alias ca -import -file cacert.pem keytool -keystore server.jks -alias server -import -file server.pem
注意:在填写COMMON NAME(Common Name (e.g. server FQDN or YOUR name))的时候,应该与服务端的域名一致,例如本例中就是local.kafka
否则客户端连接的时候会报java.security.cert.CertificateException: No name match
四、
客户端证书部分:
# 生成客户端证书仓库 keytool -keystore client.jks -alias client -validity 365 -genkey -keyalg RSA -storetype pkcs12 # 生成客户端证书签名请求 keytool -certreq -keystore client.jks -alias client -file client.csr
把client.csr扔给服务端(本案例是把ca放在服务端保存的),让ca签名:
# 在服务端执行 openssl ca -config ca.cfg -policy signing_policy -extensions signing_req -out client.pem -infiles client.csr
签好名后,把ca、客户端证书扔回给客户端:
# 回到客户端执行 # 把客户端证书加入客户端仓库 # 仍要注意先加入ca再加入客户端证书 # alias用client这个入口,配成公钥私钥对 keytool -keystore client.jks -alias ca -import -file cacert.pem keytool -keystore client.jks -alias client -import -file client.pem # 生成客户端ca仓库 keytool -keystore client.ca.jks -alias ca -import -file cacert.pem
五、
服务端。server.properties配置:
listeners=PLAINTEXT://0.0.0.0:9092,SSL://0.0.0.0:9093 #0.0.0.0表示接受任何ip的请求 advertised.listeners=PLAINTEXT://local.kafka:9092,SSL://local.kafka:9093 #hosts里面用local.kafka这个域名来访问这个broker ssl.keystore.location=/usr/local/src/kafka_2.13-2.6.0/config/ssl/server.jks #证书仓库,放了server的公钥私钥对、ca ssl.keystore.password=YOURPASSWORD ssl.key.password=YOURPASSWORD ssl.truststore.location=/usr/local/src/kafka_2.13-2.6.0/config/ssl/server.ca.jks #CA书仓库,专门放ca ssl.truststore.password=YOURPASSWORD ssl.client.auth=required #可选,具体参考kafka手册 ssl.enable.protocol=TLSv1.2 #可选,指定tls版本,具体参考kafka手册 ssl.keystore.type=JKS #可选,说明keystore类型 ssl.truststore.type=JKS
客户端。使用comsumer作为例子,新建consumer-ssl.properties:
security.protocol=SSL ssl.truststore.location=/usr/local/src/kafka_2.13-2.6.0/config/ssl/client.ca.jks ssl.truststore.password=YOURPASSWORD ssl.keystore.location=/usr/local/src/kafka_2.13-2.6.0/config/ssl/client.jks ssl.keystore.password=YOURPASSWORD ssl.key.password=YOURPASSWORD ssl.enabled.protocols=TLSv1.2 ssl.keystore.type=JKS ssl.truststore.type=JKS
./kafka-console-consumer.sh .... --consumer.config consumer-ssl.properties 进行加密消费