smartproxy/readme.plan.md

2.7 KiB

Plan: On-Demand Certificate Retrieval in NetworkProxy

When a TLS connection arrives with an SNI for a domain that has no certificate yet, we want to automatically kick off certificate issuance (ACME HTTP-01 or DNS-01) so the domain is provisioned on the fly without prior manual configuration.

Goals

  • Automatically initiate certificate issuance upon first TLS handshake for an unprovisioned domain.
  • Use Port80Handler (HTTP-01) or custom certProvisionFunction (e.g., DNS-01) to retrieve the certificate.
  • Continue the TLS handshake immediately using the default certificate, then swap to the new certificate on subsequent connections.
  • For HTTP traffic on port 80, register the domain for ACME and return a 503 until the challenge is complete.

Plan

  1. Detect missing certificate in SNI callback:

    • In ts/networkproxy/classes.np.networkproxy.ts (or within CertificateManager.handleSNI), after looking up certificateCache, if no cert is found:
      • Call port80Handler.addDomain({ domainName, sslRedirect: false, acmeMaintenance: true }) to trigger dynamic provisioning.
      • Emit a certificateRequested event for observability.
      • Immediately call cb(null, defaultSecureContext) so the handshake uses the default cert.
  2. HTTP-01 fallback on port 80:

    • In ts/port80handler/classes.port80handler.ts``, in handleRequest(), when a request arrives for a new domain not in domainCertificates`:
      • Call addDomain({ domainName, sslRedirect: false, acmeMaintenance: true }).
      • Return HTTP 503 with a message like “Certificate issuance in progress.”
  3. CertProvisioner & events:

    • Ensure CertProvisioner is subscribed to Port80Handler for newly added domains.
    • After certificate issuance completes, Port80Handler emits CERTIFICATE_ISSUED, CertificateManager caches and writes disk, and future SNI callbacks will serve the new cert.
  4. Metrics and cleanup:

    • Track dynamic requests count via a certificateRequested event or metric.
    • Handle error paths: if ACME/DNS fails, emit CERTIFICATE_FAILED and continue serving default cert.
  5. Tests:

    • Simulate a TLS ClientHello for an unconfigured domain: • Verify port80Handler.addDomain is called and certificateRequested event emitted. • Confirm handshake completes with default cert context.
    • Simulate HTTP-01 challenge flow for a new domain: • Verify on first HTTP request, addDomain is invoked and 503 returned. • After manually injecting a challenge in Http01MemoryHandler, verify 200 with key authorization.
    • Simulate successful ACME response and ensure SNI now returns the real cert.
  6. Final validation:

    • Run pnpm test to ensure all existing tests pass.
    • Add new unit/integration tests for the dynamic provisioning flow.