MQTT TLS Config Problem

Hallo Community,

Ich habe die die Konfiguration des MQTT Skripts folgend ausgefüllt und verwendete als Broker Mosquitto die Kommunikation funktioniert ohne TLS wunderbar, nur mit TLS irgendwie nicht. Ich hoffe Ihr könnt mir da weiterhelfen.

### TLS options ###

# Set to "true" to enable SSL encryption for MQTT.
enableSSL = true

# The path to the certificate authority's certificate
caFile = /etc/homegear/m2mqtt_ca.crt

# verifyCertificate checks if the server certificate received by the
# MQTT broker is signed by one of the root CAs in /etc/ssl/certs. If you use
# a self signed certificate, please put your root certificate in that
# directory. Only disable the verification for testing purposes. Without
# verification any attacker can pose as your MQTT broker.
# Default: verifyCertificate = true
verifyCertificate = true

# The path to the PEM encoded client certificate.
#certPath = /etc/homegear/mqtt.crt

# The path to the PEM encoded client keyfile.
#keyPath = /etc/homegear/mqtt.key

Im Mosquitto Log finde ich folgende Zeilen in einer Dauerschleife vor:

Socket error on client <unknown>, disconnecting.
New connection from 143.93.197.20 on port 8883.

Eine gesicherte Verbindung kommt nicht zustande.

Ich hoffe Ihr könnt mir helfen!

Gruß Pascal

Hi @ZPascal,

nur für mein Verständnis: Du hast einen externen MQTT-Broker mit einem selbsiginiertes SSL-Zertifikat? Wenn ich es richtig verstehe, müsstest du ja dann auch das Zertifikat (certPath) angeben, oder?

Ich hatte das bei mir mal testweise laufen, allerdings mit einem Letsencrypt-Zertifikat. Das hatte den Vorteil, dass ich nur enableSSL=true und verifyCertificate = true setzen musste. Letsencrypt wird ja über die im System vorhandenen CA’s beglaubigt.

Danke @pmayer für die Antwort

Genau ich verfüge über ein eigens Zertifikat (selbst signiert). In der Anleitung die benutzt habe, wurden bei Paho die certhPath Files auch nicht benutzt. Es könnte durchaus sein. Ich habe meine SSL Zertifikate meist auch über Lets Encrypt besorgt, was allerdings an dieser Maschine meines Wissens nicht verfügbar ist (Lokales Netz, keine Domain und keine Offenen Ports).

Hast du Testweise den Mosquitto Broker benutzt?

Ja, mein Mosquitto läuft mit LE-SSL-Cert mit meiner (Sub-)Domain am V4 Kabelanschluss. Das Cert habe ich über den certbot mit certonly generiert.

Ich tippe momentan darauf, dass dass Cert und dein Intermediate (CA) nicht korrekt in den Files sind.

Du kannst dir ja mal angucken, mit welchem Zertifikat dein Broker antwortet: openssl s_client -connect <ip/hostname>:8883 bzw. das hier: https://www.cyberciti.biz/faq/test-ssl-certificates-diagnosis-ssl-certificate/

Einen lokalen hostnamen würdest du ja über das /etc/hosts “bauen” können.

Nicht korrekt in den Files sind? Wie meinst du das @pmayer ?

Ich habe mal den Auszug vom Befehl hin ran gehangen kann da nicht das Problem erkennen!

CONNECTED(00000003)
depth=1 CN = An MQTT broker, O = OwnTracks.org, OU = generate-CA, emailAddress = nobody@example.net
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
 0 s:/CN=IWILR3-3/O=OwnTracks.org/OU=generate-CA/emailAddress=nobody@example.net
   i:/CN=An MQTT broker/O=OwnTracks.org/OU=generate-CA/emailAddress=nobody@example.net
 1 s:/CN=An MQTT broker/O=OwnTracks.org/OU=generate-CA/emailAddress=nobody@example.net
   i:/CN=An MQTT broker/O=OwnTracks.org/OU=generate-CA/emailAddress=nobody@example.net
---
Server certificate
-----BEGIN CERTIFICATE-----
Zertikat
-----END CERTIFICATE-----
subject=/CN=IWILR3-3/O=OwnTracks.org/OU=generate-CA/emailAddress=nobody@example.net
issuer=/CN=An MQTT broker/O=OwnTracks.org/OU=generate-CA/emailAddress=nobody@example.net
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2972 bytes and written 434 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 
    Session-ID-ctx:
    Master-Key: 
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - 86 62 03 93 2a bb 9f 30-0d e9 16 4c 28 3a 95 80   .b..*..0...L(:..
    0010 - ad 08 86 40 bd ea 89 41-60 97 e8 45 48 6d 82 e8   ...@...A`..EHm..
    0020 - a8 13 62 8b fe 73 a2 28-2f 8f 1a 50 81 87 0e 8b   ..b..s.(/..P....
    0030 - cd 36 ff ac a7 03 5d e0-54 5f 4a dd 55 66 59 82   .6....].T_J.UfY.
    0040 - 0a 05 de 99 47 1a 8e 50-a5 38 93 96 0d 9d 0c 36   ....G..P.8.....6
    0050 - 71 4e 52 24 14 e1 eb ca-60 ff a8 a2 c3 b1 e7 8f   qNR$....`.......
    0060 - 1a 18 79 8e bc 8c 46 94-e9 c4 54 f6 63 f7 31 4a   ..y...F...T.c.1J
    0070 - 6e 87 45 5f 46 aa fc c2-ab 94 49 41 89 63 33 f3   n.E_F.....IA.c3.
    0080 - f5 a1 2b 6a 06 cf 47 ce-39 20 bd af a2 26 4a b1   ..+j..G.9 ...&J.
    0090 - ad 24 8f a9 f3 b7 2a 0d-1f 6f e9 00 9d c4 cb bd   .$....*..o......
    00a0 - 0d bb 19 f8 51 b2 00 ab-31 2e f7 e2 22 51 b3 18   ....Q...1..."Q..

    Start Time: 1504716534
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---

Eine lokaler Hostname würde meines Wissens aber der Prüfung durch LE nicht stand halten. Die Prüfung erfolgt mittels des hinterlegten DNS Eintrags.

Gruß Pascal

Naja, ob im File entsprechend dein key, deine Cert (crt) und deine CA/Root-Zertifikate passend hinterlegt sind.

Sieht für mich aber soweit gut aus, was der Broker da antwortet. Auch wenn ich nicht weiß warum deine OU owntracks.org ist :wink:

Du könntest mal beim connect mit openssl checken wie es aussieht wenn du dein Zertifikat mitgibst. Da kenne ich mich aber leider auch nicht genau aus…

@pmayer
Meinst du es wäre möglich ein LE Zertifikat + alles was dazu gehört wo anders auf einer anderen Maschine zu erstellen und dieses wie ein Shared Zertifikat zu nutzen? Die Verlängerung des Zertifikats würde ich dann mittels eines cronjobs von der anderen Maschine erledigen.

Sollte meiner Meinung nach funktionieren. Das Zertifikat prüft ja nur den aufgerufenen Namen ab. Ob das jetzt eine interne oder eine externe IP ist müsste völlig egal sein.

Gut ich werde es versuchen. Zertifikat erstelle ich später. Domain habe ich schon angelegt.

Könntest du mir deine Implementierung in deinem Broker und Homegear zeigen?

Ich will da lieber auf Nummer sicher gehen!

Ich hatte das nur mal zum Test von außen probiert, intern connecte ich ohne TLS.
Soweit ich mich erinnere, brauchst du aber nur den hostname mit 8883 und enableTLS einzutragen. verifyCertificate ist ja default true. Den Rest sollte openssl vom Betriebssystem übernehmen.

@pmayer

Ich habe alles mal anschlossen und Erstellt. Die Authentifizierung scheint zu klappen. Lediglich kommen an meinem Test Client MQTTFX keine neuen Daten an. Hast du ne Idee?

Hmm,

nicht wirklich. Siehst du eine nachricht, wenn du mit mosquitto_pub etwas publishst?

Werde ich gleich mal versuchen habe dir mal meine Config Files angehangen.

Mosquitto
port 8883
cafile /etc/mosquitto/ca_certificates/DST_Root_CA_X3.pem
#certfile /etc/mosquitto/certs/fullchain.pem
keyfile /etc/mosquitto/certs/privkey.pem
Homegear

Port of your MQTT message broker.

brokerPort = 8883

# When authentication by username and password is enabled, uncomment the following two lines and fill in your username
# and password.
username = homegear
password = blabla

### TLS options ###

# Set to "true" to enable SSL encryption for MQTT.
enableSSL = true

# The path to the certificate authority's certificate
#caFile = /etc/homegear/ca.crt

# verifyCertificate checks if the server certificate received by the
# MQTT broker is signed by one of the root CAs in /etc/ssl/certs. If you use
# a self signed certificate, please put your root certificate in that
# directory. Only disable the verification for testing purposes. Without
# verification any attacker can pose as your MQTT broker.
# Default: verifyCertificate = true
verifyCertificate = true

# The path to the PEM encoded client certificate.
#certPath = /etc/homegear/mqtt.crt

# The path to the PEM encoded client keyfile.
#keyPath = /etc/homegear/mqtt.key

Sollte so völlig ok sein. Schau mal im Log auf debulevel 5 ob auch die Messages deiner Geräte im mqtt gepostet werden.

Also ich habe mal die Logs geprüft scheinbar versucht Homegear es noch nicht mal mit meinem Broker. Ich sehe keine Meldung von Homegear. Lediglich von Paho sehe ich eine Meldung mit einem Fehler. MXTT kann sich verbinden und ich sehe auch die gesicherte Verbindung in Wireshark. Langsam habe ich ehrlich gesagt keine Idee mehr.

@pmayer Habe die Mosquitto Config leicht angepasst und oben geupdatet!

Update: openHAB hängt über die gesicherte Verbindung drin und MQTTFX. Lediglich die beiden Producer fehlen nun noch Paho und Homegear. Hat jemand noch eine Idee?

Ich habe zurzeit noch eine Letzte Vermutung wo das Problem liegen könnte und zwar denke ich könnte es an der openssl Version liegen. Das Zertifikat wurde mit openssl Verison 1.0.2 erstellt, auf den Clients ist aber 1.0.1 vorhanden. Vielleicht ist hier ja ein Entwickler im Forum @sathya der mir meine Vermutung bestätigen könnte?

Zeig mal bitte den Rest deiner mqtt.conf… Also das oberhalb von brokerPort.

Das Log sollte dir beim Start von homegear auf jeden Fall sagen, dass homegear zum Broker connecten konnte.

@pmayer

# mqtt.conf
#
# MQTT settings.
#

# Set this to "true" to enable MQTT.
# Default: false
enabled = true

# Hostname or IP address of your MQTT message broker.
brokerHostname = mosquitto.example.de

# Port of your MQTT message broker.
brokerPort = 8883

# Name of this client.
clientName = Homegear

# The prefix to use. Every topic starts with this prefix.
# Default: homegear
prefix = homegear

# Unique ID of this Homegear instance. Change this, have you have multiple
# Homegear installations.
homegearId = XXXX-XXXX-XXXX

# Tells the MQTT server to retain received MQTT messages. New clients will then
# receive the last value of a topic on connection.
# Variables of type "Action" are not retained.
retain = true

# When authentication by username and password is enabled, uncomment the following two lines and fill in your username
# and password.
username = homegear
password = 

# The number of parallel processing threads.
processingThreadCount = 5

### Topic payload encodings ###

# Enable topic: homegear/HOMEGEAR_ID/plain/PEERID/CHANNEL/VARIABLE_NAME
# Contains the value as is. E. g.: 43.7.
plainTopic = true

# Enable topic: homegear/HOMEGEAR_ID/json/PEERID/CHANNEL/VARIABLE_NAME
# Puts the value in a JSON array to be JSON-compliant: [43.7].
jsonTopic = true

# Enable topic: homegear/HOMEGEAR_ID/jsonobj/PEERID/CHANNEL/VARIABLE_NAME
# Puts the value into a JSON object. The key is value: { "value": 43.7 }.
jsonobjTopic = true

### TLS options ###

# Set to "true" to enable SSL encryption for MQTT.
enableSSL = true

# The path to the certificate authority's certificate
#caFile = /etc/homegear/ca.crt

# verifyCertificate checks if the server certificate received by the
# MQTT broker is signed by one of the root CAs in /etc/ssl/certs. If you use
# a self signed certificate, please put your root certificate in that
# directory. Only disable the verification for testing purposes. Without
# verification any attacker can pose as your MQTT broker.
# Default: verifyCertificate = true
verifyCertificate = true

# The path to the PEM encoded client certificate.
#certPath = /etc/homegear/mqtt.crt

# The path to the PEM encoded client keyfile.
#keyPath = /etc/homegear/mqtt.key

Hmm. Bis auf das doppelte retain sieht das für mich gut aus. Was sagt das Log beim Starten von homegear mit Debuglevel 5?

@pmayer

Das Retain ist beim Kopieren entstanden und der Config nicht doppelt vorhanden.

Start Log Mosquitto
1504845080: mosquitto version 1.4.14 terminating
1504845080: mosquitto version 1.4.14 (build date Mon, 10 Jul 2017 23:48:43 +0100) starting
1504845080: Config loaded from /etc/mosquitto/mosquitto.conf.
1504845080: Opening ipv4 listen socket on port 8883.
1504845080: Opening ipv6 listen socket on port 8883.
1504845090: New connection from 143.93.197.87 on port 8883.
1504845091: New client connected from 143.93.197.87 as OPENHAB2 (c1, k60, u'openhab').
1504845091: Sending CONNACK to OPENHAB2 (0, 0)
1504845091: Received SUBSCRIBE from OPENHAB2
1504845091:     tinkerforge/bricklet/temperature/t6d/temperature (QoS 1)
1504845091: OPENHAB2 1 tinkerforge/bricklet/temperature/t6d/temperature
1504845091: Sending SUBACK to OPENHAB2

Ich habe mir mal heute das Homegear Log File angeschaut.

homegear.err
09/08/17 11:13:11.709 MQTT Client: Error: Could not send packet to MQTT server, because we are not connected.
09/08/17 11:13:11.710 MQTT Client: Error in file MQTT/Mqtt.cpp line 984 in function void Mqtt::connect(): Hostname is empty

Und dabei festgestellt das mir mitgeteilt wird das der Hostname leer sei