golang连接带ssl认证rabbitmq证书验证问题

551 阅读1分钟

golang的amqp库提供了使用ssl认证的demo,代码 使用自签名的证书,连接的demo如下

cfg := new(tls.Config)
cfg.RootCAs = x509.NewCertPool()
if ca, err := ioutil.ReadFile(config.RabbitMq.CACert); err == nil {
   cfg.RootCAs.AppendCertsFromPEM(ca)
}
if cert, err := tls.LoadX509KeyPair(config.RabbitMq.ClientCert, config.RabbitMq.ClientKey); err == nil {
   cfg.Certificates = append(cfg.Certificates, cert)
}

mqUrl := amqp.URI{
   Scheme:   "amqps",
   Host:     config.RabbitMq.Host,
   Port:     config.RabbitMq.Port,
   Username: config.RabbitMq.UserName,
   Password: config.RabbitMq.PassWord,
   Vhost:    "test",
}.String()
gologger.Debug().Msgf("rabbitmq url: %s", mqUrl)

conn, err := amqp.DialTLS(mqUrl, cfg)
if err != nil {
   gologger.Fatal().Msgf("Failed to connect rabbitmq: %s", err.Error())
}
gologger.Debug().Msgf("%+v", conn)

这个代码在rabbitmq是在localhost搭建的,这段测试代码也是在本地运行的情况下是不会报错的,但是如果将Host换成ip,就会报如下的错误

x509: cannot validate certificate for 192.168.31.69 because it doesn't contain any IP SANs

这应该是自签的证书没带有hostname,导致证书校验失败了,于是翻了一下源码,发现tls.Config有一个InsecureSkipVerify选项,原始的说明如下

InsecureSkipVerify controls whether a client verifies the server's certificate chain and host name. If InsecureSkipVerify is true, crypto/tls accepts any certificate presented by the server and any host name in that certificate. In this mode, TLS is susceptible to machine-in-the-middle attacks unless custom verification is used. This should be used only for testing or in combination with VerifyConnection or VerifyPeerCertificate.

大概意思就是信任任何主机名,但是他不建议这么做,因为容易受到中间人攻击。但是开启这个选项,就可以忽略主机名校验,所以只需将这个值是在为true既可以不校验主机名,然后就可以正常连接到rabbitmq。

cfg.InsecureSkipVerify = true

将这行代码加到amqp.DialTLS前再次连接就不会报错了。