ESPHome remote device using HA Mosquitto MQTT addon over TLS secured connection

Hi all,

I’m using the (latest) Home Assistant Operating System that has LetsEncrypt, ESPHome and Mosquitto MQTT add-ons. Everything is up-to-date.

Home Assistant is accessible on its own fully qualified domain name and has a certificate installed using LetsEncrypt.

I have an esp32-s3-devkitc-1 development kit with some temperature sensors attached to it. I would like to install this device on remote locations, therefore it needs to send the temperature readings using MQTT. This works.

Next step is to secure the MQTT messages using TLS. I’ve read MQTT Client Component — ESPHome and generated self-signed CA and server certificates using the following commands (on a different Linux box):

  1. Create CA key: sudo openssl genrsa -des3 -out ca.key 2048
  2. Create Self Signed CA Certificate: sudo openssl req -new -x509 -days 1826 -key ca.key -out ca.crt
  3. Create Server key: sudo openssl genrsa -out server.key 2048
  4. Create Server Certificate Request: sudo openssl req -new -out server.csr -key server.key
  5. Create Self Signed Server Certificate: sudo openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360

The hostname used in the certificate generation above is the same as the domain name used for LetsEncrypt.

I copied the files ca.crt, server.key and server.crt to the ssl folder on the Home Assistant box and changed the Mosquitto yaml to:

logins: []
require_certificate: true
certfile: server.crt
keyfile: server.key
customize:
  active: false
  folder: mosquitto
cafile: ca.crt

On the ESPHome device I’m using the configuration:

esphome:
  name: "myespdevice"

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant MQTT
mqtt:
  broker: <redacted / same hostname used for LetsEncrypt.>
  port: 8883
  skip_cert_cn_check: false
  idf_send_async: false
  certificate_authority: |
    -----BEGIN CERTIFICATE-----
    <redacted>
    -----END CERTIFICATE-----

ota:
  password: "<redacted>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "myespdevice"
    password: "u74VGrt64CL0K8"

.... other sensor stuff ....

The ESP device keeps reporting:

INFO Successfully reconnected to the MQTT server

Mosquitto MQTT logs:

Client connection from 10.42.10.15 failed: error:1408F10B:SSL routines:ssl3_get_record:wrong version number.

or

OpenSSL Error[0]: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate

I’m probably missing something, but can’t seem to find what. Help is appreciated in getting the communication (preferably without any proxies) secured.

Thanks.

1 Like

It’s poorly documented on the addon side (I actually think it’s plain wrong :wink: ), but this means you require a client certificate from ESP, which is not what you want.

From mosquitto.conf man page | Eclipse Mosquitto

Hi Koying,

Thank you for your reply. I changed the required_certificate to false and added a login to the Mosquitto configuration and restarted it. I added the username and password to the ESPHome device configuration as well and that results in the following log-output in Mosquitto:

2023-03-22 10:29:27: New connection from 192.168.1.35:51273 on port 8883.
2023-03-22 10:29:43: Client <unknown> disconnected: Protocol error.
2023-03-22 10:29:43: Client connection from 192.168.1.35 failed: error:1408F10B:SSL routines:ssl3_get_record:wrong version number.
2023-03-22 10:29:43: New connection from 192.168.1.35:40361 on port 8883.
2023-03-22 10:30:15: Client <unknown> disconnected: Protocol error.
2023-03-22 10:30:15: New connection from 192.168.1.35:59345 on port 8883.
2023-03-22 10:30:15: OpenSSL Error[0]: error:1408F10B:SSL routines:ssl3_get_record:wrong version number

IP 192.168.1.35 is the local (internal) address of the HA and Mosquitto machine.

Any ideas?

Hi Chris,

did you have any luck getting it to work? Running into the same issue as you.

thanks!

Hello, what worked for me is the following:

  • From the website https://letsencrypt.org/ I downloaded - e5-cross.pem
  • I opened the file and put it as text in the parameter: “certificate_authority”. It is important that there is a “|”.
  • Like this: " certificate_authority: | -----BEGIN CERTIFICATE-----"
  • When I used “!include e5-cross.pem”, nothing worked.

Here is the code itself

esphome:
  name: office-aht10
  friendly_name: office AHT10

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API

ota:
  - platform: esphome
    password: "c0ab18714dbc25eb9593d6b0625b7373"

wifi:
  ssid: Office
  password: Office

  ap:
    ssid: "Office-Aht10 Fallback Hotspot"
    password: "5DgNeN1wRZqv"
    
api:
  encryption:
    key: "F4xuaOTK6G3AeIbcEqn98U9yKzw9LSGfQU1WkfSVPEY="

# MQTT  SSL //letsencrypt_intermediate
mqtt:
  broker: "office.office .com"
  port: 8883
  username: "broker"
  password: "pass"
  skip_cert_cn_check: true
  idf_send_async: true
  certificate_authority: |
    -----BEGIN CERTIFICATE-----
    MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw
    TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
    cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
    WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
    RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK
    a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO
    VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw
    gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
    ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw
    i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
    AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
    BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
    Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C
    2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+
    bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG
    6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV
    XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO
    koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq
    cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI
    E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e
    K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX
    GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL
    sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd
    VQD9F6Na/+zmXCc=
    -----END CERTIFICATE-----

captive_portal:

sensor:
  - platform: aht10
    variant: AHT20
    temperature:
      name: "Office Temperature"
    humidity:
      name: "Office Humidity"
    update_interval: 5s  

  - platform: ags10
    tvoc:
      name: "TVOC"
      id: tvoc_value 
    update_interval: 5s

  - platform: wifi_signal
    name: WiFi Strength
    update_interval: 60s

switch:
- platform: restart
  name: 'Office Restart'

i2c:
  scl: GPIO9
  sda: GPIO8
  scan: True
  id: bus_a
  frequency: 15khz

text_sensor:
  - platform: wifi_info
    ip_address:
      name: 'Office IP Address'
1 Like

Hopefully not too old, but try it with this:
Add the certfile in secrets.yaml:

certfile: | 
    -----BEGIN CERTIFICATE-----
          <REDACTED>
    -----END CERTIFICATE-----

Then add to your config:

mqtt:
  broker: <redacted>
  port: 8883
  username: mosquitto
  password: !secret mqtt_password
  discovery_prefix: ${mqtt_prefix}/homeassistant
  log_topic: ${mqtt_prefix}/logs
  skip_cert_cn_check: true
  idf_send_async: false
  certificate_authority: !secret certfile