Go 萨拉玛无法与卡夫卡服务器通话
所以我试图配置一个Sarama(kafka的原生go客户端)生产者客户端。我已相应地配置了TLS,确保使用正确的密码生成客户端证书。我初始化客户端的Go代码如下所示:Go 萨拉玛无法与卡夫卡服务器通话,go,apache-kafka,sarama,Go,Apache Kafka,Sarama,所以我试图配置一个Sarama(kafka的原生go客户端)生产者客户端。我已相应地配置了TLS,确保使用正确的密码生成客户端证书。我初始化客户端的Go代码如下所示: import ( "crypto/tls" "crypto/x509" "encoding/pem" "io/ioutil" "net" "path/filepath" "github.com/Shopify/sarama" log "github.com/siru
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"io/ioutil"
"net"
"path/filepath"
"github.com/Shopify/sarama"
log "github.com/sirupsen/logrus"
)
const (
certFile = "client_ingestion_client.pem"
keyFile = "client_ingestion_client.key"
)
func InitKafkaClient(host string, port string, certPath string) (sarama.AsyncProducer, error) {
cf := filepath.Join(certPath, certFile)
kf := filepath.Join(certPath, keyFile)
// Log cert and key path
log.Debugln(cf)
log.Debugln(kf)
// Read the cert in
certIn, err := ioutil.ReadFile(cf)
if err != nil {
log.Error("cannot read cert", err)
return nil, err
}
// Read & decode the encrypted key file with the pass to make tls work
keyIn, err := ioutil.ReadFile(kf)
if err != nil {
log.Error("cannot read key", err)
return nil, err
}
// Decode and decrypt our PEM block as DER
decodedPEM, _ := pem.Decode([]byte(keyIn))
decrypedPemBlock, err := x509.DecryptPEMBlock(decodedPEM, []byte("m4d3ups3curity4k4fka?"))
if err != nil {
log.Error("cannot decrypt pem block", err)
return nil, err
}
// Parse the DER encoded block as PEM
rsaKey, err := x509.ParsePKCS1ParrivateKey(decrypedPemBlock)
if err != nil {
log.Error("failed to parse rsa as pem", err)
return nil, err
}
// Marshal the pem encoded RSA key to bytes in memory
pemdata := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(rsaKey),
},
)
if err != nil {
log.Error("cannot marshal rsa as pem in memory", err)
return nil, err
}
// Load our decrypted key pair
crt, err := tls.X509KeyPair(certIn, pemdata)
if err != nil {
log.Error("cannot load key pair", err)
return nil, err
}
config := sarama.NewConfig()
config.Net.TLS.Enable = true
config.Net.TLS.Config = &tls.Config{
Certificates: []tls.Certificate{crt},
CipherSuites: []uint16{
tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
},
}
// Setting this allows us not to read from successes channel
config.Producer.Return.Successes = false
// Setting this allows us not to read from errors channel
config.Producer.Return.Errors = false
client, err := sarama.NewClient([]string{net.JoinHostPort(host, port)}, config)
if err != nil {
return nil, err
}
return sarama.NewAsyncProducerFromClient(client)
}
当我初始化代码时,会出现一个错误,错误是:
time=“2018-01-19T15:31:38Z”level=error msg=“尝试设置卡夫卡时出错:卡夫卡:客户端已没有可用的代理可与之对话(您的群集是否可访问?)”
我已验证卡夫卡主机是可访问的,并且可以连接到。见下文
我通过检查从go代码到从openssl rsa-in-client\u inspection\u client.key-out decrypted.key
命令生成的输出,验证密钥是否正确解密。我还确保使用keytool正确生成密钥,并使用正确的标志,包括中建议的-keylag RSA标志
我还运行了openssl s_client-connect$KAFKA_HOST:$KAFKA_PORT
,得到了以下响应
verify error:num=19:self signed certificate in certificate chain
139901934057376:error:1408E0F4:SSL routines:ssl3_get_message:unexpected message:s3_both.c:408:
验证错误很好,因为我使用的是自签名证书,但我不知道下面的错误是关于什么的。也许这就是我问题的原因
此外,我得到以下信息:
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4668 bytes and written 169 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 5A6216C765EF33BC85FACE82B01BC506358F4D62C77817A1F7EEFB50941DAEC9
Session-ID-ctx:
Master-Key: F8641FBF63A0AC7AB2D6D941C421DCA44550448524DADF4F0A7943F7928E65D5773E60A45212A7F320B250595AA6737B
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1516377799
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
---
由于此密码在openssl协议中引用:
ECDHE-RSA-AES128-GCM-SHA256
我尝试将这个
tls.tls\u RSA\u WITH_AES\u 128\u GCM\u SHA256
添加到我的go代码中,这看起来非常匹配,但我在go WITH中收到了相同的错误消息,说它已经没有可用的代理可以与之对话了。因此我发现了我的问题。原来kafka部署的子域具有自签名证书,因此我必须在客户端的config.Net.Tls.config结构中设置unsecureskipverify:true
。因此,代码如下所示:
config.Net.TLS.Config = &tls.Config{
Certificates: []tls.Certificate{crt},
InsecureSkipVerify: true,
}
也不需要包含密码套件。关闭TLS后,您可以连接吗?这是我要尝试的第一件事。不安全的SkipVerify不会禁用主机名检查。它实际上根本不检查证书。通常,需要将tls.Config.ServerName设置为与所连接的服务器证书中预期的CN匹配。这种关于禁用证书检查的空洞建议是使用TLS的Go代码中普遍存在的漏洞。UnsecureSkipVerify只有少数合法用途,其中证书实际上是通过自定义算法验证的,或者仅用于获取服务器证书并立即断开连接;一般在服务器上学习CN。