Skip to content

[Agent] Implement HTTPS/TLS in the built-in web server #650

Open

Description

@matteius

Problem and evidence

The built-in libuv web server has never supported HTTPS. A partial-feature audit (Oct 2026) found the setting wired up end to end but never implemented:

  • src/web/libuv_server.c:157-162: if config->ssl_enabled, it logs "TLS support requested (not yet implemented)" and sets server->tls_ctx = NULL.
  • src/web/libuv_server.c:577-580: // TODO: Free TLS context based on SSL library.
  • include/web/http_server.h:30-32 has ssl_enabled, cert_path and key_path. include/web/web_server.h:17 declares set_ssl_settings().
  • src/core/main.c:1100 hardcodes .ssl_enabled = false, and no config key sets it.
  • CMakeLists.txt:87-90, 197-216: ENABLE_SSL (default OFF) with mbedTLS, WolfSSL or OpenSSL selection links libraries that no server code uses.

Today the only way to serve the UI over HTTPS is a reverse proxy. Turning on ENABLE_SSL changes nothing.

Expected behavior and scope

  • Add [web] config keys, for example ssl_enabled, ssl_cert_path and ssl_key_path (match existing naming in src/core/config.c around line 968), and pass them into http_server_config_t in main.c.
  • Implement TLS termination in the libuv server for a single backend first. mbedTLS is the best choice because it is already a required dependency for ONVIF/auth (DETECT_MBEDTLS_ONCE). Use memory BIOs or the mbedTLS custom send/recv callbacks layered on the existing uv_read / uv_write paths.
  • Free the TLS context on shutdown.
  • If cert or key loading fails, refuse to start the listener with a clear log_error (fail closed). Do not silently fall back to HTTP.
  • Optional: an HTTP-to-HTTPS redirect listener. Keep it out of scope unless it's trivial.
  • Out of scope: ACME / Let's Encrypt, and client certificates.

Acceptance criteria

  • With ENABLE_SSL=ON and valid PEM cert and key, curl -k https://host:port/api/health (or any API route) works, the UI loads, and login cookies work. Check that the Secure cookie flag is set when TLS is on.
  • Streaming routes that proxy go2rtc (/go2rtc/..., WebSocket/MSE upgrades) work over TLS, or the limitation is documented.
  • A missing or invalid cert produces a clear startup error.
  • A build with ENABLE_SSL=OFF behaves exactly as today. If ssl_enabled=true is set in such a build, log a warning that the build has no TLS.
  • The ENABLE_SSL / USE_WOLFSSL / OpenSSL CMake branches either work or are removed, so none of them links unused libraries.
  • Docs: add the config keys and a short "HTTPS without a reverse proxy" section.

Validation

  • Unit or integration test that starts the server with a self-signed cert generated at test time and completes a TLS handshake plus one HTTP request.
  • Run the full ctest after building all targets (cmake --build build, not just --target lightnvr).
  • Run the sanitizer workflow. TLS buffer handling is a classic overflow and use-after-free area.

Constraints and rollback

  • Security-sensitive. Use the library defaults for protocol and cipher selection (TLS 1.2+), and don't log key material.
  • No change for existing HTTP deployments. Rollback is reverting the PR; the config keys default off.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions