Updated v2: Documentation (markdown)

Matt Holt 2019-07-03 17:59:06 -06:00
parent 70876007da
commit 58b5478bee

@ -34,12 +34,30 @@ Features which are available in Caddy Enterprise are indicated with   🏢
- [http/servers/routes]()
- [HTTP Placeholders]()
- [http/servers/routes/match]()
- [http.matchers.host]()
- [http.matchers.path]()
- [http.matchers.path_regexp]()
- [http.matchers.method]()
- [http.matchers.query]()
- [http.matchers.header]()
- [http.matchers.header_regexp]()
- [http.matchers.protocol]()
- [http.matchers.not]()
- [http.matchers.remote_ip]()
- [http.matchers.starlark_expr]()
- [http/servers/apply]()
- [http/servers/respond]()
- [http/servers/errors]()
- [http/servers/tls_conn_policies]()
- [http/servers/auto_https]()
- [tls]()
- [tls/certificates]()
- [tls/automation]()
- [tls/automation/policies]()
- [tls.management.acme]()
- [tls/session_tickets]()
- [tls.stek.standard]()
- [tls.stek.distributed]()
# Command-line interface
@ -478,6 +496,22 @@ This will allow you to access capture groups from anywhere in your HTTP route.
Each route takes a list of matcher sets. A matcher set is comprised of matchers of various types. A matcher may be comprised of multiple values.
Example:
```json
[
{
"host": ["example.com"]
},
{
"host": ["example.com", "sub.example.com"],
"path": ["/foo/bar"]
}
]
```
Here you can see there are 2 matcher sets. The first one has one matcher (`host`), and the second one has two (`host` and `path`).
The boolean logic of request matching goes like this:
- Matcher sets are OR'ed (first matching matcher set is sufficient).
@ -497,6 +531,138 @@ Even more advanced logic can be expressed through the Starlark expression matche
Omit matchers entirely to match all requests.
##### http.matchers.host
Matches requests by Host header.
```json
"host": []
```
Host values can contain wildcards to substitute for one label of the domain name.
##### http.matchers.path
Matches requests by request path.
```json
"path": []
```
Paths may contain globular patterns.
##### http.matchers.path_regexp
Matches requests by request path using a regular expression.
```json
"path_regexp": {
"name": "",
"pattern": "",
}
```
- `name`: A name for the regular expression so you can access its capture groups in placeholders.
- `pattern`: The regular expression in [Go's regexp syntax](https://golang.org/pkg/regexp/).
##### http.matchers.method
Matches requests by the request method.
```json
"method": []
```
Methods should be upper-cased.
##### http.matchers.query
Matches requests by query string parameters.
```json
"query": {
"param": ["values"]
}
```
The object keys should be query string parameters, with the values to match in an array, as strings.
##### http.matchers.header
Matches requests by request headers.
```json
"header": {
"Field": ["values"]
}
```
The object keys should be header field names, with the values to match in an array.
##### http.matchers.header_regexp
Matches requests by request headers using a regular expression.
```json
"header_regexp": {
"Field": {
"name": "",
"pattern": ""
}
}
```
The object keys should be header fields, then:
- `name`: A name for the regular expression so you can access its capture groups in placeholders.
- `pattern`: The regular expression in [Go's regexp syntax](https://golang.org/pkg/regexp/).
##### http.matchers.protocol
Matches requests by the protocol being used.
```json
"protocol": ""
```
Possible values are `http`, `https`, or `grpc`.
##### http.matchers.not
Matches requests by negating a matcher set.
```json
"not": {}
```
Its value should be a matcher set. The result of the matcher set will be negated.
##### http.matchers.remote_ip
Matches requests by the client IP address.
```json
"remote_ip": {
"ranges": []
}
```
- `ranges`: A list of IP addresses or CIDR ranges to match.
##### http.matchers.starlark_expr
Matches requests by evaluating a Starlark expression. This provides a great deal of flexibility with regards to boolean logic, and is a fine fit for advanced matching needs.
```json
"starlark_expr": ""
```
The value should be a Starlark expression. (TODO: examples and docs)
#### http/servers/apply
The list of middleware to apply to the request.
@ -847,8 +1013,11 @@ The app is structured like this:
#### tls/certificates
Configures how certificates are loaded into memory. There are several loader modules available.
Configures how certificates are loaded into memory.
All loaded certificates get pooled into the same cache and may be used to complete TLS handshakes for the relevant server names (SNI). Certificates loaded manually (anything other than "automate") are not automatically managed and will have to be refreshed manually before they expire.
There are several loader modules available.
##### tls.certificates.load_files
@ -914,137 +1083,125 @@ Loads certificate and key pairs directly as presented in the config, without nee
#### tls/automation
Configures TLS asset automation.
Configures TLS certificate automation.
TODO.
# FIN
The rest of this document is a WIP. It takes hours and hours to polish the documentation, so please check back later; I'm actively working on it!
What follows is the original ad-hoc documentation that we sent some early testers. We'll replace it with more polished docs very soon.
--------------------------------
TLS App
=========
Here is a contrived example showing all fields:
```
"tls": {
"certificates": {
"load_files": [
{"certificate": "cert.pem", "key": "key.pem", "format": "pem"}
],
"load_folders": ["/var/all_my_certs"],
"load_pem": [
{
"certificate": "-----BEGIN CERTIFICATE-----\nMIIFNTCCBB2gAw...",
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCA..."
}
],
"automate": ["example.com", "example.net"]
},
"automation": {
"policies": [
{
"hosts": ["example.com"],
"management": {
"module": "acme",
"ca": "https://acme-endpoint-here/",
"email": "foo@bar.com"
"key_type": "p256",
"acme_timeout": "1m",
"must_staple": false,
"challenges": {
"http": {
"disabled": false,
"alternate_port": 2080
},
"tls-alpn": {
"disabled": false,
"alternate_port": 2443
},
"dns": {
"provider": "cloudflare",
"auth_email": "me@mine.com",
"auth_key": "foobar1234",
"ttl": 3600,
"propogation_timeout": "5m"
}
},
"on_demand": false,
"storage": { ... }
}
}
],
```json
{
"policies": [],
"on_demand": {
"rate_limit": {
"interval": "1m",
"burst": 3
"interval": "",
"burst": 0
},
"ask": "http://localhost:8123/cert_allowed"
}
},
"session_tickets": {
"disabled": false,
"max_keys": 4,
"key_source": {
"provider": "distributed",
"storage": { ... }
},
"disable_rotation": false,
"rotation_interval": "12h"
"ask": ""
}
}
```
As you can see, there are 4 ways to load certificates:
- from individual files
- from folders
- from hard-coded/in-memory values (enterprise feature)
- from automated management
All loaded certificates get pooled into the same cache and may be used to complete
TLS handshakes for the relevant server names (SNI). Certificates loaded manually
(anything other than "automate") are not automatically managed and will have to
be refreshed manually before they expire.
Automation policies are an expressive way to configure how automated certificates
should be managed. You can optionally switch the policies based on hostnames (SANs),
but omitting that will cause that policy to be applied to all certificates. The first
matching policy is used.
Right now the only manangement module is "acme" which uses Let's Encrypt by default.
There are many fields you can configure, including the ability to customize or toggle
each challenge type, enabling On-Demand TLS (which defers certificate management until
TLS-handshake-time), or customizing the storage unit for those certificates only.
You can also configure On-Demand TLS, which for arbitrary hostnames, should have some
restrictions in place to prevent abuse. You can customize rate limits or a URL to
be queried to ask if a domain name can get a certificate. The URL will be augmented
with the "domain" query string parameter which specifies the hostname in question. The
endpoint must return a 200 OK if a certificate is allowed; anything else will cause it
to be denied. Redirects are not followed.
Finally, you can customize TLS session ticket ephemeral keys (STEKs). This includes
rotation, and source. Enterprise users can have distributed STEKs, which improves TLS
performance over a cluster of load-balanced instances, since TLS sessions can always be
resumed no matter the load balancing.
- `policies`: An ordered list of automation policies.
- `on_demand`: The configuration On-Demand TLS, when needed. On-Demand TLS defers certificate operations to the time they are needed, e.g. during a TLS handshake. Because it is possible to abuse this feature, usage controls are configurable.
- `on_demand.rate_limit`: Configures a rate limit for getting certificates with On-Demand TLS.
- `on_demand.rate_limit.interval`: A duration value. A certificate may be obtained `burst` times during this interval.
- `on_demand.rate_limit.burst`: How many times during an interval a certificate can be obtained.
- `on_demand.ask`: A URL which will be queried to check if Caddy should be allowed to try to get a certificate for a hostname. The name will be passed in a query string parameter like so: `?domain=example.com`. The endpoint must return a 200 OK if a certificate is allowed; anything else will cause it to be denied. Redirects are not followed.
FIN.
#### tls/automation/policies
Automation policies are a very powerful way to describe how Caddy should manage certificates for certain names.
The first matching policy will be used. Policies are matched by hostname (aka "domain name").
```json
{
"hosts": [],
"management": {}
}
```
- `hosts`: The list of host names for which this policy should be applied. Omitting this field matches all hostnames. An empty list matches none.
- `management`: The module to use for management.
##### tls.management.acme
This module uses ACME to manage TLS certificates.
```json
{
"module": "acme",
"ca": "https://acme-staging-v02.api.letsencrypt.org/directory",
"email": "",
"key_type": "",
"acme_timeout": "",
"must_staple": false,
"challenges": {
"http": {
"disabled": false,
"alternate_port": 0
},
"tls-alpn": {
"disabled": false,
"alternate_port": 0
},
"dns": {}
},
"on_demand": false,
"storage": {}
}
```
- `ca`: The ACME CA's directory endpoint.
- `email`: Your email address, so the CA can contact you if necessary. Not required but strongly recommended to provide one so you can be reached if there is a problem.
- `key_type`: The type of key to generate for the certificate. Supported values: `rsa2048`, `rsa4096`, `p256`, `p384`
- `acme_timeout`: Duration to wait before timing out an ACME operation.
- `must_staple`: If true, the certificate will have MustStaple set.
- `challenges`: Configures the various ACME challenge types.
- `challenges.http`: Configures the ACME HTTP challenge type.
- `challenges.http.disabled`: Disables the HTTP challenge.
- `challenges.http.alternate_port`: Use this port for the HTTP challenge. Since the ACME spec requires port 80, you must use port forwarding to this alternate port.
- `challenges.tls-alpn`: Configures the ACME TLS-ALPN challenge type.
- `challenges.tls-alpn.disabled`: Disables the TLS-ALPN challenge.
- `challenges.tls-alpn.alternate_port`: Use this port for the TLS-ALPN challenge. Since the ACME spec requires port 443, you must use port forwarding to this alternate port.
- `challenges.dns`: Configures the ACME DNS challenge. Doing so disables the other challenge types. This challenge type must be configured using a DNS challenge module.
- `on_demand`: If true, certificates will be managed "on demand", that is, during TLS handshakes or when needed, as opposed to at startup.
- `storage`: Optionally configure a separate storage module associated with this manager, instead of using Caddy's global/default-configured storage.
#### tls/session_tickets
Configures Caddy's TLS session tickets. By default, Caddy generates several keys and rotates them automatically on a regular basis, preserving forward secrecy in TLS 1.2. (Caddy is the only web server to do this by default.) You can customize this behavior.
```json
{
"disabled": false,
"max_keys": 4,
"key_source": {},
"disable_rotation": false,
"rotation_interval": "12h"
}
```
- `disabled`: Disables session ticket keys.
- `max_keys`: How many keys to keep in memory.
- `key_source`: A STEK provider module that produces keys.
- `disable_rotation`: Disables STEK rotation. This is discouraged.
- `rotation_interval`: How often to rotate STEKs.
##### tls.stek.standard
Caddy's standard STEK provider module. It generates cyrptographically-secure keys in memory. There is nothing to configure, and it does not need to be specified in a config.
##### tls.stek.distributed
🏢 _Enterprise_
A distributed STEK provider module. This allows Caddy to share STEKs among other instances in its cluster (those which use the same storage configuration), increasing performance and reducing connection latency when behind a load balancer.
```json
{
"storage": {}
}
```
- `storage`: The storage module to use. All instances in the cluster should use the same storage configuration.