首页 > 解决方案 > VerneMQ TLS 配置给出错误握手失败使用letsencrypt

问题描述

我在使用 ubuntu 18.04 作为操作系统的 VPS 上运行 vernerMQ,我使用 OpenSSL 进行了认证,然后将证书文件从 /etc/letsencrypt/live/$mydomain/*.pem 复制到 /etc/vernemq/ 我正在将此配置用于 SSL :

listener.ssl.cafile = /etc/vernemq/chain.pem
listener.ssl.certfile = /etc/vernemq/cert.pem
listener.ssl.keyfile = /etc/vernemq/privkey.pem

listener.ssl.default = 0.0.0.0:8883

用户和密码在 passwd 文件中设置。问题是当我尝试从 esp8266 连接到服务器时,它给了我这个错误:

BSSL:_wait_for_handshake: failed
BSSL:Couldn't connect. Error = 'Unknown error code.'

这是 esp8266 代码:

#include <ESP8266WiFi.h>
#include<WiFiManager.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

//Enter your wifi credentials
const char* ssid = "ssid";  
const char* password =  "ssidpass";

// A name for our device
const char* deviceName = "devicename";

// Our mqtt server Adress and port
const char* mqttServer = "mydomain";
const int mqttPort = 8883;

// a user defined on our server with it's password for login purpose
const char* mqttUser = "user"; //User
const char* mqttPassword = "pass"; //Password

// our gpio
#define ESP8266_LED (0)

// this is ca Certificate used as SSL key
const char caCert[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
    cert content : cert.pem
-----END CERTIFICATE-----
)EOF";

/* MQTT broker cert SHA1 fingerprint, used to validate connection to right server */
const char mqttCertFingerprint[] = "fingerprint";
     
/* Other globals */
X509List caCertX509(caCert);        /* X.509 parsed CA Cert */
WiFiClientSecure espClient;         /* Secure client connection class, as opposed to WiFiClient */
PubSubClient mqttClient(espClient); /* MQTT Client connection */
String clientId = "ESP8266Client-"; /* MQTT client ID (will add random hex suffix during setup) */



void setup() {
    Serial.begin(115200);
  
  // prepare GPIO0
  pinMode(0, OUTPUT);
 // digitalWrite(0, LOW);


  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

/*#ifdef SERIAL_DEBUG*/
  Serial.print("Connecting");
/*#endif*/
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
/*#ifdef SERIAL_DEBUG*/
    Serial.print(".");
/*#endif*/
  }
/*#ifdef SERIAL_DEBUG*/
  /* When WiFi connection is complete, debug log connection info */
  Serial.println();
  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
  setClock();
/*#endif*/
 /* Configure secure client connection */
  espClient.setTrustAnchors(&caCertX509);         /* Load CA cert into trust store */
  espClient.allowSelfSignedCerts();               /* Enable self-signed cert support */
  espClient.setFingerprint(mqttCertFingerprint);  /* Load SHA1 mqtt cert fingerprint for connection validation */
  
  /* Optionally do none of the above and allow insecure connections.                                             
   * This will accept any certificates from the server, without validation and is not recommended.
   */
  //espClient.setInsecure();

 /* #ifdef TLS_DEBUG
  /* Call verifytls to verify connection can be done securely and validated - this is optional but was useful during debug */
  verifytls();
/*#endif
  /* Configure MQTT Broker settings */
  mqttClient.setServer(mqttServer,mqttPort);
  mqttClient.setCallback(subCallback);

    /* Add random hex client ID suffix once during each reboot */
  clientId += String(random(0xffff), HEX); 

}



void loop() {
    /* Main loop. Attempt to re-connect to MQTT broker if connection drops, and service the mqttClient task. */
  if(!mqttClient.connected()) {
    reconnect();
  }
  mqttClient.loop();
}

/*#ifdef TLS_DEBUG
/* verifytls()
 *  Test WiFiClientSecure connection using supplied cert and fingerprint
 */
bool verifytls() {
  bool success = false;
    
/*#ifdef SERIAL_DEBUG*/
  Serial.print("Verifying TLS connection to ");
  Serial.println(mqttServer);
/*#endif*/

  success = espClient.connect(mqttServer, mqttPort);

/*#ifdef SERIAL_DEBUG*/
  if (success) {
    Serial.println("Connection complete, valid cert, valid fingerprint.");
  }
  else {
    Serial.println("Connection failed!");
  }
/*#endif*/

  return (success);
}
/*#endif*/

void reconnect() {
  /* Loop until we're reconnected */
  while (!mqttClient.connected()) {
/*#ifdef SERIAL_DEBUG*/
    Serial.print("Attempting MQTT broker connection...");
/*#endif*/
    /* Attempt to connect */
    if (mqttClient.connect(clientId.c_str(),mqttUser,mqttPassword)) {
/*#ifdef SERIAL_DEBUG*/
      Serial.println("connected");
/*#endif*/
      /* Once connected, resubscribe */
      mqttClient.subscribe("user/home1/esponoff");      
    } 
    else {
/*#ifdef SERIAL_DEBUG*/
      Serial.print("Failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(". Trying again in 5 seconds...");
/*#endif
      /* Wait 5 seconds between retries */
      delay(5000);
    }
  }
}

// Set time via NTP, as required for x.509 validation
void setClock() {
  //get the time
}

void subCallback(char *topic, byte *payload, unsigned int length)
{
 //to do
}

相同的配置适用于 mosquitto 但不适用于 verneMQ

标签: sslmqttvps

解决方案


我有完全相同的问题。唯一的区别是我创建了我的证书(OpenSSL),我以完全相同的方式配置了 vernemq。MQTT.fx 连接良好,node-red 连接良好,mosquitto_pub 和 mosquitto_sub 连接良好。

它唯一的带有 WiFiClientSecure espClient 的 ESP8266;没有连接。但是,如果我将代理更改为蚊子,那么 ESP 也可以毫无问题地连接。

如果您已经使用 VerneMQ 解决了它,请告诉我。如果没有,我们可以交换我们的实验结果,看看是否有任何结果。谢谢你。


推荐阅读