Repository navigation
Enable TLS on the broker, with server-certificate verification on every client #25
Description
#7 put usernames, passwords and an ACL on the bench broker (#24), but everything still crosses the LAN in plain text. Anyone who can sniff that segment gets the passwords, and with the io-node password they can publish readings the orchestrator will trust. TLS closes that. Deferred until the certificates are sorted out.
Hostname verification: the cert has to match the name each client dials
None of these clients has a separate "expected hostname" setting. Each one checks the certificate against the host it connected to, so the cert needs a SAN for every name in use:
| Client | Dials today | Verifies hostname? |
|---|---|---|
Orchestrator (mqtt.js on Node tls) |
localhost (MQTT_URL) |
Yes, by default. IP SANs are supported. |
mosquitto_sub/_pub with --cafile |
localhost on the bench, the IP or a name from the LAN |
Yes, unless --insecure |
| io-node (ESP-AT) | 172.18.10.240 (config.MQTT_HOST) |
Unverified. See below. |
So a cert with these SANs covers everything as configured today:
DNS:pbarrett-HP-EliteDesk-800-G2.localdomain # resolves via 172.18.10.1 today
DNS:localhost
IP:127.0.0.1
IP:172.18.10.240
Alternatively, give the broker a stable alias such as mqtt.localdomain on the router, and point clients at that. Moving the Pico to a DNS name adds a dependency on the router's DNS to a node whose silence is dangerous. Keeping it on the IP avoids that.
ESP-AT: what has to be checked on the bench first
These are all not yet verified. The modem's ESP-AT version is not recorded anywhere yet (AT+GMR).
- TLS support at all.
AT+MQTTUSERCFG's scheme becomes3(verify the server cert) rather than1(plain TCP). Scheme2encrypts without verifying anything, and that is not worth doing, because it doesn't stop a MITM. - How the CA gets onto the modem. ESP-AT reads certificates from its own flash partition, not per connection over AT. Recent versions write that partition with
AT+SYSMFG; older ones need the partition reflashed with esptool. The deploy would have to provision the modem as well as the Pico. - Whether it checks the hostname against an IP. The esp-tls layer passes the
AT+MQTTCONNhost through for verification. Older mbedTLS matches DNS SANs and the CN only, not IP SANs. If so, the Pico needs either a DNS name or a CN of172.18.10.240. - Clock. If certificate validity dates are enforced and the modem has no SNTP time, a fresh cert can read as "not yet valid". Check whether
AT+CIPSNTPCFGis needed. - A refused handshake will flash code 5, the same as any broker fault.
docs/broker-auth.mdanddocs/startup-and-status-led.mdshould say that.
Broker shape
- TLS listener on 8883 for the LAN.
- 1883 either goes or is restricted to loopback for the orchestrator. Note Broker accepts loopback connections only, so no node can publish #7's warning:
listener 1883 127.0.0.1drops[::1], and the orchestrator'slocalhostmay resolve to either. Moving the orchestrator tomqtts://localhost:8883with the CA avoids the question. - Keep
password_fileandacl_fileon every listener. TLS protects the password in transit; it doesn't replace the ACL.
Expiry is an outage
An expired server cert takes every client off the broker at once. The node would flash code 5, the orchestrator would lose its sensors, and blocks would degrade to unknown. Choose a long validity for a private CA, and record the renewal date and procedure in docs/broker-auth.md. Consider a check that warns ahead of expiry.
Later, optional
Client certificates (ESP-AT schemes 4 and 5) could replace per-node passwords. The ACL can then key on the cert's CN with use_identity_as_username. That's more provisioning, and the ACL already limits what a stolen node credential can do, so it's not part of this issue.
Acceptance
- The node connects over TLS with server-certificate verification enabled (not scheme 2), and it's proven on the bench that the node refuses a cert signed by a different CA.
- The orchestrator and bench
mosquitto_subconnect with the CA. Plain-text connects to the LAN listener are refused. - A packet capture of a node publish shows no readable password or payload.
docs/broker-auth.mdcovers the CA, the SANs, expiry and renewal, and modem provisioning.
Activity