如何在Go中使用SSL/TLS证书实现MQTT?

huangapple go评论84阅读模式
英文:

How to implement mqtt with SSL/TLS certs in Go?

问题

我正在尝试使用Go编写一个脚本,该脚本将使用SSL/TLS证书将消息发送到mqtt代理。我使用openSSL创建了这些证书,并使用mosquitto_sub和mosquitto_pub命令测试了mqtt通信,这部分工作正常。但是,当我尝试使用Go脚本发送消息时,我收到以下错误:

网络错误:read tcp 192.168.1.243:59454->192.168.1.171:8883: read: connection reset by peer

在mosquitto代理的日志中,出现了以下消息:

1627682906: 来自192.168.1.243的新连接,端口8883。
1627682906: OpenSSL错误:error:1408F10B:SSL routines:ssl3_get_record:wrong version number
1627682906: 客户端<unknown>的套接字错误,断开连接。
1627682906: 来自192.168.1.243的新连接,端口8883。
1627682906: OpenSSL错误:error:1408F10B:SSL routines:ssl3_get_record:wrong version number
1627682906: 客户端<unknown>的套接字错误,断开连接。

我正在使用以下代码:

package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"log"

	MQTT "github.com/eclipse/paho.mqtt.golang" // mqtt
)

func main() {
	broker := "192.168.1.171"
	port := "8883"
	topic := "sensor/temperature"

	opts := MQTT.NewClientOptions()
	opts.AddBroker(fmt.Sprintf("tcp://%s:%s", broker, port))
	opts.SetClientID("Device")
	opts.SetUsername("")
	opts.SetPassword("")
	tlsConfig := NewTlsConfig()
	opts.SetTLSConfig(tlsConfig)

	client := MQTT.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		log.Println("1. ", token.Error())
	}

	token := client.Publish(topic, 0, false, "36.2")
	token.Wait()

	client.Disconnect(250)
}

func NewTlsConfig() *tls.Config {
	certpool := x509.NewCertPool()
	ca, err := ioutil.ReadFile("/home/pi/server.crt")
	if err != nil {
		log.Fatalln(err.Error())
	}
	certpool.AppendCertsFromPEM(ca)
	return &tls.Config{
		RootCAs: certpool,
	}
}

我的代码中是否有任何错误?还是有其他方法可以在Go中实现带有SSL证书的mqtt通信?

英文:

I'm trying to make a script in Go that will send a message to a mqtt broker with SSL / TLS certificates. I created these certificates with openSSL and tested mqtt communication with mosquitto_sub and mosquitto_pub commands and this works fine, but when I try to send a message with the Go script I get the following error:

network Error : read tcp 192.168.1.243:59454->192.168.1.171:8883: read: connection reset by peer

And in the log of the mosquitto broker, the following message appears:

1627682906: New connection from 192.168.1.243 on port 8883.
1627682906: OpenSSL Error: error:1408F10B:SSL routines:ssl3_get_record:wrong version number
1627682906: Socket error on client <unknown>, disconnecting.
1627682906: New connection from 192.168.1.243 on port 8883.
1627682906: OpenSSL Error: error:1408F10B:SSL routines:ssl3_get_record:wrong version number
1627682906: Socket error on client <unknown>, disconnecting.

The code I'm using is the following:

package main

import (
	&quot;crypto/tls&quot;
	&quot;crypto/x509&quot;
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;log&quot;

	MQTT &quot;github.com/eclipse/paho.mqtt.golang&quot; // mqtt
)

func main() {
	broker := &quot;192.168.1.171&quot;
	port := &quot;8883&quot;
	topic := &quot;sensor/temperature&quot;

	opts := MQTT.NewClientOptions()
	opts.AddBroker(fmt.Sprintf(&quot;tcp://%s:%s&quot;, broker, port))
	opts.SetClientID(&quot;Device&quot;)
	opts.SetUsername(&quot;&quot;)
	opts.SetPassword(&quot;&quot;)
	tlsConfig := NewTlsConfig()
	opts.SetTLSConfig(tlsConfig)

	client := MQTT.NewClient(opts)
	if token := client.Connect(); token.Wait() &amp;&amp; token.Error() != nil {
		log.Println(&quot;1. &quot;, token.Error())
	}

	token := client.Publish(topic, 0, false, &quot;36.2&quot;)
	token.Wait()

	client.Disconnect(250)
}

func NewTlsConfig() *tls.Config {
	certpool := x509.NewCertPool()
	ca, err := ioutil.ReadFile(&quot;/home/pi/server.crt&quot;)
	if err != nil {
		log.Fatalln(err.Error())
	}
	certpool.AppendCertsFromPEM(ca)
	return &amp;tls.Config{
		RootCAs: certpool,
	}
}

Am I have any bugs in the code or is there some other way to implement mqtt communication with SSL certificates in Go?

答案1

得分: 2

我注意到的第一个问题是(这可能是唯一的问题,也可能还有其他问题):

opts.AddBroker(fmt.Sprintf("tcp://%s:%s", broker, port))

使用tcp(或mqtt)作为URL方案表示您希望建立一个未加密的连接(您提供的证书将被忽略)。要请求使用TLS的MQTT,请使用ssltlsmqttsmqtt+ssltcps之一。例如,示例代码(我猜测您的代码是基于该示例)使用:

opts.AddBroker("ssl://iot.eclipse.org:8883")

英文:

The first issue I noticed is (this may be the only issue or there may be others):

opts.AddBroker(fmt.Sprintf(&quot;tcp://%s:%s&quot;, broker, port))

Using the url scheme tcp (or mqtt) indicates that you wish to establish an unencrypted connection (the certificate you provide will be ignored). To request MQTT over TLS use one of ssl, tls, mqtts, mqtt+ssl or tcps. For example the demo (which I suspect your code is based on) uses:

opts.AddBroker(&quot;ssl://iot.eclipse.org:8883&quot;)

huangapple
  • 本文由 发表于 2021年7月31日 06:39:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/68597739.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定