Continuing the MQTT security work. The broker had no resource limits at all, and it's now load-bearing + reachable by ~30 untrusted IoT devices (the Shelly fleet) + the edge host on a single 256Mi replica — so a misbehaving/compromised client is a real DoS vector against a critical service.
Adds three guards, all set well above real usage:
message_size_limit 1048576 — MQTT permits up to 256 MB per publish; one such message would OOM the broker. Every legit payload here (HA discovery, Shelly/open3e/evcc telemetry) is <10 KB.
persistent_client_expiration 1d — reap abandoned persistent sessions (the edge bridges reconnect within seconds, so they never hit this).
max_connections 200 per listener — bound a connection flood (~40 clients today; generous headroom vs the previous unlimited).
kubectl kustomize builds clean.
Context / status of the MQTT security work
✅ #sec-1 (plaintext on the untrusted IoT VLAN): edge-1 + all 28 Gen2+ Shellies now on TLS; netpol scoped (#125), ACLs least-privilege (#126).
⏹️HA/evcc → TLS: not pursued — verified in-cluster mqtt.k.renner.uno resolves to the public proxy, so in-cluster TLS needs CoreDNS+cert plumbing for marginal benefit (they're pod-to-pod, never on the untrusted VLAN).
Apply
The ConfigMap has no checksum annotation, so Flux won't roll the pod on config change — after reconcile it needs kubectl -n home-assistant rollout restart deploy/mosquitto (brief reconnect; clients auto-reconnect).
Continuing the MQTT security work. The broker had **no resource limits at all**, and it's now load-bearing + reachable by ~30 untrusted IoT devices (the Shelly fleet) + the edge host on a single 256Mi replica — so a misbehaving/compromised client is a real DoS vector against a critical service.
Adds three guards, all set well above real usage:
- **`message_size_limit 1048576`** — MQTT permits up to **256 MB** per publish; one such message would OOM the broker. Every legit payload here (HA discovery, Shelly/open3e/evcc telemetry) is <10 KB.
- **`persistent_client_expiration 1d`** — reap abandoned persistent sessions (the edge bridges reconnect within seconds, so they never hit this).
- **`max_connections 200`** per listener — bound a connection flood (~40 clients today; generous headroom vs the previous *unlimited*).
`kubectl kustomize` builds clean.
## Context / status of the MQTT security work
- ✅ #sec-1 (plaintext on the untrusted IoT VLAN): **edge-1 + all 28 Gen2+ Shellies now on TLS**; netpol scoped (#125), ACLs least-privilege (#126).
- ⚠️ **5 Gen1 Shellies** remain plaintext — firmware-locked, pending hardware replacement (list provided separately). This blocks fully closing LB-`:1883`.
- ⏹️ **HA/evcc → TLS: not pursued** — verified in-cluster `mqtt.k.renner.uno` resolves to the public proxy, so in-cluster TLS needs CoreDNS+cert plumbing for marginal benefit (they're pod-to-pod, never on the untrusted VLAN).
## Apply
The ConfigMap has no checksum annotation, so Flux won't roll the pod on config change — after reconcile it needs `kubectl -n home-assistant rollout restart deploy/mosquitto` (brief reconnect; clients auto-reconnect).
The broker had no resource limits at all. It's now load-bearing and reachable
by ~30 untrusted IoT devices (the Shelly fleet) + the edge host on a single
256Mi replica, so a misbehaving/compromised client is a real DoS vector.
Add:
- message_size_limit 1048576 — MQTT permits up to 256 MB per publish; one such
message would OOM the broker. Every legit payload here (HA discovery,
Shelly/open3e/evcc telemetry) is <10 KB.
- persistent_client_expiration 1d — reap abandoned persistent sessions (the
edge bridges reconnect within seconds, so they never hit this).
- max_connections 200 per listener — bound a connection flood (~40 clients
today; generous headroom, not the previous unlimited).
All values chosen well above real usage, so no legit client is affected.
Apply: the ConfigMap has no checksum annotation, so Flux won't restart the pod
on its own — needs `kubectl -n home-assistant rollout restart deploy/mosquitto`
(brief reconnect; clients auto-reconnect) after reconcile.
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.
Continuing the MQTT security work. The broker had no resource limits at all, and it's now load-bearing + reachable by ~30 untrusted IoT devices (the Shelly fleet) + the edge host on a single 256Mi replica — so a misbehaving/compromised client is a real DoS vector against a critical service.
Adds three guards, all set well above real usage:
message_size_limit 1048576— MQTT permits up to 256 MB per publish; one such message would OOM the broker. Every legit payload here (HA discovery, Shelly/open3e/evcc telemetry) is <10 KB.persistent_client_expiration 1d— reap abandoned persistent sessions (the edge bridges reconnect within seconds, so they never hit this).max_connections 200per listener — bound a connection flood (~40 clients today; generous headroom vs the previous unlimited).kubectl kustomizebuilds clean.Context / status of the MQTT security work
:1883.mqtt.k.renner.unoresolves to the public proxy, so in-cluster TLS needs CoreDNS+cert plumbing for marginal benefit (they're pod-to-pod, never on the untrusted VLAN).Apply
The ConfigMap has no checksum annotation, so Flux won't roll the pod on config change — after reconcile it needs
kubectl -n home-assistant rollout restart deploy/mosquitto(brief reconnect; clients auto-reconnect).