# Serves the Furtka landing page + live JSON on :80 (plain HTTP). HTTPS # is **opt-in** — Caddy doesn't serve :443 until the user clicks the # "Enable HTTPS" toggle on /settings, which drops an import snippet into # /etc/caddy/furtka-https.d/. Default install has NO tls site block → # Caddy never generates a self-signed CA / leaf cert → no # SEC_ERROR_BAD_SIGNATURE when a user visits https://furtka.local before # they've trusted anything. That was the 26.14-era regression this file # exists to cure: the old Caddyfile always served :443 with a freshly- # generated cert, and a browser that had ever trusted an older Furtka # box's CA would reject the new one with an unbypassable bad-sig error. # # /apps, /api, /login, /logout, / (home), /settings are reverse-proxied # to the resource-manager API (furtka serve, bound to 127.0.0.1:7000). # Static pages are read from /opt/furtka/current/ — updates flip the # symlink and everything picks up the new content without a Caddy # restart (a `systemctl reload caddy` is still triggered post-swap to # flush the file-server's handle cache). # # Two snippet dirs, both silently no-op when empty: # - /etc/caddy/furtka.d/*.caddyfile → imported inside the :80 block. # The HTTPS toggle's "force HTTP→HTTPS redirect" snippet lands here. # - /etc/caddy/furtka-https.d/*.caddyfile → imported at TOP LEVEL, so # the HTTPS hostname+tls-internal site block can drop in here when # the toggle is on. Hostname is substituted at toggle-time. { # Named-hostname :443 blocks would otherwise make Caddy add its own # HTTP→HTTPS redirect — but we already serve our own `:80` block and # the opt-in /settings toggle owns the redirect. Disable the built-in # to keep a single source of truth. auto_https disable_redirects } (furtka_routes) { handle /api/* { reverse_proxy localhost:7000 } handle /apps* { reverse_proxy localhost:7000 } handle /login* { reverse_proxy localhost:7000 } handle /logout* { reverse_proxy localhost:7000 } # /settings and / — these previously served as static HTML straight # from the catch-all file_server, which meant the auth-guard was # bypassed: a LAN visitor could see the box's version, IP, and # reach the Update-now / Reboot buttons (the API calls behind them # are auth-gated, but the page itself rendered without a redirect # to /login). Route them through the Python handler which checks # the session cookie and either serves the static HTML from # assets/www/ or redirects to /login. handle /settings* { reverse_proxy localhost:7000 } handle / { reverse_proxy localhost:7000 } # Runtime JSON lives under /var/lib/furtka/ so it survives self-updates # (which only swap /opt/furtka/current). handle /status.json { root * /var/lib/furtka file_server } handle /furtka.json { root * /var/lib/furtka file_server } handle /update-state.json { root * /var/lib/furtka file_server } # Download the local root CA cert Caddy generated for `tls internal`. # Public because users need to grab it before they've trusted it. # The private key next to it stays 0600 / caddy-owned. handle /rootCA.crt { root * /var/lib/caddy/pki/authorities/local rewrite * /root.crt file_server header Content-Type "application/x-x509-ca-cert" header Content-Disposition "attachment; filename=furtka-local-rootCA.crt" } handle { root * /opt/furtka/current/assets/www file_server encode gzip } log { output stdout } } # HTTPS opt-in: when /settings toggles HTTPS on, a snippet gets written # into /etc/caddy/furtka-https.d/ that adds the hostname+tls-internal # site block. Empty directory = HTTP-only (default fresh install). import /etc/caddy/furtka-https.d/*.caddyfile :80 { import /etc/caddy/furtka.d/*.caddyfile import furtka_routes }