Ich versuche, eine Verbindung zu einem Moskito-Broker herzustellen, der eine zertifikatbasierte Authentifizierung verwendet.Paho GO-Client kann keine Verbindung zum Broker herstellen
Die mosquitto snipped Konfiguration unter:
listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
require_certificate true
Die Konfiguration es funktioniert, weil ich in der Lage ein Pub/sub in einer Remote-Maschine mit folgenden Befehlen zu machen:
mosquitto_pub -t "/test" -m "test" --cafile ca/ca.crt --cert certs/client.crt --key certs/client.key -p 8883 -h server.com
mosquitto_sub -t "/test" --cafile ca/ca.crt --cert certs/client.crt --key certs/client.key -p 8883 -h server.com
oder öffnen SSL Socket von:
openssl s_client -connect server.com:8883 -CAfile ca/ca.crt -cert certs/client.crt -key certs/client.key
aber wenn ich versuche, GO Paho Client zu verwenden, funktioniert nicht:
Das Laden der Konfiguration nicht, da funktioniert in configureMqttConnection()
ist nicht in der Lage, die Zertifikate (diese Linie tls.LoadX509KeyPair(c.config.CertFile, c.config.KeyFile)
) und in connect(backOff int)
nicht geladen werden, da der Client nicht in der Lage ist, das Zertifikat im Handshake zu senden.
Ich denke, das Problem ist vielleicht, dass die Zertifikate, die LoadX509KeyPair erwartet, nicht die sind, die ich erzeuge. Meine Zertifikate lauten "BEGIN TRUSTED CERTIFICATE" und wird nicht vertrauenswürdig und zertifiziert oder ähnlich. Wenn das ist bin ich mir nicht sicher, wie ich das richtige Zertifikat erstellen kann.
ich diesen GO Code unten bin mit (der Code beginnt mit GO start()
:
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"strings"
"time"
MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
"linksmart.eu/lc/core/catalog"
"linksmart.eu/lc/core/catalog/service"
)
// MQTTConnector provides MQTT protocol connectivity
type MQTTConnector struct {
config *MqttProtocol
clientID string
client *MQTT.Client
pubCh chan AgentResponse
subCh chan<- DataRequest
pubTopics map[string]string
subTopicsRvsd map[string]string // store SUB topics "reversed" to optimize lookup in messageHandler
}
const defaultQoS = 1
func (c *MQTTConnector) start() {
logger.Println("MQTTConnector.start()")
if c.config.Discover && c.config.URL == "" {
err := c.discoverBrokerEndpoint()
if err != nil {
logger.Println("MQTTConnector.start() failed to start publisher:", err.Error())
return
}
}
// configure the mqtt client
c.configureMqttConnection()
// start the connection routine
logger.Printf("MQTTConnector.start() Will connect to the broker %v\n", c.config.URL)
go c.connect(0)
// start the publisher routine
go c.publisher()
}
// reads outgoing messages from the pubCh und publishes them to the broker
func (c *MQTTConnector) publisher() {
for resp := range c.pubCh {
if !c.client.IsConnected() {
logger.Println("MQTTConnector.publisher() got data while not connected to the broker. **discarded**")
continue
}
if resp.IsError {
logger.Println("MQTTConnector.publisher() data ERROR from agent manager:", string(resp.Payload))
continue
}
topic := c.pubTopics[resp.ResourceId]
c.client.Publish(topic, byte(defaultQoS), false, resp.Payload)
// We dont' wait for confirmation from broker (avoid blocking here!)
//<-r
logger.Println("MQTTConnector.publisher() published to", topic)
}
}
func (c *MQTTConnector) stop() {
logger.Println("MQTTConnector.stop()")
if c.client != nil && c.client.IsConnected() {
c.client.Disconnect(500)
}
}
func (c *MQTTConnector) connect(backOff int) {
if c.client == nil {
logger.Printf("MQTTConnector.connect() client is not configured")
return
}
for {
logger.Printf("MQTTConnector.connect() connecting to the broker %v, backOff: %v sec\n", c.config.URL, backOff)
time.Sleep(time.Duration(backOff) * time.Second)
if c.client.IsConnected() {
break
}
token := c.client.Connect()
token.Wait()
if token.Error() == nil {
break
}
logger.Printf("MQTTConnector.connect() failed to connect: %v\n", token.Error().Error())
if backOff == 0 {
backOff = 10
} else if backOff <= 600 {
backOff *= 2
}
}
logger.Printf("MQTTConnector.connect() connected to the broker %v", c.config.URL)
return
}
func (c *MQTTConnector) onConnected(client *MQTT.Client) {
// subscribe if there is at least one resource with SUB in MQTT protocol is configured
if len(c.subTopicsRvsd) > 0 {
logger.Println("MQTTPulbisher.onConnected() will (re-)subscribe to all configured SUB topics")
topicFilters := make(map[string]byte)
for topic, _ := range c.subTopicsRvsd {
logger.Printf("MQTTPulbisher.onConnected() will subscribe to topic %s", topic)
topicFilters[topic] = defaultQoS
}
client.SubscribeMultiple(topicFilters, c.messageHandler)
} else {
logger.Println("MQTTPulbisher.onConnected() no resources with SUB configured")
}
}
func (c *MQTTConnector) onConnectionLost(client *MQTT.Client, reason error) {
logger.Println("MQTTPulbisher.onConnectionLost() lost connection to the broker: ", reason.Error())
// Initialize a new client and reconnect
c.configureMqttConnection()
go c.connect(0)
}
func (c *MQTTConnector) configureMqttConnection() {
connOpts := MQTT.NewClientOptions().
AddBroker(c.config.URL).
SetClientID(c.clientID).
SetCleanSession(true).
SetConnectionLostHandler(c.onConnectionLost).
SetOnConnectHandler(c.onConnected).
SetAutoReconnect(false) // we take care of re-connect ourselves
// Username/password authentication
if c.config.Username != "" && c.config.Password != "" {
connOpts.SetUsername(c.config.Username)
connOpts.SetPassword(c.config.Password)
}
// SSL/TLS
if strings.HasPrefix(c.config.URL, "ssl") {
tlsConfig := &tls.Config{}
// Custom CA to auth broker with a self-signed certificate
if c.config.CaFile != "" {
caFile, err := ioutil.ReadFile(c.config.CaFile)
if err != nil {
logger.Printf("MQTTConnector.configureMqttConnection() ERROR: failed to read CA file %s:%s\n", c.config.CaFile, err.Error())
} else {
tlsConfig.RootCAs = x509.NewCertPool()
ok := tlsConfig.RootCAs.AppendCertsFromPEM(caFile)
if !ok {
logger.Printf("MQTTConnector.configureMqttConnection() ERROR: failed to parse CA certificate %s\n", c.config.CaFile)
}
}
}
// Certificate-based client authentication
if c.config.CertFile != "" && c.config.KeyFile != "" {
cert, err := tls.LoadX509KeyPair(c.config.CertFile, c.config.KeyFile)
if err != nil {
logger.Printf("MQTTConnector.configureMqttConnection() ERROR: failed to load client TLS credentials: %s\n",
err.Error())
} else {
tlsConfig.Certificates = []tls.Certificate{cert}
}
}
connOpts.SetTLSConfig(tlsConfig)
}
c.client = MQTT.NewClient(connOpts)
}
ich glaube, das Problem, das ich
Danke. Wenn Sie schreiben, wie Sie das richtige Zertifikat erstellen, gebe ich Ihnen den Cookie –