Security review — #sec-1 (HIGH), edge-1 leg. PR 3 of the series. You picked the local-bridge approach; this implements it, self-contained to the edge-host role (no cluster change).
Why a bridge (not just port 8883)
Verified: open3e (0.6.2) and e3oncan have no TLS support — their MQTT code does a bare mqtt_client.connect(host, port), no tls_set(), no cert flags. Only sml2mqtt could do native TLS. So edge-1 can't just point at :8883.
What this does
A local mosquitto on edge-1 that open3e/e3oncan/sml2mqtt reach over loopback (127.0.0.1:1883), bridged to the cluster broker over TLS (mqtt.renner.uno:8883; public LE cert validated via the system CA bundle). Plaintext never leaves the host; the network hop is encrypted.
Two bridge connections preserve the existing cluster users — one as open3e (open3e/# out + open3e/cmnd back), one as sml2mqtt (sml2mqtt/# out). So no cluster-side change, and the current ACLs already cover it.
Availability bonus (#avail-4): the local broker buffers telemetry in RAM during cluster/network blips and flushes on reconnect.
eMMC (per your note)
The local broker writes nothing to flash: persistence false (queue in RAM) + log_dest stdout → the volatile journal → Loki. Called out in the config + README so it stays that way.
Verified before building
edge-1 → :8883 TLS validates (Verify return code: 0); mosquitto 2.1.2 in Arch extra; existing open3e/sml2mqtt cluster ACLs suffice for the bridge; #125's netpol already allows :8883. ansible-playbook --syntax-check clean.
Apply / rollback
Applying installs mosquitto and restarts open3e/e3oncan/sml2mqtt → a brief telemetry reconnect (open3e = heat pump, so a short blip). After it, edge-1's MQTT on the IoT VLAN is TLS-only. This does NOT yet remove :1883 from the cluster LB — that's the final step of #sec-1 after evcc/HA are also on TLS. Rollback = point edge_mqtt_host back to mqtt.renner.uno, re-run.
Want me to apply + validate on edge-1 on your go (confirm both bridges connect, topics still land in the cluster, and edge-1 no longer opens plaintext :1883)?
**Security review — #sec-1 (HIGH), edge-1 leg.** PR 3 of the series. You picked the local-bridge approach; this implements it, self-contained to the edge-host role (no cluster change).
## Why a bridge (not just port 8883)
Verified: **open3e (0.6.2) and e3oncan have no TLS support** — their MQTT code does a bare `mqtt_client.connect(host, port)`, no `tls_set()`, no cert flags. Only sml2mqtt could do native TLS. So edge-1 can't just point at :8883.
## What this does
A **local mosquitto on edge-1** that open3e/e3oncan/sml2mqtt reach over **loopback** (`127.0.0.1:1883`), **bridged to the cluster broker over TLS** (`mqtt.renner.uno:8883`; public LE cert validated via the system CA bundle). Plaintext never leaves the host; the network hop is encrypted.
- **Two bridge `connection`s preserve the existing cluster users** — one as `open3e` (`open3e/#` out + `open3e/cmnd` back), one as `sml2mqtt` (`sml2mqtt/#` out). So **no cluster-side change**, and the current ACLs already cover it.
- **Availability bonus (#avail-4):** the local broker buffers telemetry in RAM during cluster/network blips and flushes on reconnect.
## eMMC (per your note)
The local broker writes **nothing** to flash: `persistence false` (queue in RAM) + `log_dest stdout` → the volatile journal → Loki. Called out in the config + README so it stays that way.
## Verified before building
edge-1 → :8883 TLS validates (`Verify return code: 0`); `mosquitto 2.1.2` in Arch `extra`; existing open3e/sml2mqtt cluster ACLs suffice for the bridge; #125's netpol already allows :8883. `ansible-playbook --syntax-check` clean.
## Apply / rollback
Applying installs mosquitto and restarts open3e/e3oncan/sml2mqtt → a brief telemetry reconnect (open3e = heat pump, so a short blip). After it, edge-1's MQTT on the IoT VLAN is TLS-only. **This does NOT yet remove :1883 from the cluster LB** — that's the final step of #sec-1 after evcc/HA are also on TLS. Rollback = point `edge_mqtt_host` back to `mqtt.renner.uno`, re-run.
Want me to apply + validate on edge-1 on your go (confirm both bridges connect, topics still land in the cluster, and edge-1 no longer opens plaintext :1883)?
Security review #sec-1 (edge-1 leg). open3e/e3oncan/sml2mqtt publish to the
cluster broker in plaintext over the untrusted IoT VLAN, and open3e/e3oncan
have no native MQTTS (their MQTT code does a bare connect()), so "just use
8883" isn't possible for them.
Run a local mosquitto on edge-1 that the clients reach over loopback
(127.0.0.1:1883), bridged to the cluster broker over TLS (mqtt.renner.uno:8883,
public LE cert validated via the system CA bundle). Plaintext stays on
loopback; the wire hop is encrypted. Two bridge connections preserve the
existing cluster identities (open3e user carries open3e/# out + open3e/cmnd
back; sml2mqtt user carries sml2mqtt/# out), so NO cluster-side change is
needed and the existing ACLs already suffice.
Bonus (availability, #avail-4): the local broker buffers telemetry in RAM and
flushes on reconnect, so edge-1 no longer hard-depends on cluster/network
uptime for every publish.
eMMC: the local broker writes NOTHING to flash — persistence false (queue in
RAM) + log_dest stdout (volatile journal -> Loki).
Verified before building: edge-1 -> :8883 TLS validates (return code 0);
mosquitto 2.1.2 in Arch extra; existing open3e/sml2mqtt cluster ACLs cover the
bridge; #125 netpol already allows :8883.
Rollback: point edge_mqtt_host back to mqtt.renner.uno and re-run.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Security review — #sec-1 (HIGH), edge-1 leg. PR 3 of the series. You picked the local-bridge approach; this implements it, self-contained to the edge-host role (no cluster change).
Why a bridge (not just port 8883)
Verified: open3e (0.6.2) and e3oncan have no TLS support — their MQTT code does a bare
mqtt_client.connect(host, port), notls_set(), no cert flags. Only sml2mqtt could do native TLS. So edge-1 can't just point at :8883.What this does
A local mosquitto on edge-1 that open3e/e3oncan/sml2mqtt reach over loopback (
127.0.0.1:1883), bridged to the cluster broker over TLS (mqtt.renner.uno:8883; public LE cert validated via the system CA bundle). Plaintext never leaves the host; the network hop is encrypted.connections preserve the existing cluster users — one asopen3e(open3e/#out +open3e/cmndback), one assml2mqtt(sml2mqtt/#out). So no cluster-side change, and the current ACLs already cover it.eMMC (per your note)
The local broker writes nothing to flash:
persistence false(queue in RAM) +log_dest stdout→ the volatile journal → Loki. Called out in the config + README so it stays that way.Verified before building
edge-1 → :8883 TLS validates (
Verify return code: 0);mosquitto 2.1.2in Archextra; existing open3e/sml2mqtt cluster ACLs suffice for the bridge; #125's netpol already allows :8883.ansible-playbook --syntax-checkclean.Apply / rollback
Applying installs mosquitto and restarts open3e/e3oncan/sml2mqtt → a brief telemetry reconnect (open3e = heat pump, so a short blip). After it, edge-1's MQTT on the IoT VLAN is TLS-only. This does NOT yet remove :1883 from the cluster LB — that's the final step of #sec-1 after evcc/HA are also on TLS. Rollback = point
edge_mqtt_hostback tomqtt.renner.uno, re-run.Want me to apply + validate on edge-1 on your go (confirm both bridges connect, topics still land in the cluster, and edge-1 no longer opens plaintext :1883)?