Как реализовать mqtt с сертификатами SSL/TLS в Go?

# #go #ssl #mqtt

Вопрос:

Я пытаюсь создать сценарий в Go, который отправит сообщение брокеру mqtt с сертификатами SSL / TLS. Я создал эти сертификаты с помощью OpenSSL и протестировал связь mqtt с командами mosquitto_sub и mosquitto_pub, и это работает нормально, но когда я пытаюсь отправить сообщение с помощью сценария Go, я получаю следующую ошибку:

сетевая ошибка : чтение tcp 192.168.1.243:59454->192.168.1.171:8883: чтение: сброс соединения одноранговым узлом

И в журнале брокера mosquitto появляется следующее сообщение:

1627682906: Новое соединение с 192.168.1.243 на порту 8883.
1627682906: Ошибка OpenSSL: ошибка:1408F10B:Процедуры SSL:ssl3_get_record:неверный номер версии
1627682906: Ошибка сокета на клиенте , отключение.
1627682906: Новое соединение от 192.168.1.243 на порту 8883.
1627682906: Ошибка OpenSSL: ошибка:1408F10B:Процедуры SSL:ssl3_get_record:неверный номер версии
1627682906: Ошибка сокета на клиенте , отключение.

Код, который я использую, выглядит следующим образом:

 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() amp;amp; 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 amp;tls.Config{
        RootCAs: certpool,
    }
}
 

Есть ли у меня какие-либо ошибки в коде или есть какой-то другой способ реализовать связь mqtt с SSL-сертификатами в Go?

Комментарии:

1. вот у вас есть пример github.com/eclipse/paho.mqtt.golang/blob/master/…

Ответ №1:

Первая проблема, которую я заметил (это может быть единственная проблема или могут быть другие):

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

Использование схемы URL tcp (или mqtt ) указывает на то, что вы хотите установить незашифрованное соединение (предоставленный вами сертификат будет проигнорирован). Чтобы запросить MQTT по протоколу TLS, используйте один из ssl , tls , mqtts , mqtt ssl или tcps . Например, демонстрационная версия (на которой, как я подозреваю, основан ваш код) использует:

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