Paho GO客户端无法连接到Broker

问题描述:

我试图连接到使用基于证书的身份验证的mosquitto broker。Paho GO客户端无法连接到Broker

的mosquitto剪断以下配置:

listener 8883 
cafile /etc/mosquitto/ca_certificates/ca.crt 
certfile /etc/mosquitto/certs/server.crt 
keyfile /etc/mosquitto/certs/server.key 

require_certificate true 

它的作品,因为我可以使用下面的命令作出的pub/sub在远程机器的配置:

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 

或打开SSL插座由:

openssl s_client -connect server.com:8883 -CAfile ca/ca.crt -cert certs/client.crt -key certs/client.key 

,但是当我试图用GO泛美卫生组织客户端不起作用:

装载不会因为configureMqttConnection()工作的配置是无法加载证书(此行tls.LoadX509KeyPair(c.config.CertFile, c.config.KeyFile))和connect(backOff int)失败,因为客户机无法发送证书在握手。

我想也许问题是LoadX509KeyPair期望的证书不是我生成的证书。我的证书上写着'BEGIN TRUSTED CERTIFICATE',而不是被信任和证明或者类似的东西。如果这是我不知道如何创建正确的证书。

我下面用这个GO代码(代码开头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) 
} 

我认为这个问题我

证书即开始BEGIN TRUSTED CERTIFICATE是OpenSSL的“受信任的证书”文件,该文件是一个格式不理解转到加密库/可解析的。当你生成你的x509 man page使用任何选项下的“信任设置”的证书? 转到TLS库只是looking-----BEGIN CERTIFICATE-----的文件,任何物品的开始否则会引发错误。

+0

谢谢。如果你写了如何创建正确的证书,我给你的cookie –