• Matthew Holt's avatar
    tls: Restructure and improve certificate management · fc2ff915
    Matthew Holt authored
    - Expose the list of Caddy instances through caddy.Instances()
    
    - Added arbitrary storage to caddy.Instance
    
    - The cache of loaded certificates is no longer global; now scoped
      per-instance, meaning upon reload (like SIGUSR1) the old cert cache
      will be discarded entirely, whereas before, aggressively reloading
      config that added and removed lots of sites would cause unnecessary
      build-up in the cache over time.
    
    - Key certificates in the cache by their SHA-256 hash instead of
      by their names. This means certificates will not be duplicated in
      memory (within each instance), making Caddy much more memory-efficient
      for large-scale deployments with thousands of sites sharing certs.
    
    - Perform name-to-certificate lookups scoped per caddytls.Config instead
      of a single global lookup. This prevents certificates from stepping on
      each other when they overlap in their names.
    
    - Do not allow TLS configurations keyed by the same hostname to be
      different; this now throws an error.
    
    - Updated relevant tests, with a stark awareness that more tests are
      needed.
    
    - Change the NewContext function signature to include an *Instance.
    
    - Strongly recommend (basically require) use of caddytls.NewConfig()
      to create a new *caddytls.Config, to ensure pointers to the instance
      certificate cache are initialized properly.
    
    - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled
      currently on the CA side). Store temporary challenge cert in instance
      cache, but do so directly by the ACME challenge name, not the hash.
      Modified the getCertificate function to check the cache directly for
      a name match if one isn't found otherwise. This will allow any
      caddytls.Config to be able to help solve a TLS-SNI challenge, with one
      extra side-effect that might actually be kind of interesting (and
      useless): clients could send a certificate's hash as the SNI and
      Caddy would be able to serve that certificate for the handshake.
    
    - Do not attempt to match a "default" (random) certificate when SNI
      is present but unrecognized; return no certificate so a TLS alert
      happens instead.
    
    - Store an Instance in the list of instances even while the instance
      is still starting up (this allows access to the cert cache for
      performing renewals at startup, etc). Will be removed from list again
      if instance startup fails.
    
    - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support.
    
    Server type plugins will need to be updated slightly to accommodate
    minor adjustments to their API (like passing in an Instance). This
    commit includes the changes for the HTTP server.
    
    Certain Caddyfile configurations might error out with this change, if
    they configured different TLS settings for the same hostname.
    
    This change trades some complexity for other complexity, but ultimately
    this new complexity is more correct and robust than earlier logic.
    
    Fixes #1991
    Fixes #1994
    Fixes #1303
    fc2ff915