fix: let the panel reach the API over plain HTTP, deliberately
The e-ink firmware carries a certificate-authority bundle fixed when it was built, so it cannot validate a chain rooted in an authority created afterwards. Let's Encrypt's ISRG Root YR was issued in May 2026 and is not even in an up-to-date Ubuntu CA bundle yet; the kit's firmware predates it. The handshake fails before a request is ever sent, which is why neither Traefik nor the application saw anything at all while the device reported "API connection cannot be established". Ruled out first, with evidence: TLS 1.2 and the ECDHE-RSA-AES-GCM suites an ESP32 needs are both offered, and the intermediate is not cross-signed by an older root, so no alternate path exists in what is served. A Traefik router now serves four device paths over :80, ahead of the entrypoint-wide redirect. The administration stays on TLS. The device token travels in clear; it is used for nothing else and is revocable from the settings page, and the image URL is an unguessable content hash. DEVICE_ALLOW_HTTP existed but was never read — a setting that does nothing misrepresents what it protects. The device routes now refuse an unencrypted request unless it is set, so opening this door is a written decision rather than the silent consequence of a proxy change. DEPLOY.md records the whole diagnosis, including the commands that distinguish a TLS failure from an application one, and what to do the day the firmware learns the new roots. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012cSY9pVhZmJUKNN7wf1Myd
This commit is contained in:
+25
-2
@@ -39,11 +39,34 @@ services:
|
||||
traefik.http.routers.horaires.middlewares: horaires-hsts
|
||||
traefik.http.services.horaires.loadbalancer.server.port: "3010"
|
||||
# The admin is only ever served over TLS; say so to the browsers.
|
||||
# Note the panel is NOT a browser: if its firmware trips over the
|
||||
# certificate chain, see DEPLOY.md before reaching for DEVICE_ALLOW_HTTP.
|
||||
traefik.http.middlewares.horaires-hsts.headers.stsSeconds: "31536000"
|
||||
traefik.http.middlewares.horaires-hsts.headers.stsIncludeSubdomains: "true"
|
||||
|
||||
# --- The panel, in clear, on four paths only ---
|
||||
#
|
||||
# The e-ink firmware carries a certificate-authority bundle fixed when it
|
||||
# was built, so it cannot validate a chain rooted in an authority created
|
||||
# afterwards — which is exactly the case with Let's Encrypt's ISRG Root YR
|
||||
# (May 2026). The handshake fails before a request is ever sent, which is
|
||||
# why neither Traefik nor the application sees anything at all.
|
||||
#
|
||||
# This router therefore serves the four device paths over plain HTTP. The
|
||||
# administration stays on TLS. The trade-off is real and bounded: the
|
||||
# device token travels in clear, it is used for nothing else, and it can
|
||||
# be revoked from Paramètres → Appareils. The image URL is an unguessable
|
||||
# content hash.
|
||||
#
|
||||
# The priority beats the entrypoint-wide HTTP→HTTPS redirection, which is
|
||||
# otherwise applied to everything on :80. Remove this block the day the
|
||||
# firmware learns the new roots, and set DEVICE_ALLOW_HTTP=false — the
|
||||
# application refuses plain requests without it.
|
||||
traefik.http.routers.horaires-device.rule: >-
|
||||
Host(`${APP_DOMAIN}`) && (PathPrefix(`/api/setup`) || PathPrefix(`/api/display`)
|
||||
|| PathPrefix(`/api/log`) || PathPrefix(`/api/device/`))
|
||||
traefik.http.routers.horaires-device.entrypoints: web
|
||||
traefik.http.routers.horaires-device.priority: "2147483647"
|
||||
traefik.http.routers.horaires-device.service: horaires
|
||||
|
||||
backup:
|
||||
# A nightly dump kept for two weeks. Small, boring, and the only thing
|
||||
# standing between a bad migration and retyping a year of opening hours.
|
||||
|
||||
Reference in New Issue
Block a user