mirror of
https://github.com/caddyserver/website.git
synced 2025-04-22 04:56:17 -04:00
Docs for upcoming v2.5.0 release (#216)
* docs: new `log` filters in Caddyfile * docs: `renew_interval` global option * docs: Update access log example * docs: `log_credentials` global option * docs: `vars`, `vars_regexp` matchers * docs: `roll_uncompressed`, `roll_local_time` * docs: `http_redirect` listener wrapper * docs: `pki` app * docs: `strict_sni_host` options * docs: `default_bind` option * docs: `method` directive * docs: `tls internal` subdirectives * Apply suggestions from code review Co-authored-by: Matt Holt <mholt@users.noreply.github.com> * Matchers, options, file_server, reverse_proxy * More clarifications / corrections * Corrections from review * Typo fix * One more note about dynamic upstreams * Tab -> space * Update module namespaces * Update some docs about logging * `copy_response`, `copy_response_headers`, `replace_status` * `dns_challenge_domain_override` * `caddy trust`, API endpoints * `trusted_proxies` * Note about `pass_thru` being only useful inside `route` * Improve logging docs to clarify the difference * A bit of polish on patterns * request_body: Clarify error behavior * review Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
This commit is contained in:
parent
c734cc3e64
commit
a1ddadf798
19 changed files with 575 additions and 157 deletions
|
@ -42,6 +42,12 @@ To get started with the API, try our [API tutorial](/docs/api-tutorial) or, if y
|
||||||
- **[Using `@id` in JSON](#using-id-in-json)**
|
- **[Using `@id` in JSON](#using-id-in-json)**
|
||||||
Easily traverse into the config structure
|
Easily traverse into the config structure
|
||||||
|
|
||||||
|
- **[GET /pki/ca/<id>](#get-pkicaid)**
|
||||||
|
Returns information about a particular [PKI app](/docs/json/apps/pki/) CA
|
||||||
|
|
||||||
|
- **[GET /pki/ca/<id>/certificates](#get-pkicaidcertificates)**
|
||||||
|
Returns the certificate chain of a particular [PKI app](/docs/json/apps/pki/) CA
|
||||||
|
|
||||||
- **[GET /reverse_proxy/upstreams](#get-reverse-proxyupstreams)**
|
- **[GET /reverse_proxy/upstreams](#get-reverse-proxyupstreams)**
|
||||||
Returns the current status of the configured proxy upstreams
|
Returns the current status of the configured proxy upstreams
|
||||||
|
|
||||||
|
@ -232,6 +238,40 @@ but with an ID, the path becomes
|
||||||
which is much easier to remember and write by hand.
|
which is much easier to remember and write by hand.
|
||||||
|
|
||||||
|
|
||||||
|
## GET /pki/ca/<id>
|
||||||
|
|
||||||
|
Returns information about a particular [PKI app](/docs/json/apps/pki/) CA by its ID. If the requested CA ID is the default (`local`), then the CA will be provisioned if it has not already been. Other CA IDs will return an error if they have not been previously provisioned.
|
||||||
|
|
||||||
|
<pre><code class="cmd"><span class="bash">curl "http://localhost:2019/pki/ca/local" | jq</span>
|
||||||
|
{
|
||||||
|
"id": "local",
|
||||||
|
"name": "Caddy Local Authority",
|
||||||
|
"root_common_name": "Caddy Local Authority - 2022 ECC Root",
|
||||||
|
"intermediate_common_name": "Caddy Local Authority - ECC Intermediate",
|
||||||
|
"root_certificate": "-----BEGIN CERTIFICATE-----\nMIIB ... gRw==\n-----END CERTIFICATE-----\n",
|
||||||
|
"intermediate_certificate": "-----BEGIN CERTIFICATE-----\nMIIB ... FzQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
}</code></pre>
|
||||||
|
|
||||||
|
|
||||||
|
## GET /pki/ca/<id>/certificates
|
||||||
|
|
||||||
|
Returns the certificate chain of a particular [PKI app](/docs/json/apps/pki/) CA by its ID. If the requested CA ID is the default (`local`), then the CA will be provisioned if it has not already been. Other CA IDs will return an error if they have not been previously provisioned.
|
||||||
|
|
||||||
|
This endpoint is used internally by the [`caddy trust`](/docs/command-line#caddy-trust) command to allow installing the CA's root certificate to your system's trust store.
|
||||||
|
|
||||||
|
<pre><code class="cmd"><span class="bash">curl "http://localhost:2019/pki/ca/local/certificates"</span>
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIByDCCAW2gAwIBAgIQViS12trTXBS/nyxy7Zg9JDAKBggqhkjOPQQDAjAwMS4w
|
||||||
|
...
|
||||||
|
By75JkP6C14OfU733oElfDUMa5ctbMY53rWFzQ==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIBpDCCAUmgAwIBAgIQTS5a+3LUKNxC6qN3ZDR8bDAKBggqhkjOPQQDAjAwMS4w
|
||||||
|
...
|
||||||
|
9M9t0FwCIQCAlUr4ZlFzHE/3K6dARYKusR1ck4A3MtucSSyar6lgRw==
|
||||||
|
-----END CERTIFICATE-----</code></pre>
|
||||||
|
|
||||||
|
|
||||||
## GET /reverse_proxy/upstreams
|
## GET /reverse_proxy/upstreams
|
||||||
|
|
||||||
Returns the current status of the configured reverse proxy upstreams (backends) as a JSON document.
|
Returns the current status of the configured reverse proxy upstreams (backends) as a JSON document.
|
||||||
|
|
|
@ -179,6 +179,8 @@ The DNS challenge performs an authoritative DNS lookup for the candidate hostnam
|
||||||
|
|
||||||
This challenge does not require any open ports, and the server requesting a certificate does not need to be externally accessible. However, the DNS challenge requires configuration. Caddy needs to know the credentials to access your domain's DNS provider so it can set (and clear) the special TXT records. If the DNS challenge is enabled, other challenges are disabled by default.
|
This challenge does not require any open ports, and the server requesting a certificate does not need to be externally accessible. However, the DNS challenge requires configuration. Caddy needs to know the credentials to access your domain's DNS provider so it can set (and clear) the special TXT records. If the DNS challenge is enabled, other challenges are disabled by default.
|
||||||
|
|
||||||
|
Since ACME CAs follow DNS standards when looking up TXT records for challenge verification, you can use CNAME records to delegate answering the challenge to other DNS zones. This can be used to delegate the `_acme-challenge` subdomain to another zone. This is particularly useful if your DNS provider doesn't provide an API, or isn't supported by one of the DNS plugins for Caddy.
|
||||||
|
|
||||||
DNS provider support is a community effort. [Learn how to enable the DNS challenge for your provider at our wiki.](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148)
|
DNS provider support is a community effort. [Learn how to enable the DNS challenge for your provider at our wiki.](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ Directive | Description
|
||||||
**[import](/docs/caddyfile/directives/import)** | Include snippets or files
|
**[import](/docs/caddyfile/directives/import)** | Include snippets or files
|
||||||
**[log](/docs/caddyfile/directives/log)** | Enables access/request logging
|
**[log](/docs/caddyfile/directives/log)** | Enables access/request logging
|
||||||
**[map](/docs/caddyfile/directives/map)** | Maps an input value to one or more outputs
|
**[map](/docs/caddyfile/directives/map)** | Maps an input value to one or more outputs
|
||||||
|
**[method](/docs/caddyfile/directives/method)** | Change the HTTP method internally
|
||||||
**[metrics](/docs/caddyfile/directives/metrics)** | Configures the Prometheus metrics exposition endpoint
|
**[metrics](/docs/caddyfile/directives/metrics)** | Configures the Prometheus metrics exposition endpoint
|
||||||
**[php_fastcgi](/docs/caddyfile/directives/php_fastcgi)** | Serve PHP sites over FastCGI
|
**[php_fastcgi](/docs/caddyfile/directives/php_fastcgi)** | Serve PHP sites over FastCGI
|
||||||
**[push](/docs/caddyfile/directives/push)** | Push content to the client using HTTP/2 server push
|
**[push](/docs/caddyfile/directives/push)** | Push content to the client using HTTP/2 server push
|
||||||
|
@ -115,7 +116,8 @@ request_body
|
||||||
|
|
||||||
redir
|
redir
|
||||||
|
|
||||||
# URI manipulation
|
# incoming request manipulation
|
||||||
|
method
|
||||||
rewrite
|
rewrite
|
||||||
uri
|
uri
|
||||||
try_files
|
try_files
|
||||||
|
|
|
@ -22,5 +22,5 @@ acme_server [<matcher>] {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- **ca** specifies the ID of the certificate authority with which to sign certificates. The default is `local`, which is Caddy's default CA, intended for locally-used, self-signed certificates, which is most common in dev environments. For broader use, it is recommended to specify a different CA to avoid confusion. If the CA with the given ID does not already exist, it will be created.
|
- **ca** specifies the ID of the certificate authority with which to sign certificates. The default is `local`, which is Caddy's default CA, intended for locally-used, self-signed certificates, which is most common in dev environments. For broader use, it is recommended to specify a different CA to avoid confusion. If the CA with the given ID does not already exist, it will be created. See the [PKI app global options](/docs/caddyfile/options#pki-options) to configure alternate CAs.
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ file_server [<matcher>] [browse] {
|
||||||
precompressed <formats...>
|
precompressed <formats...>
|
||||||
status <status>
|
status <status>
|
||||||
disable_canonical_uris
|
disable_canonical_uris
|
||||||
|
pass_thru
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ file_server [<matcher>] [browse] {
|
||||||
- **precompressed** is the list of encoding formats to search for precompressed sidecar files. Arguments are an ordered list of encoding formats to search for precompressed sidecar files. Supported formats are `gzip`, `zstd` and `br`.
|
- **precompressed** is the list of encoding formats to search for precompressed sidecar files. Arguments are an ordered list of encoding formats to search for precompressed sidecar files. Supported formats are `gzip`, `zstd` and `br`.
|
||||||
- **status** is an optional status code override to be used when writing the response. Particularly useful when responding to a request with a custom error page. Can be a 3-digit status code, For example: `404`. Placeholders are supported. By default, the written status code will typically be `200`, or `206` for partial content.
|
- **status** is an optional status code override to be used when writing the response. Particularly useful when responding to a request with a custom error page. Can be a 3-digit status code, For example: `404`. Placeholders are supported. By default, the written status code will typically be `200`, or `206` for partial content.
|
||||||
- **disable_canonical_uris** disables the default behaviour of redirecting to add a trailing slash if the request path is a directory, or remove the trailing slash if the request path is a file. Note that by default, canonicalization will not happen if the last element of the request's path (the filename) underwent an internal rewrite, to avoid clobbering an explicit rewrite with implicit behaviour.
|
- **disable_canonical_uris** disables the default behaviour of redirecting to add a trailing slash if the request path is a directory, or remove the trailing slash if the request path is a file. Note that by default, canonicalization will not happen if the last element of the request's path (the filename) underwent an internal rewrite, to avoid clobbering an explicit rewrite with implicit behaviour.
|
||||||
|
- **pass_thru** enables pass-thru mode, which continues to the next HTTP handler in the route if the requested file is not found, instead of returning a `404`. Practically, this is likely only be useful inside of a [`route`](/docs/caddyfile/directives/route) block, because the `file_server` directive is effectively [ordered last](/docs/caddyfile/directives#directive-order) otherwise.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,10 @@ $(function() {
|
||||||
|
|
||||||
Enables and configures HTTP request logging (also known as access logs).
|
Enables and configures HTTP request logging (also known as access logs).
|
||||||
|
|
||||||
|
<aside class="tip">
|
||||||
|
If you're looking to configure Caddy's runtime logs, you're looking for the <a href="/docs/caddyfile/options#log"><code>log</code> global option</a> instead.
|
||||||
|
</aside>
|
||||||
|
|
||||||
The `log` directive applies to the host/port of the site block it appears in, not any other part of the site address (e.g. path).
|
The `log` directive applies to the host/port of the site block it appears in, not any other part of the site address (e.g. path).
|
||||||
|
|
||||||
- [Syntax](#syntax)
|
- [Syntax](#syntax)
|
||||||
|
@ -25,13 +29,18 @@ The `log` directive applies to the host/port of the site block it appears in, no
|
||||||
- [Format modules](#format-modules)
|
- [Format modules](#format-modules)
|
||||||
- [console](#console)
|
- [console](#console)
|
||||||
- [json](#json)
|
- [json](#json)
|
||||||
- [single_field](#single-field)
|
|
||||||
- [filter](#filter)
|
- [filter](#filter)
|
||||||
- [delete](#delete)
|
- [delete](#delete)
|
||||||
- [replace](#replace)
|
- [replace](#replace)
|
||||||
- [ip_mask](#ip-mask)
|
- [ip_mask](#ip-mask)
|
||||||
|
- [query](#query)
|
||||||
|
- [cookie](#cookie)
|
||||||
|
- [regexp](#regexp)
|
||||||
|
- [hash](#hash)
|
||||||
- [Examples](#examples)
|
- [Examples](#examples)
|
||||||
|
|
||||||
|
Since Caddy v2.5, by default, headers with potentially sensitive information (`Cookie`, `Set-Cookie`, `Authorization` and `Proxy-Authorization`) will be logged with empty values. This behaviour can be disabled with the [`log_credentials`](/docs/caddyfile/options#log-credentials) global server option.
|
||||||
|
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
|
||||||
|
@ -85,6 +94,8 @@ A file. By default, log files are rotated ("rolled") to prevent disk space exhau
|
||||||
output file <filename> {
|
output file <filename> {
|
||||||
roll_disabled
|
roll_disabled
|
||||||
roll_size <size>
|
roll_size <size>
|
||||||
|
roll_uncompressed
|
||||||
|
roll_local_time
|
||||||
roll_keep <num>
|
roll_keep <num>
|
||||||
roll_keep_for <days>
|
roll_keep_for <days>
|
||||||
}
|
}
|
||||||
|
@ -93,6 +104,8 @@ output file <filename> {
|
||||||
- **<filename>** is the path to the log file.
|
- **<filename>** is the path to the log file.
|
||||||
- **roll_disabled** disables log rolling. This can lead to disk space depletion, so only use this if your log files are maintained some other way.
|
- **roll_disabled** disables log rolling. This can lead to disk space depletion, so only use this if your log files are maintained some other way.
|
||||||
- **roll_size** is the size at which to roll the log file. The current implementation supports megabyte resolution; fractional values are rounded up to the next whole megabyte. For example, `1.1MiB` is rounded up to `2MiB`. Default: `100MiB`
|
- **roll_size** is the size at which to roll the log file. The current implementation supports megabyte resolution; fractional values are rounded up to the next whole megabyte. For example, `1.1MiB` is rounded up to `2MiB`. Default: `100MiB`
|
||||||
|
- **roll_uncompressed** turns off gzip log compression. Default: gzip compression is enabled.
|
||||||
|
- **roll_local_time** sets the rolling to use local timestamps in filenames. Default: uses UTC time.
|
||||||
- **roll_keep** is how many log files to keep before deleting the oldest ones. Default: `10`
|
- **roll_keep** is how many log files to keep before deleting the oldest ones. Default: `10`
|
||||||
- **roll_keep_for** is how long to keep rolled files as a [duration string](/docs/conventions#durations). The current implementation supports day resolution; fractional values are rounded up to the next whole day. For example, `36h` (1.5 days) is rounded up to `48h` (2 days). Default: `2160h` (90 days)
|
- **roll_keep_for** is how long to keep rolled files as a [duration string](/docs/conventions#durations). The current implementation supports day resolution; fractional values are rounded up to the next whole day. For example, `36h` (1.5 days) is rounded up to `48h` (2 days). Default: `2160h` (90 days)
|
||||||
|
|
||||||
|
@ -116,6 +129,10 @@ output net <address> {
|
||||||
|
|
||||||
The **format** subdirective lets you customize how logs get encoded (formatted). It appears within a `log` block.
|
The **format** subdirective lets you customize how logs get encoded (formatted). It appears within a `log` block.
|
||||||
|
|
||||||
|
<aside class="tip">
|
||||||
|
<b>A note about Common Log Format (CLF):</b> CLF clashes with modern structured logs. To transform your access logs into the deprecated Common Log Format, please use the <a href="https://github.com/caddyserver/transform-encoder"><code>transform-encoder</code> plugin</a>.
|
||||||
|
</aside>
|
||||||
|
|
||||||
In addition to the syntax for each individual encoder, these common properties can be set on most encoders:
|
In addition to the syntax for each individual encoder, these common properties can be set on most encoders:
|
||||||
|
|
||||||
```caddy-d
|
```caddy-d
|
||||||
|
@ -158,17 +175,6 @@ Formats each log entry as a JSON object.
|
||||||
format json
|
format json
|
||||||
```
|
```
|
||||||
|
|
||||||
#### single_field
|
|
||||||
|
|
||||||
<span class="warning">⚠️ This format is deprecated, and will be removed in a future version.</span>
|
|
||||||
|
|
||||||
Writes only a single field from the structure log entry. Useful if one of the fields has all the information you need.
|
|
||||||
|
|
||||||
```caddy-d
|
|
||||||
format single_field <field_name>
|
|
||||||
```
|
|
||||||
|
|
||||||
- **<field_name>** is the name of the field whose value to use as the log entry.
|
|
||||||
|
|
||||||
#### filter
|
#### filter
|
||||||
|
|
||||||
|
@ -207,8 +213,7 @@ Marks a field to be replaced with the provided string at encoding time.
|
||||||
|
|
||||||
##### ip_mask
|
##### ip_mask
|
||||||
|
|
||||||
Masks IP addresses in the field using a CIDR mask, i.e. the number of bytes from the IP to retain, starting from the left side. There is separate configuration for IPv4 and IPv6 addresses.
|
Masks IP addresses in the field using a CIDR mask, i.e. the number of bytes from the IP to retain, starting from the left side. There is separate configuration for IPv4 and IPv6 addresses. Most commonly, the field to filter would be `request>remote_ip`.
|
||||||
|
|
||||||
|
|
||||||
```caddy-d
|
```caddy-d
|
||||||
<field> ip_mask {
|
<field> ip_mask {
|
||||||
|
@ -217,6 +222,59 @@ Masks IP addresses in the field using a CIDR mask, i.e. the number of bytes from
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### query
|
||||||
|
|
||||||
|
Marks a field to have one or more actions performed, to manipulate the query part of a URL field. Most commonly, the field to filter would be `uri`. The available actions are:
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
<field> query {
|
||||||
|
delete <key>
|
||||||
|
replace <key> <replacement>
|
||||||
|
hash <key>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **delete** removes the given key from the query.
|
||||||
|
- **replace** replaces the value of the given query key with **replacement**. Useful to insert a redaction placeholder; you'll see that the query key was in the URL, but the value is hidden.
|
||||||
|
- **hash** replaces the value of the given query key with the first 4 bytes of the SHA-256 hash of the value, lowercase hexadecimal. Useful to obscure the value if it's sensitive, while being able to notice whether each request had a different value.
|
||||||
|
|
||||||
|
##### cookie
|
||||||
|
|
||||||
|
Marks a field to have one or more actions performed, to manipulate a `Cookie` HTTP header's value. Most commonly, the field to filter would be `request>headers>Cookie`. The available actions are:
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
<field> cookie {
|
||||||
|
delete <name>
|
||||||
|
replace <name> <replacement>
|
||||||
|
hash <name>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **delete** removes the given cookie by name from the header.
|
||||||
|
- **replace** replaces the value of the given cookie with **replacement**. Useful to insert a redaction placeholder; you'll see that the cookie was in the header, but the value is hidden.
|
||||||
|
- **hash** replaces the value of the given cookie with the first 4 bytes of the SHA-256 hash of the value, lowercase hexadecimal. Useful to obscure the value if it's sensitive, while being able to notice whether each request had a different value.
|
||||||
|
|
||||||
|
If many actions are defined for the same cookie name, only the first action will be applied.
|
||||||
|
|
||||||
|
##### regexp
|
||||||
|
|
||||||
|
Marks a field to have a regular expression replacement applied at encoding time.
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
<field> regexp <pattern> <replacement>
|
||||||
|
```
|
||||||
|
|
||||||
|
The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).
|
||||||
|
|
||||||
|
In the replacement string, capture groups can be referenced with `${group}` where `group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
||||||
|
|
||||||
|
##### hash
|
||||||
|
|
||||||
|
Marks a field to be replaced with the first 4 bytes of the SHA-256 hash of the value at encoding time. Useful to obscure the value if it's sensitive, while being able to notice whether each request had a different value.
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
<field> hash
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -250,18 +308,6 @@ log {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Use Common Log Format (CLF):
|
|
||||||
|
|
||||||
<span class="warning">⚠️ The `single_field` format is deprecated and will be removed in a future version. To encode logs in common log format, please use the [`format-encoder`](https://github.com/caddyserver/format-encoder) plugin.</span>
|
|
||||||
|
|
||||||
```caddy-d
|
|
||||||
log {
|
|
||||||
format single_field common_log
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Delete the Authorization request header from the logs:
|
Delete the Authorization request header from the logs:
|
||||||
|
|
||||||
```caddy-d
|
```caddy-d
|
||||||
|
@ -276,15 +322,31 @@ log {
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Mask the remote address from the request, keeping the first 16 bits (i.e. 255.255.0.0) for IPv4 addresses, and the first 32 bits from IPv6 addresses, and also deletes the `common_log` field which would normally contain an unmasked IP address:
|
Redact multiple sensitive cookies:
|
||||||
|
|
||||||
```caddy-d
|
```caddy-d
|
||||||
log {
|
log {
|
||||||
format filter {
|
format filter {
|
||||||
wrap console
|
wrap console
|
||||||
fields {
|
fields {
|
||||||
common_log delete
|
request>headers>Cookie cookie {
|
||||||
request>remote_addr ip_mask {
|
replace session REDACTED
|
||||||
|
delete secret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Mask the remote address from the request, keeping the first 16 bits (i.e. 255.255.0.0) for IPv4 addresses, and the first 32 bits from IPv6 addresses. (Note that prior to Caddy v2.5, the field was named `remote_addr`, but is now `remote_ip`):
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
log {
|
||||||
|
format filter {
|
||||||
|
wrap console
|
||||||
|
fields {
|
||||||
|
request>remote_ip ip_mask {
|
||||||
ipv4 16
|
ipv4 16
|
||||||
ipv6 32
|
ipv6 32
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ map [<matcher>] <source> <destinations...> {
|
||||||
|
|
||||||
The number of outputs for each mapping must not exceed the number of destinations; however, for convenience, there may be fewer outputs than destinations, and any missing outputs will be filled in implicitly.
|
The number of outputs for each mapping must not exceed the number of destinations; however, for convenience, there may be fewer outputs than destinations, and any missing outputs will be filled in implicitly.
|
||||||
|
|
||||||
If a regular expression was used as the input, then the capture groups can be referenced with `${capture_group}` where `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
If a regular expression was used as the input, then the capture groups can be referenced with `${group}` where `group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
||||||
|
|
||||||
- **<default>** specifies the output values to store if no inputs are matched.
|
- **<default>** specifies the output values to store if no inputs are matched.
|
||||||
|
|
||||||
|
|
25
src/docs/markdown/caddyfile/directives/method.md
Normal file
25
src/docs/markdown/caddyfile/directives/method.md
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
title: method (Caddyfile directive)
|
||||||
|
---
|
||||||
|
|
||||||
|
# method
|
||||||
|
|
||||||
|
Changes the HTTP method on the request.
|
||||||
|
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
method [<matcher>] <method>
|
||||||
|
```
|
||||||
|
|
||||||
|
- **<method>** is the HTTP method to change the request to.
|
||||||
|
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Change the method for all requests under `/api` to `POST`:
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
method /api* POST
|
||||||
|
```
|
|
@ -15,7 +15,7 @@ request_body [<matcher>] {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- **max_size** is the maximum size in bytes allowed for the request body. It accepts all formats supported by [go-humanize](https://github.com/dustin/go-humanize/blob/master/bytes.go).
|
- **max_size** is the maximum size in bytes allowed for the request body. It accepts all size values supported by [go-humanize](https://pkg.go.dev/github.com/dustin/go-humanize#pkg-constants). Reads of more bytes will return an error with HTTP status 413.
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
|
@ -30,6 +30,10 @@ Proxies requests to one or more backends with configurable transport, load balan
|
||||||
|
|
||||||
- [Syntax](#syntax)
|
- [Syntax](#syntax)
|
||||||
- [Upstreams](#upstreams)
|
- [Upstreams](#upstreams)
|
||||||
|
- [Upstream addresses](#upstream-addresses)
|
||||||
|
- [Dynamic upstreams](#dynamic-upstreams)
|
||||||
|
- [SRV](#srv)
|
||||||
|
- [A/AAAA](#aaaaa)
|
||||||
- [Load balancing](#load-balancing)
|
- [Load balancing](#load-balancing)
|
||||||
- [Active health checks](#active-health-checks)
|
- [Active health checks](#active-health-checks)
|
||||||
- [Passive health checks](#passive-health-checks)
|
- [Passive health checks](#passive-health-checks)
|
||||||
|
@ -48,8 +52,8 @@ Proxies requests to one or more backends with configurable transport, load balan
|
||||||
```caddy-d
|
```caddy-d
|
||||||
reverse_proxy [<matcher>] [<upstreams...>] {
|
reverse_proxy [<matcher>] [<upstreams...>] {
|
||||||
# backends
|
# backends
|
||||||
to <upstreams...>
|
to <upstreams...>
|
||||||
...
|
dynamic <module> ...
|
||||||
|
|
||||||
# load balancing
|
# load balancing
|
||||||
lb_policy <name> [<options...>]
|
lb_policy <name> [<options...>]
|
||||||
|
@ -81,6 +85,7 @@ reverse_proxy [<matcher>] [<upstreams...>] {
|
||||||
max_buffer_size <size>
|
max_buffer_size <size>
|
||||||
|
|
||||||
# header manipulation
|
# header manipulation
|
||||||
|
trusted_proxies [private_ranges] <ranges...>
|
||||||
header_up [+|-]<field> [<value|regexp> [<replacement>]]
|
header_up [+|-]<field> [<value|regexp> [<replacement>]]
|
||||||
header_down [+|-]<field> [<value|regexp> [<replacement>]]
|
header_down [+|-]<field> [<value|regexp> [<replacement>]]
|
||||||
|
|
||||||
|
@ -94,8 +99,18 @@ reverse_proxy [<matcher>] [<upstreams...>] {
|
||||||
status <code...>
|
status <code...>
|
||||||
header <field> [<value>]
|
header <field> [<value>]
|
||||||
}
|
}
|
||||||
handle_response [<matcher>] [status_code] {
|
replace_status [<matcher>] <status_code>
|
||||||
|
handle_response [<matcher>] {
|
||||||
<directives...>
|
<directives...>
|
||||||
|
|
||||||
|
# special directives only available in handle_response
|
||||||
|
copy_response [<matcher>] [<status>] {
|
||||||
|
status <status>
|
||||||
|
}
|
||||||
|
copy_response_headers [<matcher>] {
|
||||||
|
include <fields...>
|
||||||
|
exclude <fields...>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -106,8 +121,12 @@ reverse_proxy [<matcher>] [<upstreams...>] {
|
||||||
|
|
||||||
- **<upstreams...>** is a list of upstreams (backends) to which to proxy.
|
- **<upstreams...>** is a list of upstreams (backends) to which to proxy.
|
||||||
- **to** <span id="to"/> is an alternate way to specify the list of upstreams, one (or more) per line.
|
- **to** <span id="to"/> is an alternate way to specify the list of upstreams, one (or more) per line.
|
||||||
|
- **dynamic** <span id="dynamic"/> configures a _dynamic upstreams_ module. This allows getting the list of upstreams dynamically for every request. See [dynamic upstreams](#dynamic-upstreams) below for a description of standard dynamic upstream modules. Dynamic upstreams are retrieved at every proxy loop iteration (i.e. potentially multiple times per request if load balancing retries are enabled) and will be preferred over static upstreams. If an error occurs, the proxy will fall back to using any statically-configured upstreams.
|
||||||
|
|
||||||
Upstream addresses can take the form of a conventional [Caddy network address](/docs/conventions#network-addresses) or a URL that contains only scheme and host/port, with a special exception that the scheme may be prefixed by `srv+` to enable SRV DNS record lookups for load balancing. Valid examples:
|
|
||||||
|
#### Upstream addresses
|
||||||
|
|
||||||
|
Static upstream addresses can take the form of a conventional [Caddy network address](/docs/conventions#network-addresses) or a URL that contains only scheme and host/port. Valid examples:
|
||||||
|
|
||||||
- `localhost:4000`
|
- `localhost:4000`
|
||||||
- `127.0.0.1:4000`
|
- `127.0.0.1:4000`
|
||||||
|
@ -116,16 +135,69 @@ Upstream addresses can take the form of a conventional [Caddy network address](/
|
||||||
- `h2c://127.0.0.1`
|
- `h2c://127.0.0.1`
|
||||||
- `example.com`
|
- `example.com`
|
||||||
- `unix//var/php.sock`
|
- `unix//var/php.sock`
|
||||||
- `srv+http://internal.service.consul`
|
|
||||||
- `srv+https://internal.service.consul`
|
|
||||||
|
|
||||||
Note: Schemes cannot be mixed, since they modify the common transport configuration (a TLS-enabled transport cannot carry both HTTPS and plaintext HTTP). Specifying ports 80 and 443 are the same as specifying the HTTP and HTTPS schemes, respectively. Any explicit transport configuration will not be overwritten, and omitting schemes or using other ports will not assume a particular transport.
|
Note: Schemes cannot be mixed, since they modify the common transport configuration (a TLS-enabled transport cannot carry both HTTPS and plaintext HTTP). Any explicit transport configuration will not be overwritten, and omitting schemes or using other ports will not assume a particular transport.
|
||||||
|
|
||||||
Additionally, upstream addresses cannot contain paths or query strings, as that would imply simultaneous rewriting the request while proxying, which behavior is not defined or supported. You may use the [`rewrite`](/docs/caddyfile/directives/rewrite) directive should you need this.
|
Additionally, upstream addresses cannot contain paths or query strings, as that would imply simultaneous rewriting the request while proxying, which behavior is not defined or supported. You may use the [`rewrite`](/docs/caddyfile/directives/rewrite) directive should you need this.
|
||||||
|
|
||||||
If the address is not a URL (i.e. does not have a scheme), then placeholders can be used, but this makes the upstream dynamic, meaning that the potentially many different backends act as one upstream in terms of health checks and load balancing.
|
If the address is not a URL (i.e. does not have a scheme), then placeholders can be used, but this makes the upstream _dynamically static_, meaning that potentially many different backends act as a single, static upstream in terms of health checks and load balancing.
|
||||||
|
|
||||||
When proxying over HTTPS, you may need to override the `Host` header (which by default, retains the value from the original request) such that the `Host` header matches the TLS SNI value, which is used by servers for routing and certificate selection. See the [Headers](#headers) section below for more details.
|
When proxying over HTTPS, you may need to override the `Host` header such that it matches the TLS SNI value, which is used by servers for routing and certificate selection. See the [Headers](#headers) section below for more details.
|
||||||
|
|
||||||
|
|
||||||
|
#### Dynamic upstreams
|
||||||
|
|
||||||
|
Caddy's reverse proxy comes standard with some dynamic upstream modules. Note that using dynamic upstreams has implications for load balancing and health checks, depending on specific policy configuration: active health checks do not run for dynamic upstreams; and load balancing and passive health checks are best served if the list of upstreams is relatively stable and consistent (especially with round-robin). Ideally, dynamic upstream modules only return healthy, usable backends.
|
||||||
|
|
||||||
|
|
||||||
|
##### SRV
|
||||||
|
|
||||||
|
Retrieves upstreams from SRV DNS records.
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
dynamic srv [<name>] {
|
||||||
|
service <service>
|
||||||
|
proto <proto>
|
||||||
|
name <name>
|
||||||
|
refresh <interval>
|
||||||
|
resolvers <ip...>
|
||||||
|
dial_timeout <duration>
|
||||||
|
dial_fallback_delay <duration>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **<name>** - The full domain name of the record to look up (i.e. `_service._proto.name`).
|
||||||
|
- **service** - The service component of the full name.
|
||||||
|
- **proto** - The protocol component of the full name. Either `tcp` or `udp`.
|
||||||
|
- **name** - The name component. Or, if `service` and `proto` are empty, the full domain name to query.
|
||||||
|
- **refresh** - How often to refresh cached results. Default: `1m`
|
||||||
|
- **resolvers** - List of DNS resolvers to override system resolvers.
|
||||||
|
- **dial_timeout** - Timeout for dialing the query.
|
||||||
|
- **dial_fallback_delay** - Timeout for falling back from IPv6 to IPv4 via RFC 6555. Default: `300ms`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### A/AAAA
|
||||||
|
|
||||||
|
Retrieves upstreams from A/AAAA DNS records.
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
dynamic a [<name> <port>] {
|
||||||
|
name <name>
|
||||||
|
port <port>
|
||||||
|
refresh <interval>
|
||||||
|
resolvers <ip...>
|
||||||
|
dial_timeout <duration>
|
||||||
|
dial_fallback_delay <duration>
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **<name>, name** - The domain name to query.
|
||||||
|
- **<port>, port** - The port to use for the backend.
|
||||||
|
- **refresh** - How often to refresh cached results. Default: `1m`
|
||||||
|
- **resolvers** - List of DNS resolvers to override system resolvers.
|
||||||
|
- **dial_timeout** - Timeout for dialing the query.
|
||||||
|
- **dial_fallback_delay** - Timeout for falling back from IPv6 to IPv4 via RFC 6555. Default: `300ms`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,24 +265,25 @@ The proxy can **manipulate headers** between itself and the backend:
|
||||||
- **header_up** <span id="header_up"/> Sets, adds, removes, or performs a replacement in a request header going upstream to the backend.
|
- **header_up** <span id="header_up"/> Sets, adds, removes, or performs a replacement in a request header going upstream to the backend.
|
||||||
- **header_down** <span id="header_down"/> Sets, adds, removes, or performs a replacement in a response header coming downstream from the backend.
|
- **header_down** <span id="header_down"/> Sets, adds, removes, or performs a replacement in a response header coming downstream from the backend.
|
||||||
|
|
||||||
|
|
||||||
#### Defaults
|
#### Defaults
|
||||||
|
|
||||||
By default, Caddy passes thru incoming headers to the backend—including the `Host` header—without modifications, with two exceptions:
|
By default, Caddy passes thru incoming headers—including `Host`—to the backend without modifications, with three exceptions:
|
||||||
|
|
||||||
- It adds or augments the [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) header field.
|
- It adds or augments the [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) header field.
|
||||||
- It sets the [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) header field.
|
- It sets the [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) header field.
|
||||||
|
- It sets the [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host) header field.
|
||||||
|
|
||||||
|
For these `X-Forwarded-*` headers, by default, Caddy will ignore their values from incoming requests, to prevent spoofing. If Caddy is not the first server being connected to by your clients (for example when a CDN is in front of Caddy), you may configure `trusted_proxies` <span id="trusted_proxies"/> with a list of IP ranges (CIDRs) from which incoming requests are trusted to have sent good values for these headers. As a shortcut, `trusted_proxies private_ranges` may be configured to trust all private IP ranges.
|
||||||
|
|
||||||
Additionally, when using the [`http` transport](#the-http-transport), the `Accept-Encoding: gzip` header will be set, if it is missing in the request from the client. This behavior can be disabled with [`compression off`](#compression) on the transport.
|
Additionally, when using the [`http` transport](#the-http-transport), the `Accept-Encoding: gzip` header will be set, if it is missing in the request from the client. This behavior can be disabled with [`compression off`](#compression) on the transport.
|
||||||
|
|
||||||
#### HTTPS
|
#### HTTPS
|
||||||
|
|
||||||
For HTTPS upstreams, since the `Host` header retains its original value, it is typically necessary to override the header with the configured upstream address, such that the `Host` header matches the TLS SNI value. A `X-Forwarded-Host` header may also be added to inform the upstream of the original `Host` header's value. For example:
|
Since (most) headers retain their original value when being proxied, it is often necessary to override the `Host` header with the configured upstream address when proxying to HTTPS, such that the `Host` header matches the TLS ServerName value. For example:
|
||||||
|
|
||||||
```caddy-d
|
```caddy-d
|
||||||
reverse_proxy https://example.com {
|
reverse_proxy https://example.com {
|
||||||
header_up Host {upstream_hostport}
|
header_up Host {upstream_hostport}
|
||||||
header_up X-Forwarded-Host {host}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -297,19 +370,28 @@ transport fastcgi {
|
||||||
- **write_timeout** <span id="write_timeout"/> is how long to wait when sending to the FastCGI server. Accepts [duration values](/docs/conventions#durations). Default: no timeout.
|
- **write_timeout** <span id="write_timeout"/> is how long to wait when sending to the FastCGI server. Accepts [duration values](/docs/conventions#durations). Default: no timeout.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Intercepting responses
|
### Intercepting responses
|
||||||
|
|
||||||
The reverse proxy can be configured to intercept responses from the backend. To facilitate this, response matchers can be defined (similar to the syntax for request matchers) and the first matching `handle_response` route will be invoked. When this happens, the response from the backend is not written to the client, and the configured `handle_response` route will be executed instead, and it is up to that route to write a response.
|
The reverse proxy can be configured to intercept responses from the backend. To facilitate this, response matchers can be defined (similar to the syntax for request matchers) and the first matching `handle_response` route will be invoked. When this happens, the response from the backend is not written to the client, and the configured `handle_response` route will be executed instead, and it is up to that route to write a response.
|
||||||
|
|
||||||
- **@name** is the name of a [response matcher](#response-matcher). As long as each response matcher has a unique name, multiple matchers can be defined. A response can be matched on the status code and presence or value of a response header.
|
- **@name** is the name of a [response matcher](#response-matcher). As long as each response matcher has a unique name, multiple matchers can be defined. A response can be matched on the status code and presence or value of a response header.
|
||||||
|
- **replace_status** <span id="replace_status"/> simply changes the status code of response when matched by the given matcher.
|
||||||
- **handle_response** <span id="handle_response"/> defines the route to execute when matched by the given matcher (or, if a matcher is omitted, all responses). The first matching block will be applied. Inside a `handle_response` block, any other [directives](/docs/caddyfile/directives) can be used.
|
- **handle_response** <span id="handle_response"/> defines the route to execute when matched by the given matcher (or, if a matcher is omitted, all responses). The first matching block will be applied. Inside a `handle_response` block, any other [directives](/docs/caddyfile/directives) can be used.
|
||||||
|
|
||||||
Three placeholders will be made available to the `handle_response` routes:
|
Additionally, inside `handle_response`, two special handler directives may be used:
|
||||||
|
|
||||||
|
- **copy_response** <span id="copy_response"/> copies the response from the backend back to the client. Optionally allows changing the status code of the response while doing so. This directive is [ordered before `respond`](/docs/caddyfile/directives#directive-order).
|
||||||
|
- **copy_response_headers** <span id="copy_response_headers"/> copies the response headers from the backend to the client, optionally including _OR_ excluding a list of headers fields (cannot specify both `include` and `exclude`). This directive is [ordered after `header`](/docs/caddyfile/directives#directive-order).
|
||||||
|
|
||||||
|
Three placeholders will be made available within the `handle_response` routes:
|
||||||
|
|
||||||
- `{http.reverse_proxy.status_code}` The status code from the backend's response.
|
- `{http.reverse_proxy.status_code}` The status code from the backend's response.
|
||||||
- `{http.reverse_proxy.status_text}` The status text from the backend's response.
|
- `{http.reverse_proxy.status_text}` The status text from the backend's response.
|
||||||
- `{http.reverse_proxy.header.*}` The headers from the backend's response.
|
- `{http.reverse_proxy.header.*}` The headers from the backend's response.
|
||||||
|
|
||||||
|
|
||||||
#### Response matcher
|
#### Response matcher
|
||||||
|
|
||||||
**Response matchers** can be used to filter (or classify) responses by specific criteria.
|
**Response matchers** can be used to filter (or classify) responses by specific criteria.
|
||||||
|
@ -326,7 +408,11 @@ By HTTP status code.
|
||||||
|
|
||||||
##### header
|
##### header
|
||||||
|
|
||||||
See the [header](/docs/caddyfile/matchers#header) request matcher for the supported syntax.
|
See the [`header`](/docs/caddyfile/matchers#header) request matcher for the supported syntax.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
@ -401,7 +487,7 @@ reverse_proxy localhost:8080 {
|
||||||
@accel header X-Accel-Redirect *
|
@accel header X-Accel-Redirect *
|
||||||
handle_response @accel {
|
handle_response @accel {
|
||||||
root * /path/to/private/files
|
root * /path/to/private/files
|
||||||
rewrite {http.reverse_proxy.header.X-Accel-Redirect}
|
rewrite * {http.reverse_proxy.header.X-Accel-Redirect}
|
||||||
file_server
|
file_server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,3 +506,19 @@ reverse_proxy localhost:8080 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Get backends dynamically from A/AAAA record DNS queries:
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
reverse_proxy {
|
||||||
|
dynamic a example.com 9000
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Get backends dynamically from SRV record DNS queries:
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
reverse_proxy {
|
||||||
|
dynamic srv _api._tcp.example.com
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -31,6 +31,7 @@ tls [internal|<email>] | [<cert_file> <key_file>] {
|
||||||
ca_root <pem_file>
|
ca_root <pem_file>
|
||||||
key_type ed25519|p256|p384|rsa2048|rsa4096
|
key_type ed25519|p256|p384|rsa2048|rsa4096
|
||||||
dns <provider_name> [<params...>]
|
dns <provider_name> [<params...>]
|
||||||
|
dns_challenge_domain_override <domain>
|
||||||
resolvers <dns_servers...>
|
resolvers <dns_servers...>
|
||||||
eab <key_id> <mac_key>
|
eab <key_id> <mac_key>
|
||||||
on_demand
|
on_demand
|
||||||
|
@ -79,7 +80,8 @@ tls [internal|<email>] | [<cert_file> <key_file>] {
|
||||||
- **ca** <span id="ca"/> changes the ACME CA endpoint. This is most often used to set [Let's Encrypt's staging endpoint](https://letsencrypt.org/docs/staging-environment/) when testing, or an internal ACME server. (To change this value for the whole Caddyfile, use the `acme_ca` [global option](/docs/caddyfile/options) instead.)
|
- **ca** <span id="ca"/> changes the ACME CA endpoint. This is most often used to set [Let's Encrypt's staging endpoint](https://letsencrypt.org/docs/staging-environment/) when testing, or an internal ACME server. (To change this value for the whole Caddyfile, use the `acme_ca` [global option](/docs/caddyfile/options) instead.)
|
||||||
- **ca_root** <span id="ca_root"/> specifies a PEM file that contains a trusted root certificate for the ACME CA endpoint, if not in the system trust store.
|
- **ca_root** <span id="ca_root"/> specifies a PEM file that contains a trusted root certificate for the ACME CA endpoint, if not in the system trust store.
|
||||||
- **key_type** <span id="key_type"/> is the type of key to use when generating CSRs. Only set this if you have a specific requirement.
|
- **key_type** <span id="key_type"/> is the type of key to use when generating CSRs. Only set this if you have a specific requirement.
|
||||||
- **dns** <span id="dns"/> enables the [DNS challenge](/docs/automatic-https#dns-challenge) using the specified provider plugin, which must be plugged in from one of the [caddy-dns](https://github.com/caddy-dns) repositories. Each provider plugin may have their own syntax following their name; refer to their docs for details. Maintaining support for each DNS provider is a community effort. [Learn how to enable the DNS challenge for your provider at our wiki.](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148)
|
- **dns** <span id="dns"/> enables the [DNS challenge](/docs/automatic-https#dns-challenge) using the specified provider plugin, which must be plugged in from one of the [`caddy-dns`](https://github.com/caddy-dns) repositories. Each provider plugin may have their own syntax following their name; refer to their docs for details. Maintaining support for each DNS provider is a community effort. [Learn how to enable the DNS challenge for your provider at our wiki.](https://caddy.community/t/how-to-use-dns-provider-modules-in-caddy-2/8148)
|
||||||
|
- **dns_challenge_domain_override** <span id="dns_challenge_domain_override"/> overrides the domain to use for the DNS challenge. This is to delegate the challenge to a different domain, e.g. one whose DNS provider has a [`caddy-dns`](https://github.com/caddy-dns) plugin.
|
||||||
- **resolvers** <span id="resolvers"/> customizes the DNS resolvers used when performing the DNS challenge; these take precedence over system resolvers or any default ones. If set here, the resolvers will propagate to all configured certificate issuers.
|
- **resolvers** <span id="resolvers"/> customizes the DNS resolvers used when performing the DNS challenge; these take precedence over system resolvers or any default ones. If set here, the resolvers will propagate to all configured certificate issuers.
|
||||||
- **eab** <span id="eab"/> configures ACME external account binding (EAB) for this site, using the key ID and MAC key provided by your CA.
|
- **eab** <span id="eab"/> configures ACME external account binding (EAB) for this site, using the key ID and MAC key provided by your CA.
|
||||||
- **on_demand** <span id="on_demand"/> enables [on-demand TLS](/docs/automatic-https#on-demand-tls) for the hostnames given in the site block's address(es). **Security warning:** Doing so in production is insecure unless you also configure the [`on_demand_tls` global option](https://caddyserver.com/docs/caddyfile/options#on-demand-tls) to mitigate abuse.
|
- **on_demand** <span id="on_demand"/> enables [on-demand TLS](/docs/automatic-https#on-demand-tls) for the hostnames given in the site block's address(es). **Security warning:** Doing so in production is insecure unless you also configure the [`on_demand_tls` global option](https://caddyserver.com/docs/caddyfile/options#on-demand-tls) to mitigate abuse.
|
||||||
|
@ -177,12 +179,15 @@ Obtains certificates from an internal certificate authority.
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
... internal {
|
... internal {
|
||||||
ca <name>
|
ca <name>
|
||||||
|
lifetime <duration>
|
||||||
|
sign_with_root
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- **ca** is the name of the internal CA to use. Default: `local`
|
- **ca** <span id="ca"/> is the name of the internal CA to use. Default: `local`. See the [PKI app global options](/docs/caddyfile/options#pki-options) to configure alternate CAs.
|
||||||
|
- **lifetime** <span id="lifetime"/> is a [duration value](/docs/conventions#durations) that sets the validity period for interally issued leaf certificates. Default: 12h. It is NOT recommended to not change this, unless absolutely necessary.
|
||||||
|
- **sign_with_root** <span id="sign_with_root"/> forces the root to be the issuer instead of the intermediate. This is NOT recommended and should only be used when devices/clients do not properly validate certificate chains (very uncommon).
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
@ -207,6 +212,16 @@ tls internal {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Use custom options for the internal CA (cannot use the `tls internal` shortcut):
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
tls {
|
||||||
|
issuer internal {
|
||||||
|
ca foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Specify an email address for your ACME account (but if only one email is used for all sites, we recommend the `email` [global option](/docs/caddyfile/options) instead):
|
Specify an email address for your ACME account (but if only one email is used for all sites, we recommend the `email` [global option](/docs/caddyfile/options) instead):
|
||||||
|
|
||||||
```caddy-d
|
```caddy-d
|
||||||
|
|
|
@ -51,6 +51,8 @@ $(function() {
|
||||||
- [protocol](#protocol)
|
- [protocol](#protocol)
|
||||||
- [query](#query)
|
- [query](#query)
|
||||||
- [remote_ip](#remote-ip)
|
- [remote_ip](#remote-ip)
|
||||||
|
- [vars](#vars)
|
||||||
|
- [vars_regexp](#vars-regexp)
|
||||||
|
|
||||||
|
|
||||||
## Syntax
|
## Syntax
|
||||||
|
@ -317,7 +319,7 @@ Match requests that do not have the `Foo` header field at all:
|
||||||
header_regexp [<name>] <field> <regexp>
|
header_regexp [<name>] <field> <regexp>
|
||||||
```
|
```
|
||||||
|
|
||||||
Like `header`, but supports regular expressions. Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
Like [`header`](#header), but supports regular expressions. Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
||||||
|
|
||||||
The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).
|
The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).
|
||||||
|
|
||||||
|
@ -457,7 +459,7 @@ Multiple `path` matchers will be OR'ed together.
|
||||||
path_regexp [<name>] <regexp>
|
path_regexp [<name>] <regexp>
|
||||||
```
|
```
|
||||||
|
|
||||||
Like `path`, but supports regular expressions. Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
Like [`path`](#path), but supports regular expressions. Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
||||||
|
|
||||||
The request path is URL-decoded, and cleaned (to collapse doubled-up slashes and directory traversal dots) before matching. For example `/foo*` will also match `//foo` and `/%2F/foo`.
|
The request path is URL-decoded, and cleaned (to collapse doubled-up slashes and directory traversal dots) before matching. For example `/foo*` will also match `//foo` and `/%2F/foo`.
|
||||||
|
|
||||||
|
@ -516,7 +518,7 @@ query sort=asc
|
||||||
remote_ip [forwarded] <ranges...>
|
remote_ip [forwarded] <ranges...>
|
||||||
```
|
```
|
||||||
|
|
||||||
By remote (client) IP address. Accepts exact IPs or CIDR ranges. If the first argument is `forwarded`, then the first IP in the `X-Forwarded-For` request header, if present, will be preferred as the reference IP, rather than the immediate peer's IP, which is the default.
|
By remote (client) IP address. Accepts exact IPs or CIDR ranges. If the first argument is `forwarded`, then the first IP in the `X-Forwarded-For` request header, if present, will be preferred as the reference IP, rather than the immediate peer's IP, which is the default. IPv6 zones are supported.
|
||||||
|
|
||||||
Multiple `remote_ip` matchers will be OR'ed together.
|
Multiple `remote_ip` matchers will be OR'ed together.
|
||||||
|
|
||||||
|
@ -527,3 +529,47 @@ Match requests from private IPv4 addresses.
|
||||||
```caddy-d
|
```caddy-d
|
||||||
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
|
remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
### vars
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
vars <variable> <values...>
|
||||||
|
```
|
||||||
|
|
||||||
|
By the value of a variable in the request context, or the value of a placeholder. Multiple values may be specified to match any of those possible values (OR'ed).
|
||||||
|
|
||||||
|
This matcher is most useful when paired with the [`map` directive](/docs/caddyfile/directives/map) which sets outputs, or with plugins which set some information in the request context.
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
Match an output of the [`map` directive](/docs/caddyfile/directives/map) named `magic_number` for the values `3`, or `5`.
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
vars {magic_number} 3 5
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
### vars_regexp
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
vars_regexp [<name>] <variable> <regexp>
|
||||||
|
```
|
||||||
|
|
||||||
|
Like [`vars`](#vars), but supports regular expressions. Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on.
|
||||||
|
|
||||||
|
The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).
|
||||||
|
|
||||||
|
There can only be one `vars_regexp` matcher per named matcher.
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
Match an output of the [`map` directive](/docs/caddyfile/directives/map) named `magic_number` for a value starting with `4`, capturing the value in a capture group.
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
vars_regexp magic {magic_number} ^(4.*)
|
||||||
|
```
|
||||||
|
|
|
@ -42,13 +42,15 @@ Possible options are:
|
||||||
{
|
{
|
||||||
# General Options
|
# General Options
|
||||||
debug
|
debug
|
||||||
http_port <port>
|
http_port <port>
|
||||||
https_port <port>
|
https_port <port>
|
||||||
|
default_bind <host>
|
||||||
order <dir1> first|last|[before|after <dir2>]
|
order <dir1> first|last|[before|after <dir2>]
|
||||||
storage <module_name> {
|
storage <module_name> {
|
||||||
<options...>
|
<options...>
|
||||||
}
|
}
|
||||||
storage_clean_interval <duration>
|
storage_clean_interval <duration>
|
||||||
|
renew_interval <duration>
|
||||||
admin off|<addr> {
|
admin off|<addr> {
|
||||||
origins <origins...>
|
origins <origins...>
|
||||||
enforce_origin
|
enforce_origin
|
||||||
|
@ -63,7 +65,7 @@ Possible options are:
|
||||||
grace_period <duration>
|
grace_period <duration>
|
||||||
|
|
||||||
# TLS Options
|
# TLS Options
|
||||||
auto_https off|disable_redirects|ignore_loaded_certs
|
auto_https off|disable_redirects|ignore_loaded_certs|disable_certs
|
||||||
email <yours>
|
email <yours>
|
||||||
default_sni <name>
|
default_sni <name>
|
||||||
local_certs
|
local_certs
|
||||||
|
@ -97,10 +99,30 @@ Possible options are:
|
||||||
idle <duration>
|
idle <duration>
|
||||||
}
|
}
|
||||||
max_header_size <size>
|
max_header_size <size>
|
||||||
|
log_credentials
|
||||||
protocol {
|
protocol {
|
||||||
allow_h2c
|
allow_h2c
|
||||||
experimental_http3
|
experimental_http3
|
||||||
strict_sni_host
|
strict_sni_host [on|insecure_off]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# PKI Options
|
||||||
|
pki {
|
||||||
|
ca [<id>] {
|
||||||
|
name <name>
|
||||||
|
root_cn <name>
|
||||||
|
intermediate_cn <name>
|
||||||
|
root {
|
||||||
|
format <format>
|
||||||
|
cert <path>
|
||||||
|
key <path>
|
||||||
|
}
|
||||||
|
intermediate {
|
||||||
|
format <format>
|
||||||
|
cert <path>
|
||||||
|
key <path>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +132,13 @@ Possible options are:
|
||||||
## General Options
|
## General Options
|
||||||
|
|
||||||
##### `debug`
|
##### `debug`
|
||||||
Enables debug mode, which sets the log level to `DEBUG` for the default logger. This reveals more details that can be useful when troubleshooting (and is very verbose in production). We ask that you enable this before asking for help on the [community forums](https://caddy.community).
|
Enables debug mode, which sets the log level to `DEBUG` for the [default logger](#log). This reveals more details that can be useful when troubleshooting (and is very verbose in production). We ask that you enable this before asking for help on the [community forums](https://caddy.community). For example, at the top of your Caddyfile, if you have no other global options:
|
||||||
|
|
||||||
|
```caddy
|
||||||
|
{
|
||||||
|
debug
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
##### `http_port`
|
##### `http_port`
|
||||||
|
@ -121,6 +149,10 @@ The port for the server to use for HTTP. For internal use only; does not change
|
||||||
The port for the server to use for HTTPS. For internal use only; does not change the HTTPS port for clients. Default: `443`
|
The port for the server to use for HTTPS. For internal use only; does not change the HTTPS port for clients. Default: `443`
|
||||||
|
|
||||||
|
|
||||||
|
##### `default_bind`
|
||||||
|
The default bind address to be used for all sites, if the [`bind` directive](/docs/caddyfile/directives/bind) is not used in the site. Default: empty, which binds to all interfaces.
|
||||||
|
|
||||||
|
|
||||||
##### `order`
|
##### `order`
|
||||||
Assigns an order to HTTP handler directive(s). As HTTP handlers execute in a sequential chain, it is necessary for the handlers to be executed in the right order. Standard directives have [a pre-defined order](/docs/caddyfile/directives#directive-order), but if using third-party HTTP handler modules, you'll need to define the order explicitly by either using this option or placing the directive in a [`route` block](/docs/caddyfile/directives/route). Ordering can be described absolutely (`first` or `last`), or relatively (`before` or `after`) to another directive.
|
Assigns an order to HTTP handler directive(s). As HTTP handlers execute in a sequential chain, it is necessary for the handlers to be executed in the right order. Standard directives have [a pre-defined order](/docs/caddyfile/directives#directive-order), but if using third-party HTTP handler modules, you'll need to define the order explicitly by either using this option or placing the directive in a [`route` block](/docs/caddyfile/directives/route). Ordering can be described absolutely (`first` or `last`), or relatively (`before` or `after`) to another directive.
|
||||||
|
|
||||||
|
@ -144,11 +176,15 @@ Customizing the storage module is typically needed when syncing Caddy's storage
|
||||||
|
|
||||||
|
|
||||||
##### `storage_clean_interval`
|
##### `storage_clean_interval`
|
||||||
How often to scan storage units for old or expired assets and remove them. These scans exert lots of reads (and list operations) on the storage module, so choose a longer interval for large deployments. The value is a [duration value](/docs/conventions#durations). Default: 24h.
|
How often to scan storage units for old or expired assets and remove them. These scans exert lots of reads (and list operations) on the storage module, so choose a longer interval for large deployments. The value is a [duration value](/docs/conventions#durations). Default: `24h`.
|
||||||
|
|
||||||
Storage will always be cleaned when the process first starts. Then, a new cleaning will be started this duration after the previous cleaning started if the previous cleaning finished in less than half the time of this interval (otherwise next start will be skipped).
|
Storage will always be cleaned when the process first starts. Then, a new cleaning will be started this duration after the previous cleaning started if the previous cleaning finished in less than half the time of this interval (otherwise next start will be skipped).
|
||||||
|
|
||||||
|
|
||||||
|
##### `renew_interval`
|
||||||
|
How often to scan all loaded, managed certificates for expiration, and trigger renewal if expired. Default: `10m`.
|
||||||
|
|
||||||
|
|
||||||
##### `admin`
|
##### `admin`
|
||||||
Customizes the [admin API endpoint](/docs/api). If `off`, then the admin endpoint will be disabled. If disabled, config changes will be impossible without stopping and starting the server.
|
Customizes the [admin API endpoint](/docs/api). If `off`, then the admin endpoint will be disabled. If disabled, config changes will be impossible without stopping and starting the server.
|
||||||
|
|
||||||
|
@ -158,13 +194,15 @@ Customizes the [admin API endpoint](/docs/api). If `off`, then the admin endpoin
|
||||||
|
|
||||||
|
|
||||||
##### `log`
|
##### `log`
|
||||||
Customizes the named logger. The name can be passed to indicate a specific logger to customize the behavior for. If no name is specified, the behavior of the default logger is modified. This option can be specified multiple times to configure different loggers. You can read more about the default logger and other logging behaviors in the [logging documentation](/docs/logging).
|
Configures named loggers. The name can be passed to indicate a specific logger for which to customize the behavior. If no name is specified, the behavior of the `default` logger is modified. Multiple loggers with different names can be configured by using the `log` multiple times. You can read more about the `default` logger and an explanation of [how logging works in Caddy](/docs/logging).
|
||||||
|
|
||||||
- **output** configures where to write the logs. See the [log directive](/docs/caddyfile/directives/log#output-modules) documentation for more information, which has the same structure.
|
The differs from the [`log` directive](/docs/caddyfile/directives/log), which only configures HTTP request logging (also known as access logs). The `log` global option shares its configuration structure with the directive (except for `include` and `exclude`), and complete documentation can be found on the directive's page.
|
||||||
- **format** describes how to encode, or format, the logs. See the [log directive](/docs/caddyfile/directives/log#format-modules) documentation for more information, which has the same structure.
|
|
||||||
- **level** is the minimum entry level to log. Default: `INFO`
|
- **output** configures where to write the logs. See the [`log` directive](/docs/caddyfile/directives/log#output-modules) for complete documentation.
|
||||||
- **include** identifies the loggers that are included in this log configuration. See the [JSON documentation](/docs/json/logging/logs/include/) for more information.
|
- **format** describes how to encode, or format, the logs. See the [`log` directive](/docs/caddyfile/directives/log#format-modules) for complete documentation.
|
||||||
- **exclude** identifies the loggers that are excluded from this log configuration. See the [JSON documentation](/docs/json/logging/logs/exclude/) for more information.
|
- **level** is the minimum entry level to log. Default: `INFO`.
|
||||||
|
- **include** specifies the log names to be included in this logger. For example, to include only logs emitted by the admin API, you would include `admin.api`.
|
||||||
|
- **exclude** specifies the log names to be excluded from this logger. For example, to exclude only HTTP access logs, you would exclude `http.log.access`.
|
||||||
|
|
||||||
|
|
||||||
##### `grace_period`
|
##### `grace_period`
|
||||||
|
@ -175,7 +213,14 @@ Defines the grace period for shutting down HTTP servers during config reloads. I
|
||||||
## TLS Options
|
## TLS Options
|
||||||
|
|
||||||
##### `auto_https`
|
##### `auto_https`
|
||||||
Configure automatic HTTPS. It can be disabled entirely (`off`), disable only HTTP-to-HTTPS redirects (`disable_redirects`), or be configured to automate certificates even for names which appear on manually-loaded certificates (`ignore_loaded_certs`). See the [Automatic HTTPS](/docs/automatic-https) page for more details.
|
Configure automatic HTTPS. There are a few modes to choose from:
|
||||||
|
|
||||||
|
- `off`: Disabled entirely. No certificate management or redirects.
|
||||||
|
- `disable_redirects`: Disable only HTTP-to-HTTPS redirects.
|
||||||
|
- `disable_certs`: Disable only certificate automation.
|
||||||
|
- `ignore_loaded_certs`: Automate certificates even for names which appear on manually-loaded certificates
|
||||||
|
|
||||||
|
See the [Automatic HTTPS](/docs/automatic-https) page for more details.
|
||||||
|
|
||||||
|
|
||||||
##### `email`
|
##### `email`
|
||||||
|
@ -275,7 +320,16 @@ Allows configuring [listener wrappers](/docs/json/apps/http/servers/listener_wra
|
||||||
|
|
||||||
There is a special no-op [`tls`](/docs/json/apps/http/servers/listener_wrappers/tls/) listener wrapper provided as a standard module which marks where TLS should be handled in the chain of listener wrappers. It should only be used if another listener wrapper must be placed in front of the TLS handshake.
|
There is a special no-op [`tls`](/docs/json/apps/http/servers/listener_wrappers/tls/) listener wrapper provided as a standard module which marks where TLS should be handled in the chain of listener wrappers. It should only be used if another listener wrapper must be placed in front of the TLS handshake.
|
||||||
|
|
||||||
For example, assuming you have the [`proxy_protocol`](/docs/json/apps/http/servers/listener_wrappers/proxy_protocol/) plugin installed:
|
The standard distribution of Caddy includes an [`http_redirect`](/docs/json/apps/http/servers/listener_wrappers/http_redirect/) listener wrapper, which can look at the first few bytes of an incoming request to determine if it's HTTP (instead of TLS), and trigger an HTTP->HTTPS redirect on the same port with the `https://` scheme. It must be placed _before_ the `tls` listener wrapper. For example:
|
||||||
|
|
||||||
|
```caddy-d
|
||||||
|
listener_wrappers {
|
||||||
|
http_redirect
|
||||||
|
tls
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Another example, assuming you have the [`proxy_protocol`](/docs/json/apps/http/servers/listener_wrappers/proxy_protocol/) plugin installed, which must be used _before_ the `tls` listener wrapper:
|
||||||
|
|
||||||
```caddy-d
|
```caddy-d
|
||||||
listener_wrappers {
|
listener_wrappers {
|
||||||
|
@ -304,10 +358,50 @@ listener_wrappers {
|
||||||
The maximum size to parse from a client's HTTP request headers. It accepts all formats supported by [go-humanize](https://github.com/dustin/go-humanize/blob/master/bytes.go).
|
The maximum size to parse from a client's HTTP request headers. It accepts all formats supported by [go-humanize](https://github.com/dustin/go-humanize/blob/master/bytes.go).
|
||||||
|
|
||||||
|
|
||||||
|
##### `log_credentials`
|
||||||
|
|
||||||
|
Since Caddy v2.5, by default, headers with potentially sensitive information (`Cookie`, `Set-Cookie`, `Authorization` and `Proxy-Authorization`) will be logged with empty values in access logs (see the [`log` directive](/docs/caddyfile/directives/log)).
|
||||||
|
|
||||||
|
If you wish to _not_ have these headers redacted, you may enable the `log_credentials` option.
|
||||||
|
|
||||||
|
|
||||||
##### `protocol`
|
##### `protocol`
|
||||||
|
|
||||||
- **allow_h2c** enables H2C ("Cleartext HTTP/2" or "H2 over TCP") support, which will serve HTTP/2 over plaintext TCP connections if a client support it. Because this is not implemented by the Go standard library, using H2C is incompatible with most of the other options for this server. Do not enable this only to achieve maximum client compatibility. In practice, very few clients implement H2C, and even fewer require it. This setting applies only to unencrypted HTTP listeners. ⚠️ Experimental feature; subject to change or removal.
|
- **allow_h2c** enables H2C ("Cleartext HTTP/2" or "H2 over TCP") support, which will serve HTTP/2 over plaintext TCP connections if a client support it. Because this is not implemented by the Go standard library, using H2C is incompatible with most of the other options for this server. Do not enable this only to achieve maximum client compatibility. In practice, very few clients implement H2C, and even fewer require it. This setting applies only to unencrypted HTTP listeners. ⚠️ Experimental feature; subject to change or removal.
|
||||||
|
|
||||||
- **experimental_http3** enables experimental draft HTTP/3 support. Note that HTTP/3 is not a finished spec and client support is extremely limited. This option will go away in the future. _This option is not subject to compatibility promises._
|
- **experimental_http3** enables experimental draft HTTP/3 support. Note that HTTP/3 is not a finished spec and client support is extremely limited. This option will go away in the future. _This option is not subject to compatibility promises._
|
||||||
|
|
||||||
- **strict_sni_host** require that a request's `Host` header matches the value of the ServerName sent by the client's TLS ClientHello; often a necessary safeguard when using TLS client authentication.
|
- **strict_sni_host** require that a request's `Host` header matches the value of the ServerName sent by the client's TLS ClientHello; often a necessary safeguard when using TLS client authentication. If there's a mismatch, an HTTP status `421 Misdirected Request` response is written to the client.
|
||||||
|
|
||||||
|
This option will be implicitly turned on if [client authentication](/docs/caddyfile/directives/tls#client_auth) is configured. This disallow TLS client auth bypass (domain fronting) which could otherwise be exploited by sending an unprotected SNI value during a TLS handshake, then putting a protected domain in the Host header after establishing connection. This is a safe default, but you may explicitly turn it off with `insecure_off`, for example in the case of running a proxy where domain fronting is desired and access is not restricted based on hostname.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## PKI Options
|
||||||
|
|
||||||
|
The PKI (Public Key Infrastructure) app is the foundation for Caddy's [Local HTTPS](/docs/automatic-https#local-https) and [ACME server](/docs/caddyfile/directives/acme_server) features. The app defines certificate authorities (CAs) which are capable of signing certificates.
|
||||||
|
|
||||||
|
The default CA ID is `local`. If the ID is omitted when configuring the `ca`, then `local` is assumed.
|
||||||
|
|
||||||
|
##### `name`
|
||||||
|
The user-facing name of the certificate authority. Default: `Caddy Local Authority`
|
||||||
|
|
||||||
|
##### `root_cn`
|
||||||
|
The name to put in the CommonName field of the root certificate. Default: `{pki.ca.name} - {time.now.year} ECC Root`
|
||||||
|
|
||||||
|
##### `intermediate_cn`
|
||||||
|
The name to put in the CommonName field of the intermediate certificates. Default: `{pki.ca.name} - ECC Intermediate`
|
||||||
|
|
||||||
|
##### `root`
|
||||||
|
A key pair (certificate and private key) to use as the root for the CA. If not specified, one will be generated and managed automatically.
|
||||||
|
|
||||||
|
- **format** is the format in which the certificate and private key are provided. Currently, only `pem_file` is supported, which is the default, so this field is optional.
|
||||||
|
- **cert** is the certificate. This should be the path to a PEM file, when using `pem_file` format.
|
||||||
|
- **key** is the private key. This should be the path to a PEM file, when using `pem_file` format.
|
||||||
|
|
||||||
|
##### `intermediate`
|
||||||
|
A key pair (certificate and private key) to use as the intermediate for the CA. If not specified, one will be generated and managed automatically.
|
||||||
|
|
||||||
|
- **format** is the format in which the certificate and private key are provided. Currently, only `pem_file` is supported, which is the default, so this field is optional.
|
||||||
|
- **cert** is the certificate. This should be the path to a PEM file, when using `pem_file` format.
|
||||||
|
- **key** is the private key. This should be the path to a PEM file, when using `pem_file` format.
|
||||||
|
|
|
@ -22,10 +22,10 @@ These are not drop-in solutions; you will have to customize your domain name, po
|
||||||
## Static file server
|
## Static file server
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com
|
example.com {
|
||||||
|
root * /var/www
|
||||||
root * /var/www
|
file_server
|
||||||
file_server
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
As usual, the first line is the site address. The [`root` directive](/docs/caddyfile/directives/root) specifies the path to the root of the site (the `*` means to match all requests, so as to disambiguate from a [path matcher](/docs/caddyfile/matchers#path-matchers))—change the path to your site if it isn't the current working directory. Finally, we enable the [static file server](/docs/caddyfile/directives/file_server).
|
As usual, the first line is the site address. The [`root` directive](/docs/caddyfile/directives/root) specifies the path to the root of the site (the `*` means to match all requests, so as to disambiguate from a [path matcher](/docs/caddyfile/matchers#path-matchers))—change the path to your site if it isn't the current working directory. Finally, we enable the [static file server](/docs/caddyfile/directives/file_server).
|
||||||
|
@ -36,19 +36,19 @@ As usual, the first line is the site address. The [`root` directive](/docs/caddy
|
||||||
Proxy all requests:
|
Proxy all requests:
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com
|
example.com {
|
||||||
|
reverse_proxy localhost:5000
|
||||||
reverse_proxy localhost:5000
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Only proxy requests having a path starting with `/api/` and serve static files for everything else:
|
Only proxy requests having a path starting with `/api/` and serve static files for everything else:
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com
|
example.com {
|
||||||
|
root * /var/www
|
||||||
root * /var/www
|
reverse_proxy /api/* localhost:5000
|
||||||
reverse_proxy /api/* localhost:5000
|
file_server
|
||||||
file_server
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,14 +57,15 @@ file_server
|
||||||
With a PHP FastCGI service running, something like this works for most modern PHP apps:
|
With a PHP FastCGI service running, something like this works for most modern PHP apps:
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com
|
example.com {
|
||||||
|
root * /srv/public
|
||||||
root * /var/www
|
encode gzip
|
||||||
php_fastcgi /blog/* localhost:9000
|
php_fastcgi localhost:9000
|
||||||
file_server
|
file_server
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Customize the site root and path matcher accordingly; this example assumes PHP is only in the `/blog/` subdirectory—all other requests will be served as static files.
|
Customize the site root accordingly; this example assumes that your PHP app's webroot is within a `public` directory—requests for files that exist on disk will be served with `file_server`, and anything else will be routed to `index.php` for handling by the PHP app.
|
||||||
|
|
||||||
The [`php_fastcgi` directive](/docs/caddyfile/directives/php_fastcgi) is actually just a shortcut for [several pieces of configuration](/docs/caddyfile/directives/php_fastcgi#expanded-form).
|
The [`php_fastcgi` directive](/docs/caddyfile/directives/php_fastcgi) is actually just a shortcut for [several pieces of configuration](/docs/caddyfile/directives/php_fastcgi#expanded-form).
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ To **add** the `www.` subdomain with an HTTP redirect:
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com {
|
example.com {
|
||||||
redir https://www.example.com{uri}
|
redir https://www.{host}{uri}
|
||||||
}
|
}
|
||||||
|
|
||||||
www.example.com {
|
www.example.com {
|
||||||
|
@ -95,6 +96,18 @@ example.com {
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
To remove it for **multiple domains** at once:
|
||||||
|
|
||||||
|
```caddy
|
||||||
|
www.example-one.com, www.example-two.com {
|
||||||
|
redir https://{labels.1}{labels.0}{uri}
|
||||||
|
}
|
||||||
|
|
||||||
|
example-one.com, example-two.com {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Trailing slashes
|
## Trailing slashes
|
||||||
|
|
||||||
You will not usually need to configure this yourself; the [`file_server` directive](/docs/caddyfile/directives/file_server) will automatically add or remove trailing slashes from requests by way of HTTP redirects, depending on whether the requested resource is a directory or file, respectively.
|
You will not usually need to configure this yourself; the [`file_server` directive](/docs/caddyfile/directives/file_server) will automatically add or remove trailing slashes from requests by way of HTTP redirects, depending on whether the requested resource is a directory or file, respectively.
|
||||||
|
@ -106,10 +119,10 @@ However, if you need to, you can still enforce trailing slashes with your config
|
||||||
This uses the [`rewrite`](/docs/caddyfile/directives/rewrite) directive. Caddy will rewrite the URI internally to add or remove the trailing slash:
|
This uses the [`rewrite`](/docs/caddyfile/directives/rewrite) directive. Caddy will rewrite the URI internally to add or remove the trailing slash:
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com
|
example.com {
|
||||||
|
rewrite /add /add/
|
||||||
rewrite /add /add/
|
rewrite /remove/ /remove
|
||||||
rewrite /remove/ /remove
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Using a rewrite, requests with and without the trailing slash will be the same.
|
Using a rewrite, requests with and without the trailing slash will be the same.
|
||||||
|
@ -120,15 +133,16 @@ Using a rewrite, requests with and without the trailing slash will be the same.
|
||||||
This uses the [`redir`](/docs/caddyfile/directives/redir) directive. Caddy will ask the browser to change the URI to add or remove the trailing slash:
|
This uses the [`redir`](/docs/caddyfile/directives/redir) directive. Caddy will ask the browser to change the URI to add or remove the trailing slash:
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com
|
example.com {
|
||||||
|
redir /add /add/
|
||||||
redir /add /add/
|
redir /remove/ /remove
|
||||||
redir /remove/ /remove
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Using a redirect, the client will have to re-issue the request, enforcing a single acceptable URI for a resource.
|
Using a redirect, the client will have to re-issue the request, enforcing a single acceptable URI for a resource.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Wildcard certificates
|
## Wildcard certificates
|
||||||
|
|
||||||
If you need to serve multiple subdomains with the same wildcard certificate, the best way to handle them is with a Caddyfile like this, making use of the [`handle`](/docs/caddyfile/directives/handle) directive and [`host`](/docs/caddyfile/matchers#host) matchers:
|
If you need to serve multiple subdomains with the same wildcard certificate, the best way to handle them is with a Caddyfile like this, making use of the [`handle`](/docs/caddyfile/directives/handle) directive and [`host`](/docs/caddyfile/matchers#host) matchers:
|
||||||
|
@ -159,6 +173,7 @@ If you need to serve multiple subdomains with the same wildcard certificate, the
|
||||||
Note that you must enable the [ACME DNS challenge](/docs/automatic-https#dns-challenge) to have Caddy automatically manage wildcard certificates.
|
Note that you must enable the [ACME DNS challenge](/docs/automatic-https#dns-challenge) to have Caddy automatically manage wildcard certificates.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Single-page apps (SPAs)
|
## Single-page apps (SPAs)
|
||||||
|
|
||||||
When a web page does its own routing, servers may receive lots of requests for pages that don't exist server-side, but which are renderable client-side as long as the singular index file is served instead. Web applications architected like this are known as SPAs, or single-page apps.
|
When a web page does its own routing, servers may receive lots of requests for pages that don't exist server-side, but which are renderable client-side as long as the singular index file is served instead. Web applications architected like this are known as SPAs, or single-page apps.
|
||||||
|
@ -168,25 +183,25 @@ The main idea is to have the server "try files" to see if the requested file exi
|
||||||
The most basic SPA config usually looks something like this:
|
The most basic SPA config usually looks something like this:
|
||||||
|
|
||||||
```caddy
|
```caddy
|
||||||
example.com
|
example.com {
|
||||||
|
|
||||||
root * /path/to/site
|
|
||||||
try_files {path} /index.html
|
|
||||||
file_server
|
|
||||||
```
|
|
||||||
|
|
||||||
If your SPA is coupled with an API or other server-side-only endpoints, you will want to use `handle` blocks to treat them exclusively:
|
|
||||||
|
|
||||||
```caddy
|
|
||||||
example.com
|
|
||||||
|
|
||||||
handle /api/* {
|
|
||||||
reverse_proxy backend:8000
|
|
||||||
}
|
|
||||||
|
|
||||||
handle {
|
|
||||||
root * /path/to/site
|
root * /path/to/site
|
||||||
try_files {path} /index.html
|
try_files {path} /index.html
|
||||||
file_server
|
file_server
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If your SPA is coupled with an API or other server-side-only endpoints, you will want to use `handle` blocks to treat them exclusively:
|
||||||
|
|
||||||
|
```caddy
|
||||||
|
example.com {
|
||||||
|
handle /api/* {
|
||||||
|
reverse_proxy backend:8000
|
||||||
|
}
|
||||||
|
|
||||||
|
handle {
|
||||||
|
root * /path/to/site
|
||||||
|
try_files {path} /index.html
|
||||||
|
file_server
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -321,46 +321,64 @@ Note: the flag `--config` doesn't support `-` to read the config from stdin.
|
||||||
|
|
||||||
Use of this command is discouraged with system services or on Windows. On Windows, the child process will remain attached to the terminal, so closing the window will forcefully stop Caddy, which is not obvious. Consider running Caddy [as a service](/docs/running) instead.
|
Use of this command is discouraged with system services or on Windows. On Windows, the child process will remain attached to the terminal, so closing the window will forcefully stop Caddy, which is not obvious. Consider running Caddy [as a service](/docs/running) instead.
|
||||||
|
|
||||||
Once started, you can use [`caddy stop`](#caddy-stop) or [the /stop API endpoint](/docs/api#post-stop) to exit the background process.
|
Once started, you can use [`caddy stop`](#caddy-stop) or the [`POST /stop`](/docs/api#post-stop) API endpoint to exit the background process.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### `caddy stop`
|
### `caddy stop`
|
||||||
|
|
||||||
<pre><code class="cmd bash">caddy stop [--address <interface>]</code></pre>
|
<pre><code class="cmd bash">caddy stop
|
||||||
|
[--address <interface>]
|
||||||
|
[--config <path> [--adapter <name>]]</code></pre>
|
||||||
|
|
||||||
<aside class="tip">
|
<aside class="tip">
|
||||||
Stopping (and restarting) the server is orthogonal to config changes. <b>Do not use the stop command to change configuration in production, unless you want downtime.</b> Use the <a href="#caddy-reload">caddy reload</a> command instead.
|
Stopping (and restarting) the server is orthogonal to config changes. <b>Do not use the stop command to change configuration in production, unless you want downtime.</b> Use the <a href="#caddy-reload">caddy reload</a> command instead.
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
Gracefully stops the running Caddy process (other than the process of the stop command) and causes it to exit. It uses the [/stop endpoint](/docs/api#post-stop) of the admin API to perform a graceful shutdown.
|
Gracefully stops the running Caddy process (other than the process of the stop command) and causes it to exit. It uses the [`POST /stop`](/docs/api#post-stop) endpoint of the admin API to perform a graceful shutdown.
|
||||||
|
|
||||||
`--address` can be used if the running instance's admin API is not on the default port; an alternate address can be specified here.
|
The address of this request can be customized using the `--address` flag, or from the given `--config`, if the running instance's admin API is not using the default listen address.
|
||||||
|
|
||||||
If you want to stop the current configuration but do not want to exit the process, use [`caddy reload`](#caddy-reload) with a blank config, or the [`DELETE /config/`](/docs/api#delete-configpath) endpoint.
|
If you want to stop the current configuration but do not want to exit the process, use [`caddy reload`](#caddy-reload) with a blank config, or the [`DELETE /config/`](/docs/api#delete-configpath) endpoint.
|
||||||
|
|
||||||
|
|
||||||
### `caddy trust`
|
### `caddy trust`
|
||||||
|
|
||||||
<pre><code class="cmd bash">caddy trust</code></pre>
|
<pre><code class="cmd bash">caddy trust
|
||||||
|
[--ca <id>]
|
||||||
|
[--address <interface>]
|
||||||
|
[--config <path> [--adapter <name>]]</code></pre>
|
||||||
|
|
||||||
Installs the root certificate for Caddy's default internal CA (named "local") into the local trust store(s); intended for development environments only. May prompt for a password if there are not already sufficient privileges.
|
Installs a root certificate for a CA managed by Caddy's [PKI app](/docs/json/apps/pki/) into local trust stores.
|
||||||
|
|
||||||
**This command is often unnecessary.** Because Caddy will install its root certificate into local trust stores automatically when first needed, this command is only useful if you need to pre-install the certificates while you have elevated privileges, like during system provisioning in automated environments.
|
Caddy will attempt to install its root certificates into the local trust stores automatically when they are first generated, but it might fail if Caddy doesn't have the appropriate permissions to write to the trust store. This command is necessary to pre-install the certificates before using them, if the server process runs as an unprivileged user (such as via systemd). You may need to run this command with `sudo` to unix systems.
|
||||||
|
|
||||||
|
By default, this command installs the root certificate for Caddy's default CA (i.e. "local"). You may specify the ID of another CA with the `--ca` flag.
|
||||||
|
|
||||||
|
This command will attempt to connect to Caddy's [admin API](/docs/api) to fetch the root certificate, using the [`GET /pki/ca/<id>/certificates`](/docs/api#get-pkicaidcertificates) endpoint. You may explicitly specify the `--address`, or use the `--config` flag to load the admin address from your config, if the running instance's admin API is not using the default listen address.
|
||||||
|
|
||||||
|
You may also use the `caddy` binary with this command to install certificates on other machines in your network, if the admin API is made accessible to other machines -- be careful if doing this, to not expose the admin API to untrusted clients.
|
||||||
|
|
||||||
|
|
||||||
### `caddy untrust`
|
### `caddy untrust`
|
||||||
|
|
||||||
<pre><code class="cmd bash">caddy untrust
|
<pre><code class="cmd bash">caddy untrust
|
||||||
|
[--cert <path>]
|
||||||
[--ca <id>]
|
[--ca <id>]
|
||||||
[--cert <path>]</code></pre>
|
[--address <interface>]
|
||||||
|
[--config <path> [--adapter <name>]]</code></pre>
|
||||||
|
|
||||||
Untrusts a root certificate from the local trust store(s). Intended for development environments only. Specify either the `--ca` or `--cert` flags, but not both. If neither are specified, Caddy's default CA (`local`).
|
Untrusts a root certificate from the local trust store(s).
|
||||||
|
|
||||||
`--ca` specifies the ID of the Caddy CA to untrust. The default CA's ID is `local`.
|
This command uninstalls trust; it does not necessarily delete the root certificate from trust stores entirely. Thus, repeatedly trusting and untrusting new certificates can fill up trust databases.
|
||||||
|
|
||||||
`--cert` specifies the path to the PEM-encoded certificate file to uninstall.
|
This command does not delete or modify certificate files from Caddy's configured storage.
|
||||||
|
|
||||||
|
This command can be used in one of two ways:
|
||||||
|
- By specifying a direct path to the root certificate to untrust with the `--cert` flag.
|
||||||
|
- By fetching the root certificate from the [admin API](/docs/api) using the [`GET /pki/ca/<id>/certificates`](/docs/api#get-pkicaidcertificates) endpoint. This is the default behaviour if no flags are given.
|
||||||
|
|
||||||
|
If the admin API is used, then the CA ID defaults to "local". You may specify the ID of another CA with the `--ca` flag. You may explicitly specify the `--address`, or use the `--config` flag to load the admin address from your config, if the running instance's admin API is not using the default listen address.
|
||||||
|
|
||||||
|
|
||||||
### `caddy upgrade`
|
### `caddy upgrade`
|
||||||
|
|
|
@ -58,7 +58,7 @@ Caddy's configuration supports the use of _placeholders_ (variables). Using plac
|
||||||
|
|
||||||
Placeholders are bounded on either side by curly braces `{ }` and contain the variable name inside, for example: `{foo.bar}`. Placeholder braces can be escaped, `\{like so\}`. Variable names are typically namespaced with dots to avoid collisions across modules.
|
Placeholders are bounded on either side by curly braces `{ }` and contain the variable name inside, for example: `{foo.bar}`. Placeholder braces can be escaped, `\{like so\}`. Variable names are typically namespaced with dots to avoid collisions across modules.
|
||||||
|
|
||||||
Which placeholders are available depends on the context. Not all placeholders are available in all parts of the config. For example, [the HTTP app sets placeholders](/docs/json/apps/http/) that are only available in areas of the config related to handling HTTP requests.
|
Which placeholders are available depends on the context. Not all placeholders are available in all parts of the config. For example, [the HTTP app sets placeholders](/docs/json/apps/http/#docs) that are only available in areas of the config related to handling HTTP requests.
|
||||||
|
|
||||||
The following placeholders are always available:
|
The following placeholders are always available:
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,13 @@ caddy.storage | [`caddy.StorageConverter`](https://pkg.go.dev/github.com/caddyse
|
||||||
http.authentication.hashes | [`caddyauth.Comparer`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth?tab=doc#Comparer) | Password hashers/comparers
|
http.authentication.hashes | [`caddyauth.Comparer`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth?tab=doc#Comparer) | Password hashers/comparers
|
||||||
http.authentication.providers | [`caddyauth.Authenticator`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth?tab=doc#Authenticator) | HTTP authentication providers
|
http.authentication.providers | [`caddyauth.Authenticator`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth?tab=doc#Authenticator) | HTTP authentication providers
|
||||||
http.handlers | [`caddyhttp.MiddlewareHandler`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp?tab=doc#MiddlewareHandler) | HTTP handlers
|
http.handlers | [`caddyhttp.MiddlewareHandler`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp?tab=doc#MiddlewareHandler) | HTTP handlers
|
||||||
http.matchers | [`caddyhttp.RequestMatcher`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp?tab=doc#RequestMatcher) | HTTP request matchers<br><i>⚠️ Subject to change</i>
|
http.matchers | [`caddyhttp.RequestMatcher`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp?tab=doc#RequestMatcher) | HTTP request matchers<br>
|
||||||
http.reverse_proxy.circuit_breakers | [`reverseproxy.CircuitBreaker`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy?tab=doc#CircuitBreaker) | Reverse proxy circuit breakers
|
http.reverse_proxy.circuit_breakers | [`reverseproxy.CircuitBreaker`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy?tab=doc#CircuitBreaker) | Reverse proxy circuit breakers
|
||||||
http.reverse_proxy.selection_policies | [`reverseproxy.Selector`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy?tab=doc#Selector) | Load balancing selection policies<br><i>⚠️ Subject to change</i>
|
http.reverse_proxy.selection_policies | [`reverseproxy.Selector`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy?tab=doc#Selector) | Load balancing selection policies<br>
|
||||||
http.reverse_proxy.transport | [`http.RoundTripper`](https://pkg.go.dev/net/http?tab=doc#RoundTripper) | HTTP reverse proxy transports
|
http.reverse_proxy.transport | [`http.RoundTripper`](https://pkg.go.dev/net/http?tab=doc#RoundTripper) | HTTP reverse proxy transports
|
||||||
|
http.reverse_proxy.upstreams | [`reverseproxy.UpstreamSource`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddyhttp/reverseproxy?tab=doc#UpstreamSource) | Dynamic upstream source <i>⚠️ Experimental</i>
|
||||||
tls.certificates | [`caddytls.CertificateLoader`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddytls?tab=doc#CertificateLoader) | TLS certificate source</i>
|
tls.certificates | [`caddytls.CertificateLoader`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddytls?tab=doc#CertificateLoader) | TLS certificate source</i>
|
||||||
tls.handshake_match | [`caddytls.ConnectionMatcher`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddytls?tab=doc#ConnectionMatcher) | TLS connection matcher</i>
|
tls.handshake_match | [`caddytls.ConnectionMatcher`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddytls?tab=doc#ConnectionMatcher) | TLS connection matcher</i>
|
||||||
tls.issuance | [`certmagic.Issuer`](https://pkg.go.dev/github.com/caddyserver/certmagic?tab=doc#Issuer) | TLS certificate issuer<br><i>⚠️ Subject to change</i>
|
tls.issuance | [`certmagic.Issuer`](https://pkg.go.dev/github.com/caddyserver/certmagic?tab=doc#Issuer) | TLS certificate issuer<br>
|
||||||
|
tls.get_certificate | [`certmagic.CertificateManager`](https://pkg.go.dev/github.com/caddyserver/certmagic?tab=doc#CertificateManager) | TLS certificate manager<br><i>⚠️ Experimental</i>
|
||||||
tls.stek | [`caddytls.STEKProvider`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddytls?tab=doc#STEKProvider) | TLS session ticket key source</i>
|
tls.stek | [`caddytls.STEKProvider`](https://pkg.go.dev/github.com/caddyserver/caddy/v2/modules/caddytls?tab=doc#STEKProvider) | TLS session ticket key source</i>
|
||||||
|
|
|
@ -50,54 +50,47 @@ Now compare an equivalent structured log message from Caddy, encoded as JSON and
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"level": "info",
|
"level": "info",
|
||||||
"ts": 1585597114.7687502,
|
"ts": 1646861401.5241024,
|
||||||
"logger": "http.log.access",
|
"logger": "http.log.access",
|
||||||
"msg": "handled request",
|
"msg": "handled request",
|
||||||
"request": {
|
"request": {
|
||||||
"method": "GET",
|
"remote_ip": "127.0.0.1",
|
||||||
"uri": "/",
|
"remote_port": "41342",
|
||||||
"proto": "HTTP/2.0",
|
"proto": "HTTP/2.0",
|
||||||
"remote_addr": "127.0.0.1:50876",
|
"method": "GET",
|
||||||
"host": "example.com",
|
"host": "localhost",
|
||||||
|
"uri": "/",
|
||||||
"headers": {
|
"headers": {
|
||||||
"User-Agent": [
|
"User-Agent": ["curl/7.82.0"],
|
||||||
"curl/7.64.1"
|
"Accept": ["*/*"],
|
||||||
],
|
"Accept-Encoding": ["gzip, deflate, br"],
|
||||||
"Accept": [
|
|
||||||
"*/*"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"tls": {
|
"tls": {
|
||||||
"resumed": false,
|
"resumed": false,
|
||||||
"version": 771,
|
"version": 772,
|
||||||
"ciphersuite": 49196,
|
"cipher_suite": 4865,
|
||||||
"proto": "h2",
|
"proto": "h2",
|
||||||
"proto_mutual": true,
|
|
||||||
"server_name": "example.com"
|
"server_name": "example.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user_id": "",
|
"user_id": "",
|
||||||
"duration": 0.000014711,
|
"duration": 0.000929675,
|
||||||
"size": 2326,
|
"size": 10900,
|
||||||
"status": 200,
|
"status": 200,
|
||||||
"resp_headers": {
|
"resp_headers": {
|
||||||
"Server": [
|
"Server": ["Caddy"],
|
||||||
"Caddy"
|
"Content-Encoding": ["gzip"],
|
||||||
],
|
"Content-Type": ["text/html; charset=utf-8"],
|
||||||
"Content-Type": ["text/html"]
|
"Vary": ["Accept-Encoding"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<aside class="tip">
|
|
||||||
In actual access logs emitted from Caddy, another field called "common_log" is also present. The purpose of this field is just to help people transition from legacy systems to more modern ones.
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
You can see how the structured log is much more useful and contains much more information. The abundance of information in this log message is not only useful, but it comes at virtually no performance overhead: Caddy's logs are zero-allocation. Structured logs have no restrictions on data types or context: they can be used in any code path and include any kind of information.
|
You can see how the structured log is much more useful and contains much more information. The abundance of information in this log message is not only useful, but it comes at virtually no performance overhead: Caddy's logs are zero-allocation. Structured logs have no restrictions on data types or context: they can be used in any code path and include any kind of information.
|
||||||
|
|
||||||
Because the logs are structured and strongly-typed, they can be encoded into any format. So if you don't want to work with JSON, logs can be encoded into any other representation. Caddy supports others through [log encoder modules](/docs/json/logging/logs/encoder/), and even more can be added.
|
Because the logs are structured and strongly-typed, they can be encoded into any format. So if you don't want to work with JSON, logs can be encoded into any other representation. Caddy supports others through [log encoder modules](/docs/json/logging/logs/encoder/), and even more can be added.
|
||||||
|
|
||||||
**Most importantly** in the distinction between structured logs and legacy formats, a structured log can be encoded as Common Log Format (or anything else!), but not the other way around. It is non-trivial (or at least inefficient) to go from CLF to structured formats, and impossible considering the lack of information.
|
**Most importantly** in the distinction between structured logs and legacy formats, with a performance penalty a structured log [can be transformed into the legacy Common Log Format](https://github.com/caddyserver/transform-encoder), but not the other way around. It is non-trivial (or at least inefficient) to go from CLF to structured formats, and impossible considering the lack of information.
|
||||||
|
|
||||||
In essence, efficient, structured logging generally promotes these philosophies:
|
In essence, efficient, structured logging generally promotes these philosophies:
|
||||||
|
|
||||||
|
|
|
@ -243,7 +243,7 @@ log
|
||||||
|
|
||||||
which emits structured logs to stderr. (You can also emit to a file or network socket; see the [`log`](/docs/caddyfile/directives/log) directive docs.)
|
which emits structured logs to stderr. (You can also emit to a file or network socket; see the [`log`](/docs/caddyfile/directives/log) directive docs.)
|
||||||
|
|
||||||
By default, logs will be in [structured](/docs/logging) JSON format. If you still need logs in Common Log Format (CLF) for legacy reasons, you may use the [`format-encoder`](https://github.com/caddyserver/format-encoder) plugin.
|
By default, logs will be in [structured](/docs/logging) JSON format. If you still need logs in Common Log Format (CLF) for legacy reasons, you may use the [`transform-encoder`](https://github.com/caddyserver/transform-encoder) plugin.
|
||||||
|
|
||||||
|
|
||||||
### proxy
|
### proxy
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue