Files
proxy/ops/nginx_conf
wmantly 22f382b968 Fix TLS handshake failure for any host without a cached target (#132)
Reported: fallback SSL doesn't work in the Docker build. Reproduced —
it's worse than the fallback specifically: TLS was broken for nearly
every connection, including ones with no SNI at all:

  $ curl -vk https://127.0.0.1/
  * TLSv1.3 (IN), TLS alert, internal error (592)
  * OpenSSL/3.0.13: error:0A000438:SSL routines::tlsv1 alert internal error

Root cause: targetinfo.lua's M.get() is shared by two call sites in
two incompatible nginx phases —

  - proxy.conf's access_by_lua_block (a normal HTTP request phase,
    where ngx.exit() is valid)
  - nginx.conf's request_domain callback, which runs during the TLS
    handshake itself (ssl_certificate_by_lua*), where ngx.exit() is
    NOT a supported API

M.get() called ngx.exit() on every lookup failure (no domain/SNI, a
Redis error, or an unregistered host). When invoked from the SSL
phase, that aborted the handshake with a bare "internal error" alert
and produced no log output anywhere — silent and total, not limited
to the unregistered-domain case, since even a connection with no SNI
hits the same code path immediately.

Fix: M.get() no longer calls ngx.exit() itself — it returns
(nil, httpStatus) on failure. proxy.conf now checks the return value
and calls ngx.exit() itself (the phase where that's actually
supported). nginx.conf's request_domain guards the now-possibly-nil
result before indexing it, and leaves ngx.ctx.toAllow unset on
failure so allow_domain() correctly denies issuance and auto-ssl
falls through to the static fallback cert in autossl.conf.

Verified end to end against a running Docker build (deployed the
changed files into a live container and reloaded, rather than relying
on a full rebuild each iteration):
- No SNI at all: TLS now completes; HTTP layer correctly returns 406
  (previously: broken handshake, no response at all)
- Unregistered SNI: same — TLS completes, 406, and openssl s_client
  confirms the cert served is genuinely the fallback
  (CN=sni-support-required-for-valid-ssl)
- A real registered Host: TLS completes and proxies through to the
  backend correctly (confirms the success path is unaffected)
- npm test: 192/192 pass
2026-07-14 21:33:48 -04:00
..