ssl - 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
解决方案
我有完全相同的问题。唯一的区别是我创建了我的证书(OpenSSL),我以完全相同的方式配置了 vernemq。MQTT.fx 连接良好,node-red 连接良好,mosquitto_pub 和 mosquitto_sub 连接良好。
它唯一的带有 WiFiClientSecure espClient 的 ESP8266;没有连接。但是,如果我将代理更改为蚊子,那么 ESP 也可以毫无问题地连接。
如果您已经使用 VerneMQ 解决了它,请告诉我。如果没有,我们可以交换我们的实验结果,看看是否有任何结果。谢谢你。
推荐阅读
- python - MP3 音频 Python
- javascript - 使用javascript更新firebase中的值不起作用
- python - ELIF SyntaxError: 无效语法;
- javascript - 解析 .aspx 和 .ascx 文件以在 VSCode Prettier 插件中使用
- android-studio - 如何在 iPhone 上测试由 Android Studio 制作的 Flutter 应用
- php - Timber/Twig - 试图将侧边栏内容作为我的页脚的一部分
- javascript - 调用函数表达式
- c++ - 如何设置嵌入 C++ 的 Firebird?
- c++ - 如何在 PlatformIO 中启用错误抛出?(我收到 g++ 错误。)
- c# - C# Uri.CheckHostName(String) 方法不起作用?