chore: drop the plain-HTTP route now the panel is proven on TLS
The transport log settles it: the device reaches the server over https and validates the Let's Encrypt chain without trouble. The dedicated port, the Traefik entrypoint and the plain-HTTP router were all built on a hypothesis the evidence has since refused. DEVICE_ALLOW_HTTP goes back to false, so the device routes refuse an unencrypted request again. DEPLOY.md is rewritten around the real cause — the firmware does not follow redirects, and a trailing slash was answered with a 308 — and records the three hypotheses that were wrong, so nobody spends another evening on them. It also names the trap that made this slow: Traefik, a production Next server and tcpdump were each read as saying "no traffic" when all three were simply silent by default. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012cSY9pVhZmJUKNN7wf1Myd
This commit is contained in:
+3
-31
@@ -38,40 +38,12 @@ services:
|
||||
traefik.http.routers.horaires.tls.certresolver: ${TRAEFIK_CERTRESOLVER:-myresolver}
|
||||
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.
|
||||
# Everything is served over TLS, the panel included: its firmware
|
||||
# validates the chain without trouble. A plain-HTTP route existed here
|
||||
# for a while, on the belief that it could not — see DEPLOY.md.
|
||||
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.
|
||||
#
|
||||
# It listens on its own entrypoint rather than on :80. Traefik applies an
|
||||
# entrypoint's HTTP→HTTPS redirection before routing, so no router
|
||||
# priority can escape it — the port has to be one that never redirects.
|
||||
# That also makes the restriction structural: nothing but these four
|
||||
# paths is reachable on 2300, and it is Traefik that guarantees it rather
|
||||
# than application code.
|
||||
#
|
||||
# Requires the matching `device` entrypoint in the shared traefik.yml.
|
||||
# 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: device
|
||||
traefik.http.routers.horaires-device.service: horaires
|
||||
|
||||
backup:
|
||||
# A nightly dump kept for two weeks. Small, boring, and the only thing
|
||||
|
||||
Reference in New Issue
Block a user