{"id":617,"date":"2021-07-12T14:43:50","date_gmt":"2021-07-12T12:43:50","guid":{"rendered":"https:\/\/www.iot-embedded.de\/iot-2021\/?p=617"},"modified":"2021-07-13T02:58:47","modified_gmt":"2021-07-13T00:58:47","slug":"mosquitto-mqtt-broker-ueber-tls-und-client-authentifikation","status":"publish","type":"post","link":"https:\/\/www.iot-embedded.de\/iot-2021\/beverage-monitoring\/mosquitto-mqtt-broker-ueber-tls-und-client-authentifikation\/","title":{"rendered":"Mosquitto MQTT Broker \u00fcber TLS und Client Authentifikation"},"content":{"rendered":"\n<p>In diesem Blogpost geht es um das Generieren von Schl\u00fcsseln f\u00fcr den MQTT Broker, f\u00fcr die einzelnen Clients, sowie die Konfiguration des MQTT Brokers. Ziel ist es einen MQTT Broker so zu konfigurieren, dass dieser nur die Kommunikation von TLS authentifizierten Clients akzeptiert. Die Authentifikation soll hierbei durch signierte Zertifikate geschehen.<\/p>\n\n\n\n<p>Hierf\u00fcr ben\u00f6tigen wir:<\/p>\n\n\n\n<ul><li>Einen MQTT Broker: Als Basis k\u00f6nnen wir die Containerfile von Johannes\u2019 Blogpost nehmen.<\/li><li><code>openssl<\/code> zum Generieren der Schl\u00fcssel und Zertifikate<\/li><li>Ein Zertifikat, um Server und Client zu signieren: Wir erstellen das Zertifikat einfach selbst.<\/li><\/ul>\n\n\n\n<p>Wir generieren: &#8211; CA &#8211; CA Key &#8211; Server Key &#8211; Server Certificate &#8211; Client Key &#8211; Client Certificate<\/p>\n\n\n\n<p>Ein paar Basics die gerne von anderen Lesern korrigiert werden d\u00fcrfen. Die Certificate Authority (CA) ist in unserem Fall ein eigener RSA Key welcher mit einem Passwort gesch\u00fctzt ist. Client und Server besitzen eigen RSA Keys basierend auf diesen Keys erstellen wir Zertifikats Anfragen welche mit Informationen \u00fcber Client und Server gef\u00fcllt sind. Solch eine Anfrage beinhaltet den <code>Common Name<\/code> des Anfragenden, was in unserem Fall die IP-Adresse des Clients oder Servers w\u00e4re.<\/p>\n\n\n\n<p>Die CA nutzt diese Anfragen, um ein Zertifikat f\u00fcr den Server und Client zu erstellen. Fragt nun der Client den Server an, so kann der Server sein Zertifikat vorzeigen. Da der Client das Zertifikat der CA kennt, kann er erkennen, ob der Server wirklich ein Zertifikat besitzt, welches von der CA erstellt wurde. Des Weiteren ist das Zertifikat von dem privaten Schl\u00fcssel des Servers abh\u00e4ngig, so dass nur wer den privaten Schl\u00fcssel besitzt sich auch als richtiger Eigent\u00fcmer des Zertifikates ausgeben kann.<\/p>\n\n\n\n<p>Bei Erg\u00e4nzungen, Korrekturen und Verbesserungen gerne kommentieren!<\/p>\n\n\n\n<p>Zu Beginn erstellen wir den Key f\u00fcr die CA, wichtig hierbei der <code>Common Name<\/code> sollte nicht der gleiche sein wie f\u00fcr einen Client oder Server, der eine Zertifikatsanfrage an die CA schickt. Wir erstellen also den Key, als auch das Zertifikat der CA, gesch\u00fctzt durch ein Passwort. (Am besten merkt man sich das Passwort, wir brauchen es sp\u00e4ter wieder)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ openssl genrsa -des3 -out ca.key 2048\nGenerating RSA private key, 2048 bit long modulus (2 primes)\n....+++++\n.........................................+++++\ne is 65537 (0x010001)\nEnter pass phrase for ca.key:\nVerifying - Enter pass phrase for ca.key:\n\n# Generate CA certificate\n$ openssl req -new -x509 -days 1826 -key ca.key -out ca.crt\n\nEnter pass phrase for ca.key:\nYou are about to be asked to enter information that will be incorporated\ninto your certificate request.\nWhat you are about to enter is what is called a Distinguished Name or a DN\nThere are quite a few fields but you can leave some blank\nFor some fields there will be a default value,\nIf you enter '.', the field will be left blank.\n-----\nCountry Name (2 letter code) &#091;AU]:DE\nState or Province Name (full name) &#091;Some-State]:BW\nLocality Name (eg, city) &#091;]:KA\nOrganization Name (eg, company) &#091;Internet Widgits Pty Ltd]:iot\nOrganizational Unit Name (eg, section) &#091;]:iot\nCommon Name (e.g. server FQDN or YOUR name) &#091;]:mydomainname.xyz\nEmail Address &#091;]:your@mail.com<\/code><\/pre>\n\n\n\n<p>Nun erstellen wir den Key f\u00fcr den MQTT Server. Hierbei nutzen wir kein Passwort, da scheinbar der Mosquitto Broker ansonsten nicht mit dem Key umgehen kann. Zuerst erstellen wir einen neuen Ordner f\u00fcr den Server. Nun generieren wir den RSA key. Basierend auopenssl req -new -x509 -days 1826 -key ca.key -out ca.crt f diesem Key erstellen wir eine Anfrage f\u00fcr ein Zertifikat. Dieses Zertifikat wird dann von der CA ausgestellt. WICHTIG: Wir geben die Information \u00fcber unseren Server gleich per CLI mit, anstatt interaktiv alle Informationen einzutippen. Der Common Name ist hierbei die IP-Adresse des Computers, auf welcher der Mosquitto Broker laufen wird. Beim Erstellen des Zertifikates werden wir nach dem Passwort f\u00fcr den Key der CA gefragt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mkdir -p server\n$ cd server\n$ openssl genrsa -out server.key 2048\n$ openssl req -new -out \n$ openssl req \\\n    -new \\\n    -out server.csr \\\n    -key server.key \\\n    -subj \"\/C=DE\/ST=BW\/L=KA\/O=iot\/OU=iot\/CN=192.168.178.123\"\n$ openssl x509 \\\n    -req \\\n    -in server.csr \\\n    -CA ..\/ca.crt \\\n    -CAkey ..\/ca.key \\\n    -CAcreateserial \\\n    -out server.crt \\\n    -days 360<\/code><\/pre>\n\n\n\n<p>Dasselbe m\u00fcssen wir nun f\u00fcr den Client machen. Hier jedoch mit anderen Key Namen und einem anderen <code>Common Name<\/code>. In unserem Fall verwenden wir die IP-Adresse des ESPs: \u201c192.168.178.121\u201d, diese k\u00f6nnen wir herausfinden, indem wir den ESP mit dem lokalen Netzwerk per WiFi verbinden und dann die IP-Adresse \u00fcber den seriellen Output loggen. Den Code Snippet welchen wir hierzu einem anderen Beispiel hinzugef\u00fcgt haben ist folgender:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n\nSerial.print(\"IP address: \");\nSerial.println(WiFi.localIP());\n...<\/code><\/pre>\n\n\n\n<p>Da wir nun die IP-Adresse wissen k\u00f6nnen wir die Keys und das Zertifikat f\u00fcr den Client erstellen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mkdir -p client\n$ cd client\n$ openssl genrsa -out client.key 2048\n$ openssl req -new -out \n$ openssl req \\\n    -new \\\n    -out client.csr \\\n    -key client.key \\\n    -subj \"\/C=DE\/ST=BW\/L=KA\/O=iot\/OU=iot\/CN=192.168.178.121\"\n$ openssl x509 \\\n    -req \\\n    -in client.csr \\\n    -CA ..\/ca.crt \\\n    -CAkey ..\/ca.key \\\n    -CAcreateserial \\\n    -out client.crt \\\n    -days 360<\/code><\/pre>\n\n\n\n<p>Somit haben wir nun alle Dateien die wir brauchen, der Datei Baum sollte nun folgend aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>tree\n.\n\u251c\u2500\u2500 ca.crt\n\u251c\u2500\u2500 ca.key\n\u251c\u2500\u2500 ca.srl\n\u251c\u2500\u2500 client\n\u2502&nbsp;&nbsp; \u251c\u2500\u2500 client.crt\n\u2502&nbsp;&nbsp; \u251c\u2500\u2500 client.csr\n\u2502&nbsp;&nbsp; \u2514\u2500\u2500 client.key\n\u2514\u2500\u2500 server\n &nbsp;&nbsp; \u251c\u2500\u2500 server.crt\n &nbsp;&nbsp; \u251c\u2500\u2500 server.csr\n &nbsp;&nbsp; \u2514\u2500\u2500 server.key<\/code><\/pre>\n\n\n\n<p>Als n\u00e4chstes m\u00fcssen wir daraus die richtige Konfiguration f\u00fcr den MQTT Broker erstellen. Dieser ben\u00f6tigt das Zertifikat der CA, das Zertifikat f\u00fcr den Server und den privaten Key des Servers. Zudem m\u00fcssen wir in der Konfigurationsdatei auf die einzelnen Keys und Zertifikate zeigen. Zudem wollen wir angeben, dass wir von unseren Clients auch valide Zertifikate und Keys erwarten. Wir erstellen daher einen <code>config<\/code> Ordner, sowie einen <code>config\/ca_certificates<\/code> Ordner und <code>config\/certs<\/code> Ordner. In den <code>ca_certificates<\/code> Ordner kopieren wir das Zertifikat der CA und in den <code>certs<\/code> Ordner kommen des Serves privater Key und Zertifikat. Zudem erstellen wir die Datei <code>config\/mosquitto.conf<\/code> dessen Inhalt sp\u00e4ter gezeigt wird.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ mkdir -p config\/ca_certificates\n$ mkdir -p config\/certs\n$ cp .\/ca.crt .\/config\/ca_certificates\n$ cp .\/server\/server.crt .\/config\/certs\n$ cp .\/server\/server.key .\/config\/certs\n$ touch .\/config\/mosquitto.conf\n$ cat .\/config\/mosquitto.conf\nlistener 8883\nallow_anonymous true\ncafile \/mosquitto\/config\/ca_certificates\/ca.crt\ncertfile \/mosquitto\/config\/certs\/server.crt\nkeyfile \/mosquitto\/config\/certs\/server.key\nrequire_certificate true<\/code><\/pre>\n\n\n\n<p>Diese Konfiguration kann nun in den Container gemounted werden, so dass der MQTT Broker Zugriff auf die Datein hat. Hierf\u00fcr nutzen wir die Kommandos, welche Johannes schon in seinem Blogpost bereitgestellt hat.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker pull eclipse-mosquitto\n$ docker run -it --name mqtt -p 192.168.178.123:8883:8883 -v $(pwd)\/config:\/mosquitto\/config  eclipse-mosquitto\n1623085571: mosquitto version 2.0.10 starting\n1623085571: Config loaded from \/mosquitto\/config\/mosquitto.conf.\n1623085571: Opening ipv4 listen socket on port 8883.\n1623085571: Opening ipv6 listen socket on port 8883.\n1623085571: mosquitto version 2.0.10 running<\/code><\/pre>\n\n\n\n<p>Mit CTRL-C kann man den laufenden Container beenden, da dieser Container im Vordergrund l\u00e4uft. Dies ist praktisch zum Debuggen, da man die Logausgaben des Brokers sieht, jedoch kann man den Container auch detached starten.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker container rm mqtt\n$ docker run -d --name mqtt -p 192.168.178.123:8883:8883 -v $(pwd)\/config:\/mosquitto\/config  eclipse-mosquitto<\/code><\/pre>\n\n\n\n<p>Um diesem als Client auf diesen Broker Nachrichten zu publizieren oder auf ein Topic zu subscriben braucht der Client:<\/p>\n\n\n\n<ul><li>CA Zertifikat<\/li><li>Client private Key<\/li><li>Client Zertifikat<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>$ # Wir sind im Ordner welcher den Key und das Zertifikat des Client beinhaltet\n$ mosquitto_sub -h 192.168.178.123 -t test -p 8883 --cafile ..\/ca.crt --cert client.crt --key client.key\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>$ # Wir sind im Ordner welcher den Key und das Zertifikat des Client beinhaltet\n$ mosquitto_pub -h 192.168.178.123 -t test -p 8883 --cafile ..\/ca.crt --cert client.crt --key client.key -m \"TEST Publish\"<\/code><\/pre>\n\n\n\n<p>Der subscribende Client sollte nun die Nachricht des Publizierenden erhalten. Damit haben wir einen MQTT Broker eingerichtet, bei dem alle Beteiligten \u00fcber TLS kommunizieren, und durch eine CA zertifiziert sind. Die Dateien zu diesem Blogpost sind <a href=\"TODO%20LINK%20ZU%20REPO\">hier<\/a> zu finden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In diesem Blogpost geht es um das Generieren von Schl\u00fcsseln f\u00fcr den MQTT Broker, f\u00fcr die einzelnen Clients, sowie die Konfiguration des MQTT Brokers. Ziel ist es einen MQTT Broker so zu konfigurieren, dass dieser nur die Kommunikation von TLS<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts\/617"}],"collection":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/comments?post=617"}],"version-history":[{"count":1,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts\/617\/revisions"}],"predecessor-version":[{"id":618,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/posts\/617\/revisions\/618"}],"wp:attachment":[{"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/media?parent=617"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/categories?post=617"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.iot-embedded.de\/iot-2021\/wp-json\/wp\/v2\/tags?post=617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}