go crypto/tls: TLS handshake issue with Eclipse Paho MQTT client and RabbitMQ

pgpifvop  于 7个月前  发布在  Go
关注(0)|答案(6)|浏览(76)

您好,这个问题可能是由于您的Go客户端和RabbitMQ代理之间的TLS握手失败导致的。您可以尝试以下步骤来解决此问题:

  1. 确保您的Go客户端和RabbitMQ代理都使用相同的TLS版本。
  2. 确保您的Go客户端和RabbitMQ代理都使用相同的加密套件。
  3. 确保您的Go客户端和RabbitMQ代理都使用相同的证书颁发机构(CA)。
  4. 确保您的Go客户端和RabbitMQ代理都使用相同的密钥长度。
  5. 确保您的Go客户端和RabbitMQ代理都使用相同的密码套件。

如果您仍然无法解决问题,请尝试使用其他MQTT客户端库,例如Eclipse Paho MQTT C++ Client Library或Paho MQTT Golang Client。

qaxu7uf2

qaxu7uf21#

请查看您的错误处理,在几个情况下,当 err 不等于 nil 时,您返回了 nil。

mec1mxoz

mec1mxoz2#

你好,@davecheney,
感谢你的回复。
我认为我的这个问题不是由于错误的错误处理(在NewTLSConfig函数上没有引发错误)引起的。
问候,
Dario

iyfjxgzm

iyfjxgzm3#

感谢您的回复。请理解,在没有上下文的情况下对问题进行分类是重要的,不要被不重要的事情分心。如果您能解决您示例中的错误处理并确认问题仍然存在,那将是非常有帮助的。

pvabu6sv

pvabu6sv4#

你好,@davecheney。

当然可以。

以下是主文件(main.go)的更新内容:

package main

import (
	MQTT "github.com/eclipse/paho.mqtt.golang"
	"fmt"
	"time"
	"io/ioutil"
	"crypto/tls"
	"crypto/x509"
)

var (
	brokerUrl = "ssl://<RABBITMQ-HOST>:8883"
)

func main() {
	opts := MQTT.NewClientOptions()
	opts.SetClientID("aa6d566f-46ea-4ada-b4ef-07b18766429b")
	opts.AddBroker(brokerUrl)	
	opts.SetPingTimeout(1 * time.Second)
	opts.SetAutoReconnect(true)
	opts.SetCleanSession(true)
	opts.SetKeepAlive(10 * time.Second)
	opts.SetConnectTimeout(10 * time.Second)
	
	tlsConfig := NewTLSConfig()
	if tlsConfig == nil {
		panic("tlsConfig is nil")
	}
	
	opts.SetTLSConfig(tlsConfig)

	client := MQTT.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	fmt.Println("Client Connected")
}

func NewTLSConfig() *tls.Config {
	
	// Import trusted certificates from CAfile.pem.
	// Alternatively, manually add CA certificates to
	// default openssl CA bundle.
	certpool, err := x509.SystemCertPool()
	if err != nil {
		fmt.Errorf("x509.SystemCertPool failed")
		return nil
	}

	pemCert, err := ioutil.ReadFile("ca.crt")
	if err != nil {
		fmt.Errorf("ioutil.ReadFile failed")
		return nil	
	}
	
	certpool.AppendCertsFromPEM(pemCert)
	
	// Import client certificate/key pair
	cert, err := tls.LoadX509KeyPair("client-cert.crt", "private-key.crt.key")
	if err != nil {
		fmt.Errorf("tls.LoadX509KeyPair failed")
		return nil
	}

	// Just to print out the client certificate...
	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		fmt.Errorf("x509.ParseCertificate failed")
		return nil
	}
	
	// Create tls.Config with desired tls properties
	return &tls.Config{
		
		// RootCAs = certs used to verify server cert.
		RootCAs: certpool,

		// Certificates = list of certs client sends to server.
		Certificates: []tls.Certificate{cert},
		
		PreferServerCipherSuites: true,
		
		CipherSuites: []uint16{
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		},
	}
}

我可以私下发送给你我正在使用的输入(服务器主机+根CA+客户端证书+私钥),以便复制该问题。

7ajki6be

7ajki6be5#

对不起,我可能有点啰嗦了,但fmt.Errorf并不会记录错误,它只会返回一个错误值,而这段代码正是忽略了这个错误值。

dzhpxtsq

dzhpxtsq6#

我再次更新了main.go文件,但仍然遇到了相同的错误:
MQTT连接失败
恐慌:网络错误:远程错误:tls握手失败
以下是使用的main.go文件:

package main

import (
	MQTT "github.com/eclipse/paho.mqtt.golang"
	"fmt"
	"time"
	"io/ioutil"
	"crypto/tls"
	"crypto/x509"
)

var (
	brokerUrl = "ssl://<RABBITMQ-HOST>:8883"
)

func main() {
	opts := MQTT.NewClientOptions()
	opts.SetClientID("aa6d566f-46ea-4ada-b4ef-07b18766429b")
	opts.AddBroker(brokerUrl)	
	opts.SetPingTimeout(1 * time.Second)
	opts.SetAutoReconnect(true)
	opts.SetCleanSession(true)
	opts.SetKeepAlive(10 * time.Second)
	opts.SetConnectTimeout(10 * time.Second)
	
	tlsConfig, err := NewTLSConfig()
	if err != nil {
		panic(err.Error())
	}
	
	opts.SetTLSConfig(tlsConfig)

	client := MQTT.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		fmt.Println("MQTT Connection failed")
		panic(token.Error())
	}

	fmt.Println("Client Connected")
}

func NewTLSConfig() (*tls.Config, error) {
	
	// Import trusted certificates from CAfile.pem.
	// Alternatively, manually add CA certificates to
	// default openssl CA bundle.
	certpool, err := x509.SystemCertPool()
	if err != nil {
		fmt.Println("x509.SystemCertPool failed")
		return nil, err
	}

	pemCert, err := ioutil.ReadFile("ca.crt")
	if err != nil {
		fmt.Println("ioutil.ReadFile failed")
		return nil, err
	}
	
	certpool.AppendCertsFromPEM(pemCert)
	
	// Import client certificate/key pair
	cert, err := tls.LoadX509KeyPair("client-cert.crt", "private-key.crt.key")
	if err != nil {
		fmt.Println("tls.LoadX509KeyPair failed")
		return nil, err
	}

	// Just to print out the client certificate...
	cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
	if err != nil {
		fmt.Println("x509.ParseCertificate failed")
		return nil, err
	}
	
	// Create tls.Config with desired tls properties
	return &tls.Config{
		
		// RootCAs = certs used to verify server cert.
		RootCAs: certpool,

		// Certificates = list of certs client sends to server.
		Certificates: []tls.Certificate{cert},
		
		PreferServerCipherSuites: true,
		
		CipherSuites: []uint16{
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
		},
	}, nil
}

相关问题