2017-03-13 5 views
0

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

Antwort

2

Zertifikate, die BEGIN TRUSTED CERTIFICATE ist ein OpenSSL "vertrauenswürdiges Zertifikat" Datei zu starten, die a Das Format wurde von den Go-Crypto-Bibliotheken nicht verstanden/geparst. Wenn Sie das Zertifikat generiert haben, haben Sie eine der Optionen unter "TRUST SETTINGS" auf der x509 man page? Die Go TLS-Bibliothek ist nur looking für -----BEGIN CERTIFICATE----- am Anfang der Datei, anyth In anderen Fällen wird ein Fehler ausgegeben.

+0

Danke. Wenn Sie schreiben, wie Sie das richtige Zertifikat erstellen, gebe ich Ihnen den Cookie –

Verwandte Themen