Certificate selection used to be a module, but this seems unnecessary,
especially since the built-in CustomSelectionPolicy allows quite complex
selection logic on a number of fields in certs. If we need to extend
that logic, we can, but I don't think there are SO many possibilities
that we need modules.
This update also allows certificate selection to choose between multiple
matching certs based on client compatibility and makes a number of other
improvements in the default cert selection logic, both here and in the
latest CertMagic.
The hardest part of this was the conn policy consolidation logic
(Caddyfile only, of course). We have to merge connection policies that
we can easily combine, because if two certs are manually loaded in a
Caddyfile site block, that produces two connection policies, and each
cert is tagged with a different tag, meaning only the first would ever
be selected. So given the same matchers, we can merge the two, but this
required improving the Tag selection logic to support multiple tags to
choose from, hence "tags" changed to "any_tag" or "all_tags" (but we
use any_tag in our Caddyfile logic).
Combining conn policies with conflicting settings is impossible, so
that should return an error if two policies with the exact same matchers
have non-empty settings that are not the same (the one exception being
any_tag which we can merge because the logic for them is to OR them).
It was a bit complicated. It seems to work in numerous tests I've
conducted, but we'll see how it pans out in the release candidates.
* pki: Initial commit of PKI app (WIP) (see #2502 and #3021)
* pki: Ability to use root/intermediates, and sign with root
* pki: Fix benign misnamings left over from copy+paste
* pki: Only install root if not already trusted
* Make HTTPS port the default; all names use auto-HTTPS; bug fixes
* Fix build - what happened to our CI tests??
* Fix go.mod
This is a breaking change primarily in two areas:
- Storage paths for certificates have changed
- Slight changes to JSON config parameters
Huge improvements in this commit, to be detailed more in
the release notes.
The upcoming PKI app will be powered by Smallstep libraries.
* remove the certificate tag tracking from global state
* refactored helper state, added log counter
* moved state initialisation close to where it is used.
* added helper state comment
* httpcaddyfile: Begin implementing log directive, and debug mode
For now, debug mode just sets the log level for all logs to DEBUG
(unless a level is specified explicitly).
* httpcaddyfile: Finish 'log' directive
Also rename StringEncoder -> SingleFieldEncoder
* Fix minor bug in replacer (when vals are empty)
See end of issue #3004. Loading the same certificate file multiple times
with different tags will result in it being de-duplicated in the in-
memory cache, because of course they all have the same bytes. This
meant that any certs of the same filename loaded with different tags
would be overwritten by the next certificate of the same filename, and
any conn policies looking for the tags of the previous ones would never
find them, causing connections to fail.
So, now we remember cert filenames and their tags, instead of loading
them multiple times and overwriting previous ones.
A user crafting their own JSON might make this error too... maybe we
won't see it happen. But if it does, one possibility is, when loading
a duplicate cert, instead of discarding it completely, merge the tag
list into the one that's already stored in the cache, then discard.
Configuration via the Caddyfile requires use of env variables, but
an upstream issue is currently blocking that:
https://github.com/go-acme/lego/issues/1054
Providers will need to be retrofitted upstream in order to support env
var configuration.
This ensure that if there are multiple certs that match a particular
ServerName or other parameter, then specifically the one the user
provided in the Caddyfile will be used.
The fix that was initially put forth in #2971 was good, but only for
up to one layer of nesting. The real problem was that we forgot to
increment nesting when already inside a block if we saw another open
curly brace that opens another block (dispenser.go L157-158).
The new 'handle' directive allows HTTP Caddyfiles to be designed more
like nginx location blocks if the user prefers. Inside a handle block,
directives are still ordered just like they are outside of them, but
handler blocks at a given level of nesting are mutually exclusive.
This work benefitted from some refactoring and cleanup.
* http: path matcher: exact match by default; substring matches (#2959)
This is a breaking change.
* caddyfile: Change "matcher" directive to "@matcher" syntax (#2959)
* cmd: Assume caddyfile adapter for config files named Caddyfile
* Sub-sort handlers by path matcher length (#2959)
Caddyfile-generated subroutes have handlers, which are sorted first by
directive order (this is unchanged), but within directives we now sort
by specificity of path matcher in descending order (longest path first,
assuming that longest path is most specific).
This only applies if there is only one matcher set, and the path
matcher in that set has only one path in it. Path matchers with two or
more paths are not sorted like this; and routes with more than one
matcher set are not sorted like this either, since specificity is
difficult or impossible to infer correctly.
This is a special case, but definitely a very common one, as a lot of
routing decisions are based on paths.
* caddyfile: New 'route' directive for appearance-order handling (#2959)
* caddyfile: Make rewrite directives mutually exclusive (#2959)
This applies only to rewrites in the top-level subroute created by the
HTTP caddyfile.
This commit goes a long way toward making automated documentation of
Caddy config and Caddy modules possible. It's a broad, sweeping change,
but mostly internal. It allows us to automatically generate docs for all
Caddy modules (including future third-party ones) and make them viewable
on a web page; it also doubles as godoc comments.
As such, this commit makes significant progress in migrating the docs
from our temporary wiki page toward our new website which is still under
construction.
With this change, all host modules will use ctx.LoadModule() and pass in
both the struct pointer and the field name as a string. This allows the
reflect package to read the struct tag from that field so that it can
get the necessary information like the module namespace and the inline
key.
This has the nice side-effect of unifying the code and documentation. It
also simplifies module loading, and handles several variations on field
types for raw module fields (i.e. variations on json.RawMessage, such as
arrays and maps).
I also renamed ModuleInfo.Name -> ModuleInfo.ID, to make it clear that
the ID is the "full name" which includes both the module namespace and
the name. This clarity is helpful when describing module hierarchy.
As of this change, Caddy modules are no longer an experimental design.
I think the architecture is good enough to go forward.
Use piles from which to draw config values.
Module values can return their name, so now we can do two-way mapping
from value to name and name to value; whereas before we could only map
name to value. This was problematic with the Caddyfile adapter since
it receives values and needs to know the name to put in the config.
Along with several other changes, such as renaming caddyhttp.ServerRoute
to caddyhttp.Route, exporting some types that were not exported before,
and tweaking the caddytls TLS values to be more consistent.
Notably, we also now disable automatic cert management for names which
already have a cert (manually) loaded into the cache. These names no
longer need to be specified in the "skip_certificates" field of the
automatic HTTPS config, because they will be skipped automatically.