You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32使用PubSubClient v2.8通过SSL连接Mosquitto失败求助

解决ESP32通过PubSubClient v2.8连接SSL加密Mosquitto失败的问题

核心问题原因

你当前使用的WiFiClient是明文TCP客户端,不支持SSL/TLS握手,而你的Mosquitto Broker启用了SSL加密,因此连接失败(错误码-2表示TCP连接层面的握手失败)。PubSubClient本身不实现SSL逻辑,依赖底层的Client接口实现,需要改用支持SSL的WiFiClientSecure。

具体解决步骤

1. 替换客户端类型

将代码中的WiFiClient替换为WiFiClientSecure,这是ESP32 Arduino核心库中支持SSL/TLS的客户端实现。

2. 导入Let's Encrypt根证书

ESP32默认不信任Let's Encrypt的根证书,需要将ISRG Root X1根证书内容添加到代码中(Let's Encrypt颁发的证书链最终信任此根证书),PEM格式内容如下:

-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6
UA5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+s
WT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qy
HB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+U
QwbsnnuyckKzDAGR6WUqmXesXnUVReJjwlVfBpLehjwq6hlKueZXkqArEdgDjKyJ
18RevEka7m0tmM0o4GDQ9X8CArNPSmz2pF9AzDo4sxTBvM4FyQjJS0jJS0jJL1A
9EzAqHazJnEipZ4Z39sNwVhd5jMIZbpIqV0LSKKmW0r5iXWej1pEXcLFuZS9mcw
YXpIuSLaR0CqwxRj2mNy2+0lsdeCuUpVersion=1 /etc/ssl/certs/ISRG_Root_X1.pem
-----END CERTIFICATE-----

3. 修改后的完整代码

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

// 替换为你的WiFi信息
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

// Let's Encrypt ISRG Root X1根证书
const char* root_ca = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n" \
"TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n" \
"cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\n" \
"WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\n" \
"ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\n" \
"MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\n" \
"h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\n" \
"0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6\n" \
"UA5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+s\n" \
"WT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qy\n" \
"HB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+U\n" \
"QwbsnnuyckKzDAGR6WUqmXesXnUVReJjwlVfBpLehjwq6hlKueZXkqArEdgDjKyJ\n" \
"18RevEka7m0tmM0o4GDQ9X8CArNPSmz2pF9AzDo4sxTBvM4FyQjJS0jJS0jJL1A\n" \
"9EzAqHazJnEipZ4Z39sNwVhd5jMIZbpIqV0LSKKmW0r5iXWej1pEXcLFuZS9mcw\n" \
"YXpIuSLaR0CqwxRj2mNy2+0lsdeCuUpVersion=1 /etc/ssl/certs/ISRG_Root_X1.pem\n" \
"-----END CERTIFICATE-----\n";

WiFiClientSecure espClient;
PubSubClient client(espClient);

String listening_topic;

void mqtt_configure(const char* mqtt_server, int mqtt_port) {
  client.setServer(mqtt_server, mqtt_port);
  // 配置SSL根证书
  espClient.setCACert(root_ca);
}

void mqtt_connect(const char* mqtt_topic, const char* mqtt_user, const char* mqtt_pass) {
  listening_topic = String(mqtt_topic);
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP32Client", mqtt_user, mqtt_pass)) {
      Serial.println("connected, subscribing to");
      Serial.println(mqtt_topic);
      client.subscribe(mqtt_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  // 连接WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected");

  mqtt_configure("my.server.com", 7383);
  mqtt_connect("esp32/output", "myuser", "mypass");
}

void loop() {
  if (!client.connected()) {
    mqtt_connect("esp32/output", "myuser", "mypass");
  }
  client.loop();
}

4. 额外说明

  • 你的Mosquitto配置中使用了fullchain.pem,其中包含了服务器证书和中间证书,客户端只需信任根证书即可完成证书链验证,无需额外配置中间证书。
  • 如果仍然连接失败,可以尝试关闭证书验证(仅用于调试,不推荐生产环境):espClient.setInsecure();,但这会降低安全性。

内容的提问来源于stack exchange,提问作者learningtech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 00:04:52