MQTT-BaCo - Installation MQTT
Debian 13: MQTT (Mosquitto) schnell & sehr sicher mit Zertifikats-Auth (mTLS) + TLS 1.3
Ein Zertifikat, das 500 Jahre gültig ist, ist nicht “super sicher”. Nicht wegen Mathematik allein, sondern wegen Praxis: Schlüssel können kompromittiert werden, Algorithmen werden über Jahrzehnte schwächer, Geräte werden ersetzt, und manche Stacks/Policies mögen extrem lange Laufzeiten nicht.
Empfehlung: Root-CA sehr lang (ja, wenn du willst 500 Jahre), aber Server- und Client-Zertifikate kurz (z.B. 1–2 Jahre) und rotieren. Das ist der übliche “maximal sicher”-Ansatz. Unten ist beides dokumentiert.
1. Architektur-Entscheidung
- Broker: Eclipse Mosquitto (leichtgewichtig, schnell, standardnah)
- Transport: TLS 1.3 (MQTTS auf Port 8883)
- Authentifizierung: Client-Zertifikate (require_certificate)
- Autorisierung: ACL-Datei, Username aus Zertifikat (CN) via
use_identity_as_username
2. Pakete installieren (Debian 13)
sudo apt update
sudo apt install -y mosquitto mosquitto-clients openssl ca-certificates
3. Verzeichnisstruktur & Rechte
Wir legen ein PKI-Verzeichnis an, in dem der Broker seine Server-Zertifikate liest. Die Root-CA-Schlüssel sollten im Idealfall offline bleiben.
# PKI-Verzeichnis: lesbar für Gruppe "mosquitto", private Keys später restriktiv
sudo install -d -m 0750 -o root -g mosquitto /etc/mosquitto/pki
# Optional: eigenes Arbeitsverzeichnis für CA/Signing (nicht auf dem Broker lassen, wenn "super sicher")
sudo install -d -m 0700 -o root -g root /root/mqtt-pki
4. PKI erstellen (Root-CA + Server + Client)
4.1 Root-CA erstellen (Beispiel: 500 Jahre)
Wir nutzen ECDSA (P-384) für die Root-CA. Das ist effizient und stark.
Hinweis zu “500 Jahre”: Wenn du das am 24.12.2025 erstellst, entsprechen 500 Jahre 182621 Tagen.
cd /root/mqtt-pki
umask 077
# Root-CA Private Key
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:secp384r1 -out ca.key
# Root-CA Zertifikat (selbstsigniert)
# 500 Jahre ab 24.12.2025: -days 182621
openssl req -x509 -new -sha384 -days 182621 \
-key ca.key -out ca.crt \
-subj "/CN=MQTT Root CA/O=YourOrg/OU=IoT/C=DE" \
-addext "basicConstraints=critical,CA:TRUE,pathlen:1" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash"
ca.key auf ein Offline-System (USB, Tresor, was auch immer Menschen so machen) und lasse auf dem Broker nur ca.crt.4.2 Server-Zertifikat erstellen (TLS für den Broker)
Der Broker braucht ein Server-Zertifikat mit korrekten SANs (DNS/IP), damit Clients den Hostnamen prüfen können.
cd /root/mqtt-pki
umask 077
# Server Key (P-256 ist schneller, i.d.R. sehr kompatibel)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out server.key
# CSR mit SAN (DNS + optional IP) - passe mqtt.example.lan und IP an
openssl req -new -sha256 \
-key server.key -out server.csr \
-subj "/CN=mqtt.example.lan/O=YourOrg/OU=IoT/C=DE" \
-addext "subjectAltName=DNS:mqtt.example.lan,IP:192.168.1.10"
# Extensions für Server-Zertifikat
cat > server.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:mqtt.example.lan,IP:192.168.1.10
EOF
# Server-Zertifikat signieren
# Empfohlen: kurz (z.B. 825 Tage ~ 2,25 Jahre) statt 500 Jahre.
openssl x509 -req -sha256 -days 825 \
-in server.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -extfile server.ext
-days 825 durch -days 182621. Das ist aber das Gegenteil von “Keys rotieren” und damit nicht “maximal sicher”.4.3 Client-Zertifikat erstellen (mTLS-Clientauth)
Der Client authentifiziert sich per Zertifikat. Der Broker kann den CN als “Username” verwenden (für ACLs).
cd /root/mqtt-pki
umask 077
# Client Key
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out client-sensor01.key
# CSR (CN entspricht später dem Username, wenn use_identity_as_username=true)
openssl req -new -sha256 \
-key client-sensor01.key -out client-sensor01.csr \
-subj "/CN=sensor01/O=YourOrg/OU=IoT/C=DE"
# Extensions für Client-Zertifikat
cat > client.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=clientAuth
EOF
# Client-Zertifikat signieren (empfohlen kurz, z.B. 365 Tage)
openssl x509 -req -sha256 -days 365 \
-in client-sensor01.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out client-sensor01.crt -extfile client.ext
5. Zertifikate zum Broker installieren
Auf dem Broker brauchen wir:
ca.crt(die CA, der der Broker vertraut)server.crt+server.key(Server-Identität)
# Kopieren
sudo cp /root/mqtt-pki/ca.crt /etc/mosquitto/pki/
sudo cp /root/mqtt-pki/server.crt /etc/mosquitto/pki/
sudo cp /root/mqtt-pki/server.key /etc/mosquitto/pki/
# Rechte: private Keys nur für mosquitto lesbar
sudo chown root:mosquitto /etc/mosquitto/pki/ca.crt /etc/mosquitto/pki/server.crt
sudo chown mosquitto:mosquitto /etc/mosquitto/pki/server.key
sudo chmod 0640 /etc/mosquitto/pki/ca.crt /etc/mosquitto/pki/server.crt
sudo chmod 0400 /etc/mosquitto/pki/server.key
ca.key (Root-Private-Key) nicht auf dem Broker, wenn du es ernst meinst.6. Mosquitto sicher konfigurieren (nur TLS + mTLS)
6.1 Hauptkonfiguration prüfen
In Debian liegt die Hauptdatei typischerweise unter /etc/mosquitto/mosquitto.conf und inkludiert Zusatzdateien aus /etc/mosquitto/conf.d/. Stelle sicher, dass dort ein include_dir /etc/mosquitto/conf.d existiert.
6.2 TLS/mTLS Listener anlegen
Neue Datei: /etc/mosquitto/conf.d/secure-tls.conf
# /etc/mosquitto/conf.d/secure-tls.conf
# Einstellungen pro Listener getrennt behandeln
per_listener_settings true
# Optional: $SYS Infos reduzieren (weniger Fingerprinting)
sys_interval 0
# TLS Listener (MQTTS)
listener 8883
protocol mqtt
# TLS 1.3 only (Minimum ist tlsv1.3)
tls_version tlsv1.3
# Server-Zertifikat + Key
cafile /etc/mosquitto/pki/ca.crt
certfile /etc/mosquitto/pki/server.crt
keyfile /etc/mosquitto/pki/server.key
# TLS 1.3 Ciphersuites (Defaults sind okay, explizit ist klarer)
ciphers_tls1.3 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
# mTLS: Client muss Zertifikat liefern
require_certificate true
# CN aus Client-Zertifikat als Username verwenden (für ACLs)
use_identity_as_username true
# Keine anonymen Clients
allow_anonymous false
# Autorisierung über ACL-Datei
acl_file /etc/mosquitto/aclfile
# Optional: Zertifikate sperren (CRL)
# crlfile /etc/mosquitto/pki/ca.crl
6.3 ACL-Datei erstellen
Datei: /etc/mosquitto/aclfile
# Standard: alles verbieten (explizit)
topic deny #
# Pattern-ACL: Jeder Client darf nur in seinen eigenen Namensraum
# %u ist der Username, der hier aus dem Zertifikats-CN kommt (use_identity_as_username)
pattern readwrite clients/%u/#
# Beispiel: Wenn du willst, dass jeder auch Status lesen kann:
# topic read clients/+/status
sudo chown root:mosquitto /etc/mosquitto/aclfile
sudo chmod 0640 /etc/mosquitto/aclfile
7. Dienst starten & prüfen
sudo systemctl enable --now mosquitto
sudo systemctl status mosquitto
Port prüfen (ohne “rumgrep’en”):
ss -ltnp | less
# Suche im less nach ":8883"
8. Firewall (nftables) minimal hart machen
Datei: /etc/nftables.conf (in der input-Chain ergänzen)
# Beispiel (IPv4): Erlaube 8883 nur aus LAN 192.168.1.0/24
tcp dport 8883 ip saddr 192.168.1.0/24 accept
# Optional (IPv6) analog:
# tcp dport 8883 ip6 saddr fd00:1234:abcd::/64 accept
sudo systemctl enable --now nftables
sudo nft list ruleset | less
9. Systemd-Hardening (optional, aber sinnvoll)
Drop-in erstellen: /etc/systemd/system/mosquitto.service.d/hardening.conf
sudo install -d -m 0755 /etc/systemd/system/mosquitto.service.d
sudo tee /etc/systemd/system/mosquitto.service.d/hardening.conf >/dev/null <<'EOF'
[Service]
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
LockPersonality=true
RestrictNamespaces=true
MemoryDenyWriteExecute=true
UMask=0077
# Mosquitto braucht Schreibzugriff für Persistence/Logs (falls aktiviert)
ReadWritePaths=/var/lib/mosquitto /var/log/mosquitto
EOF
sudo systemctl daemon-reload
sudo systemctl restart mosquitto
ReadWritePaths weiter einschränken.10. Funktionstest mit mosquitto_pub / mosquitto_sub (mTLS)
Client-Dateien (auf dem Client-System):
ca.crtclient-sensor01.crtclient-sensor01.key
# Subscribe (TLS 1.3, mTLS)
mosquitto_sub -h mqtt.example.lan -p 8883 \
--tls-version tlsv1.3 \
--cafile ca.crt \
--cert client-sensor01.crt \
--key client-sensor01.key \
-t 'clients/sensor01/#' -v
# Publish
mosquitto_pub -h mqtt.example.lan -p 8883 \
--tls-version tlsv1.3 \
--cafile ca.crt \
--cert client-sensor01.crt \
--key client-sensor01.key \
-t 'clients/sensor01/test' -m 'hello mTLS'
--insecure benutzen, wenn du “super sicher” sagst. Das deaktiviert Zertifikatsprüfung.11. Zertifikate rotieren (empfohlen) & Reload ohne Downtime
# Neue server.crt/server.key nach /etc/mosquitto/pki/ kopieren (atomar ersetzen)
# dann:
sudo systemctl kill -s HUP mosquitto
12. Optional: Zertifikate sperren (CRL)
Mosquitto unterstützt eine CRL-Datei. Damit kannst du kompromittierte Client-Zertifikate “abschalten”, ohne die CA zu wechseln. Das erfordert aber, dass du deine CA “richtig” mit Datenbank (index.txt) betreibst.
# In /etc/mosquitto/conf.d/secure-tls.conf aktivieren:
# crlfile /etc/mosquitto/pki/ca.crl
13. Kurz-Checkliste “wirklich sicher”
- Nur Port 8883 offen, ideal nur aus VPN/LAN.
- TLS 1.3 only, mTLS Pflicht.
- CA Private Key offline.
- Client-Zerts kurzlebig + Rotation.
- ACLs restriktiv, Default deny.
- Regelmäßige Security Updates (unattended-upgrades, wenn passend).