mirror of
https://github.com/caddyserver/website.git
synced 2025-04-22 21:16:15 -04:00
Docs for v2.7.0 (#322)
* Docs for v2.7.0 * Document named-routes & invoke, polish reverse_proxy * Storage import/export CLI docs * Header replacement defer * Proxy stream closing options, weighted round robin LB policy
This commit is contained in:
parent
0a8e6ef86b
commit
194beebc7c
15 changed files with 454 additions and 105 deletions
|
@ -7,13 +7,17 @@ title: Caddyfile Concepts
|
|||
This document will help you learn about the HTTP Caddyfile in detail.
|
||||
|
||||
1. [Structure](#structure)
|
||||
- [Blocks](#blocks)
|
||||
- [Directives](#directives)
|
||||
- [Tokens and quotes](#tokens-and-quotes)
|
||||
2. [Addresses](#addresses)
|
||||
3. [Matchers](#matchers)
|
||||
4. [Placeholders](#placeholders)
|
||||
5. [Snippets](#snippets)
|
||||
6. [Comments](#comments)
|
||||
7. [Environment variables](#environment-variables)
|
||||
8. [Global options](#global-options)
|
||||
6. [Named Routes](#named-routes)
|
||||
7. [Comments](#comments)
|
||||
8. [Environment variables](#environment-variables)
|
||||
9. [Global options](#global-options)
|
||||
|
||||
|
||||
## Structure
|
||||
|
@ -25,6 +29,7 @@ The Caddyfile's structure can be described visually:
|
|||
Key points:
|
||||
|
||||
- An optional [**global options block**](#global-options) can be the very first thing in the file.
|
||||
- [Snippets](#snippets) or [named routes](#named-routes) may optionally appear next.
|
||||
- Otherwise, the first line of the Caddyfile is **always** the [address(es)](#addresses) of the site to serve.
|
||||
- All [directives](#directives) and [matchers](#matchers) **must** go in a site block. There is no global scope or inheritance across site blocks.
|
||||
- If there is only one site block, its curly braces `{ }` are optional.
|
||||
|
@ -85,17 +90,17 @@ If a request matches multiple site blocks, the site block with the most specific
|
|||
[**Directives**](/docs/caddyfile/directives) are functional keywords which customize how the site is served. They **must** appear within site blocks. For example, a complete file server config might look like this:
|
||||
|
||||
```caddy
|
||||
localhost
|
||||
|
||||
file_server
|
||||
localhost {
|
||||
file_server
|
||||
}
|
||||
```
|
||||
|
||||
Or a reverse proxy:
|
||||
|
||||
```caddy
|
||||
localhost
|
||||
|
||||
reverse_proxy localhost:9000
|
||||
localhost {
|
||||
reverse_proxy localhost:9000
|
||||
}
|
||||
```
|
||||
|
||||
In these examples, [`file_server`](/docs/caddyfile/directives/file_server) and [`reverse_proxy`](/docs/caddyfile/directives/reverse_proxy) are directives. Directives are the first word on a line in a site block.
|
||||
|
@ -105,10 +110,10 @@ In the second example, `localhost:9000` is an **argument** because it appears on
|
|||
Sometimes directives can open their own blocks. **Subdirectives** appear on the beginning of each line within directive blocks:
|
||||
|
||||
```caddy
|
||||
localhost
|
||||
|
||||
reverse_proxy localhost:9000 localhost:9001 {
|
||||
lb_policy first
|
||||
localhost {
|
||||
reverse_proxy localhost:9000 localhost:9001 {
|
||||
lb_policy first
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -156,6 +161,25 @@ directive "first line
|
|||
second line"
|
||||
```
|
||||
|
||||
Heredocs <span id="heredocs"/> are also supported:
|
||||
|
||||
```caddy
|
||||
example.com {
|
||||
respond <<HTML
|
||||
<html>
|
||||
<head><title>Foo</title></head>
|
||||
<body>Foo</body>
|
||||
</html>
|
||||
HTML 200
|
||||
}
|
||||
```
|
||||
|
||||
The opening heredoc marker must start with `<<`, followed by any text (uppercase letters recommended). The closing heredoc marker must be the same text (in the above example, `HTML`).
|
||||
|
||||
The closing marker can be indented, which causes every line of text to have that much indentation stripped (inspired by [PHP](https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc)) which is nice for readability inside [blocks](#blocks) while giving great control of the whitespace in the token text. The trailing newline is also stripped, but can be retained by adding an extra blank line before the closing marker.
|
||||
|
||||
Additional tokens may follow the closing marker as arguments to the directive (such as in the example above, the status code `200`).
|
||||
|
||||
|
||||
|
||||
## Addresses
|
||||
|
@ -236,6 +260,7 @@ You can use any [Caddy placeholders](/docs/conventions#placeholders) in the Cadd
|
|||
| Shorthand | Replaces |
|
||||
|-----------------|-----------------------------------|
|
||||
| `{cookie.*}` | `{http.request.cookie.*}` |
|
||||
| `{client_ip}` | `{http.vars.client_ip}` |
|
||||
| `{dir}` | `{http.request.uri.path.dir}` |
|
||||
| `{err.*}` | `{http.error.*}` |
|
||||
| `{file_match.*}` | `{http.matchers.file.*}` |
|
||||
|
@ -297,7 +322,7 @@ You can pass arguments to imported configuration and use them like so:
|
|||
|
||||
```caddy
|
||||
(snippet) {
|
||||
respond "Yahaha! You found {args.0}!"
|
||||
respond "Yahaha! You found {args[0]}!"
|
||||
}
|
||||
|
||||
a.example.com {
|
||||
|
@ -310,6 +335,27 @@ b.example.com {
|
|||
```
|
||||
|
||||
|
||||
## Named Routes
|
||||
|
||||
Named routes use syntax similar to [snippets](#snippets); they're a special block defined outside of site blocks, prefixed with `&(` and ending in `)` with the name in between.
|
||||
|
||||
```caddy
|
||||
&(app-proxy) {
|
||||
reverse_proxy app-01:8080 app-02:8080 app-03:8080
|
||||
}
|
||||
```
|
||||
|
||||
And then you can reuse this named route within any site:
|
||||
|
||||
```caddy-d
|
||||
invoke app-proxy
|
||||
```
|
||||
|
||||
This is particularly useful to reduce memory usage if the same route is needed in many different sites, or if multiple different matcher conditions are needed to invoke the same route.
|
||||
|
||||
See the [`invoke` directive](/docs/caddyfile/directives/invoke) documentation for more details.
|
||||
|
||||
|
||||
## Comments
|
||||
|
||||
Comments start with `#` and proceed until the end of the line:
|
||||
|
|
|
@ -54,6 +54,7 @@ Directive | Description
|
|||
**[handle_path](/docs/caddyfile/directives/handle_path)** | Like handle, but strips path prefix
|
||||
**[header](/docs/caddyfile/directives/header)** | Sets or removes response headers
|
||||
**[import](/docs/caddyfile/directives/import)** | Include snippets or files
|
||||
**[invoke](/docs/caddyfile/directives/invoke)** | Invoke a named route
|
||||
**[log](/docs/caddyfile/directives/log)** | Enables access/request logging
|
||||
**[map](/docs/caddyfile/directives/map)** | Maps an input value to one or more outputs
|
||||
**[method](/docs/caddyfile/directives/method)** | Change the HTTP method internally
|
||||
|
@ -143,6 +144,7 @@ push
|
|||
templates
|
||||
|
||||
# special routing & dispatching directives
|
||||
invoke
|
||||
handle
|
||||
handle_path
|
||||
route
|
||||
|
|
|
@ -18,10 +18,14 @@ Using ACME server defaults, ACME clients should simply be configured to use `htt
|
|||
|
||||
```caddy-d
|
||||
acme_server [<matcher>] {
|
||||
ca <id>
|
||||
lifetime <duration>
|
||||
ca <id>
|
||||
lifetime <duration>
|
||||
resolvers <resolvers...>
|
||||
}
|
||||
```
|
||||
|
||||
- **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.
|
||||
|
||||
- **lifetime** (Default: `12h`) is a [duration](/docs/conventions#durations) which specifies the validity period for issued certificates. This value must be less than the lifetime of the [intermediate certificate](/docs/caddyfile/options#intermediate-lifetime) used for signing. It is not recommended to change this unless absolutely necessary.
|
||||
|
||||
- **resolvers** are the addresses of DNS resolvers to use when looking up the TXT records for solving ACME DNS challenges. Accepts [network addresses](/docs/conventions#network-addresses) defaulting to UDP and port 53 unless specified. If the host is an IP address, it will be dialed directly to resolve the upstream server. If the hot is not an IP address, the addresses are resolved using the [name resolution convention](https://golang.org/pkg/net/#hdr-Name_Resolution) of the Go standard library. If multiple resolvers are specified, then one is chosen at random.
|
||||
|
|
|
@ -12,16 +12,25 @@ By default, header operations are performed immediately unless any of the header
|
|||
## Syntax
|
||||
|
||||
```caddy-d
|
||||
header [<matcher>] [[+|-|?]<field> [<value>|<find>] [<replace>]] {
|
||||
# Replace
|
||||
<field> <find> <replace>
|
||||
header [<matcher>] [[+|-|?|>]<field> [<value>|<find>] [<replace>]] {
|
||||
# Add
|
||||
+<field> <value>
|
||||
|
||||
# Add or Set
|
||||
[+]<field> <value>
|
||||
# Set
|
||||
<field> <value>
|
||||
|
||||
# Set with defer
|
||||
><field> <value>
|
||||
|
||||
# Delete
|
||||
-<field>
|
||||
|
||||
# Replace
|
||||
<field> <find> <replace>
|
||||
|
||||
# Replace with defer
|
||||
><field> <find> <replace>
|
||||
|
||||
# Default
|
||||
?<field> <value>
|
||||
|
||||
|
@ -37,13 +46,15 @@ header [<matcher>] [[+|-|?]<field> [<value>|<find>] [<replace>]] {
|
|||
|
||||
Prefix with `?` to set a default value for the field. The field is only written if it doesn't yet exist.
|
||||
|
||||
Prefix with `>` to set the field, and enable `defer`, as a shortcut.
|
||||
|
||||
- **<value>** is the header field value, if adding or setting a field.
|
||||
|
||||
- **<find>** is the substring or regular expression to search for.
|
||||
|
||||
- **<replace>** is the replacement value; required if performing a search-and-replace.
|
||||
|
||||
- **defer** will force the header operations to be deferred until the response is being written out to the client. This is automatically enabled if any of the header fields are being deleted with `-`, or when setting a default value with `?`.
|
||||
- **defer** will force the header operations to be deferred until the response is being written out to the client. This is automatically enabled if any of the header fields are being deleted with `-`, when setting a default value with `?`, or when having used the `>` prefix.
|
||||
|
||||
For multiple header manipulations, you can open a block and specify one manipulation per line in the same way.
|
||||
|
||||
|
@ -106,3 +117,16 @@ Set a default cache expiration if upstream doesn't define one:
|
|||
header ?Cache-Control "max-age=3600"
|
||||
reverse_proxy upstream:443
|
||||
```
|
||||
|
||||
To override the cache expiration that a proxy upstream had set for paths starting with `/no-cache`; enabling `defer` is necessary to ensure the header is set _after_ the proxy writes its headers:
|
||||
|
||||
```caddy-d
|
||||
header /no-cache* >Cache-Control nocache
|
||||
reverse_proxy upstream:443
|
||||
```
|
||||
|
||||
To perform a deferred update of a `Set-Cookie` header to add `SameSite=None`; a regexp capture is used to grab the existing value, and `$1` re-inserts it at the start with the additional option appended:
|
||||
|
||||
```caddy-d
|
||||
header >Set-Cookie (.*) "$1; SameSite=None;"
|
||||
```
|
||||
|
|
|
@ -23,7 +23,16 @@ import <pattern> [<args...>]
|
|||
If the pattern is a filename or glob, it is always relative to the file the `import` appears in.
|
||||
|
||||
If using a glob pattern `*` as the final path segment, hidden files (i.e. files starting with a `.`) are ignored. To import hidden files, use `.*` as the final segment.
|
||||
- **<args...>** is an optional list of arguments to pass to the imported tokens. They can be used with a placeholder of the form `{args.N}` where `N` is the 0-based positional index of the parameter. This placeholder is a special case and is evaluated at parse-time, not run-time.
|
||||
- **<args...>** is an optional list of arguments to pass to the imported tokens. This placeholder is a special case and is evaluated at Caddyfile-parse-time, not at run-time. They can be used in various forms, similarly to [Go's slice syntax](https://gobyexample.com/slices):
|
||||
- `{args[n]}` where `n` is the 0-based positional index of the parameter
|
||||
- `{args[:]}` where all the arguments are inserted
|
||||
- `{args[:m]}` where the arguments before `m` are inserted
|
||||
- `{args[n:]}` where the arguments beginning with `n` are inserted
|
||||
- `{args[n:m]}` where the arguments in the range between `n` and `m` are inserted
|
||||
|
||||
For the forms that insert many tokens, the placeholder _must_ be a [token](/docs/caddyfile/concepts#tokens-and-quotes) on its own, it cannot be part of another token. In other words, it must have spaces around it, and cannot be in quotes.
|
||||
|
||||
Note that prior to v2.7.0, the syntax was `{args.N}` but this form was deprecated in favor of the more flexible syntax above.
|
||||
|
||||
|
||||
## Examples
|
||||
|
@ -38,8 +47,8 @@ Import a snippet that sets CORS headers using an import argument:
|
|||
|
||||
```caddy
|
||||
(cors) {
|
||||
@origin header Origin {args.0}
|
||||
header @origin Access-Control-Allow-Origin "{args.0}"
|
||||
@origin header Origin {args[0]}
|
||||
header @origin Access-Control-Allow-Origin "{args[0]}"
|
||||
header @origin Access-Control-Allow-Methods "OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE"
|
||||
}
|
||||
|
||||
|
@ -47,3 +56,32 @@ example.com {
|
|||
import cors example.com
|
||||
}
|
||||
```
|
||||
|
||||
Import a snippet which takes a list of proxy upstreams as arguments:
|
||||
|
||||
```caddy
|
||||
(https-proxy) {
|
||||
reverse_proxy {args[:]} {
|
||||
transport http {
|
||||
tls
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example.com {
|
||||
import https-proxy 10.0.0.1 10.0.0.2 10.0.0.3
|
||||
}
|
||||
```
|
||||
|
||||
Import a snippet which creates a proxy with a prefix rewrite rule as the first argument:
|
||||
|
||||
```caddy
|
||||
(proxy-rewrite) {
|
||||
rewrite * {args[0]}{uri}
|
||||
reverse_proxy {args[1:]}
|
||||
}
|
||||
|
||||
example.com {
|
||||
import proxy-rewrite /api 10.0.0.1 10.0.0.2 10.0.0.3
|
||||
}
|
||||
```
|
||||
|
|
56
src/docs/markdown/caddyfile/directives/invoke.md
Normal file
56
src/docs/markdown/caddyfile/directives/invoke.md
Normal file
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
title: invoke (Caddyfile directive)
|
||||
---
|
||||
|
||||
# invoke
|
||||
|
||||
Invokes a [named route](/docs/caddyfile/concepts#named-routes).
|
||||
|
||||
This is useful when paired with HTTP handler directives that have their own in-memory state, or if they are expensive to provision on load. If you have hundreds of sites or more, invoking a named route can help reduce memory usage.
|
||||
|
||||
<aside class="tip">
|
||||
|
||||
Unlike [`import`](/docs/caddyfile/directives/import), `invoke` does not support arguments, but you may use [`vars`](/docs/caddyfile/directives/vars) to define variables that can be used within the named route.
|
||||
|
||||
</aside>
|
||||
|
||||
## Syntax
|
||||
|
||||
```caddy-d
|
||||
invoke [<matcher>] <route-name>
|
||||
```
|
||||
|
||||
- **<route-name>** is the name of the previously defined route that should be invoked. If the route is not found, then an error will be triggered.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
Defines a [named route](/docs/caddyfile/concepts#named-routes) with a [`reverse_proxy`](/docs/caddyfile/directives/reverse_proxy) which can be reused in multiple sites, with the same in-memory load balancing state reused for every site.
|
||||
|
||||
```caddy
|
||||
&(app-proxy) {
|
||||
reverse_proxy app-01:8080 app-02:8080 app-03:8080 {
|
||||
lb_policy least_conn
|
||||
health_uri /healthz
|
||||
health_interval 5s
|
||||
}
|
||||
}
|
||||
|
||||
# Apex domain allows accessing the app via an /app subpath
|
||||
# and the main site otherwise.
|
||||
example.com {
|
||||
handle_path /app* {
|
||||
invoke app-proxy
|
||||
}
|
||||
|
||||
handle {
|
||||
root * /srv
|
||||
file_server
|
||||
}
|
||||
}
|
||||
|
||||
# The app is also accessible via a subdomain.
|
||||
app.example.com {
|
||||
invoke app-proxy
|
||||
}
|
||||
```
|
|
@ -54,3 +54,14 @@ respond /secret/* "Access denied" 403 {
|
|||
close
|
||||
}
|
||||
```
|
||||
|
||||
Write an HTML response, using [heredoc syntax](/docs/caddyfile/concepts#heredocs) to control whitespace:
|
||||
|
||||
```caddy-d
|
||||
respond <<HTML
|
||||
<html>
|
||||
<head><title>Foo</title></head>
|
||||
<body>Foo</body>
|
||||
</html>
|
||||
HTML 200
|
||||
```
|
||||
|
|
|
@ -83,9 +83,11 @@ reverse_proxy [<matcher>] [<upstreams...>] {
|
|||
unhealthy_request_count <num>
|
||||
|
||||
# streaming
|
||||
flush_interval <duration>
|
||||
request_buffers <size>
|
||||
response_buffers <size>
|
||||
flush_interval <duration>
|
||||
request_buffers <size>
|
||||
response_buffers <size>
|
||||
stream_timeout <duration>
|
||||
stream_close_delay <duration>
|
||||
|
||||
# request/header manipulation
|
||||
trusted_proxies [private_ranges] <ranges...>
|
||||
|
@ -141,6 +143,7 @@ Static upstream addresses can take the form of a URL that contains only scheme a
|
|||
- `example.com`
|
||||
- `unix//var/php.sock`
|
||||
- `unix+h2c//var/grpc.sock`
|
||||
- `localhost:8001-8006`
|
||||
|
||||
By default, connections are made to the upstream over plaintext HTTP. When using the URL form, a scheme can be used to set some [`transport`](#transports) defaults as a shorthand.
|
||||
- Using `https://` as the scheme will use the [`http` transport](#the-http-transport) with [`tls`](#tls) enabled.
|
||||
|
@ -152,7 +155,7 @@ By default, connections are made to the upstream over plaintext HTTP. When using
|
|||
|
||||
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.
|
||||
|
||||
When using the [network address](/docs/conventions#network-addresses) form, the network type is specified as a prefix to the upstream address. This cannot be combined with a URL scheme. As a special case, `unix+h2c/` is supported as a shortcut for the `unix/` network plus the same effects as the `h2c://` scheme.
|
||||
When using the [network address](/docs/conventions#network-addresses) form, the network type is specified as a prefix to the upstream address. This cannot be combined with a URL scheme. As a special case, `unix+h2c/` is supported as a shortcut for the `unix/` network plus the same effects as the `h2c://` scheme. Port ranges are supported as a shortcut, which expands to multiple upstreams with the same host.
|
||||
|
||||
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.
|
||||
|
||||
|
@ -203,6 +206,7 @@ Retrieves upstreams from A/AAAA DNS records.
|
|||
resolvers <ip...>
|
||||
dial_timeout <duration>
|
||||
dial_fallback_delay <duration>
|
||||
versions ipv4|ipv6
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -212,6 +216,7 @@ Retrieves upstreams from A/AAAA DNS records.
|
|||
- **resolvers** is the list of DNS resolvers to override system resolvers.
|
||||
- **dial_timeout** is the timeout for dialing the query.
|
||||
- **dial_fallback_delay** is how long to wait before spawning an RFC 6555 Fast Fallback connection. Default: `300ms`
|
||||
- **versions** is the list of IP versions to resolve for. Default: `ipv4 ipv6` which correspond to both A and AAAA records respectively.
|
||||
|
||||
|
||||
##### Multi
|
||||
|
@ -231,31 +236,39 @@ Append the results of multiple dynamic upstream modules. Useful if you want redu
|
|||
|
||||
### Load balancing
|
||||
|
||||
Load balancing is used whenever more than one upstream is defined.
|
||||
Load balancing is used whenever more than one upstream is defined. This is enabled by default, with the `random` load balancing policy.
|
||||
|
||||
- **lb_policy** <span id="lb_policy"/> is the name of the load balancing policy, along with any options. Default: `random`.
|
||||
|
||||
For policies that involve hashing, the [highest-random-weight (HRW)](https://en.wikipedia.org/wiki/Rendezvous_hashing) algorithm is used to ensure that a client or request with the same hash key is mapped to the same upstream, even if the list of upstreams change.
|
||||
|
||||
Some policies support fallback as an option, if noted, in which case they take a [block](/docs/caddyfile/concepts#blocks) with `fallback <policy>` which takes another load balancing policy. For those policies, the default fallback is `random`. Configuring a fallback allows using a secondary policy if the primary does not select one, allowing for powerful combinations. Fallbacks can be nested multiple times if desired. For example, `header` can be used as primary to allow for developers to choose a specific upstream, with a fallback of `first` for all other connections to implement primary/secondary failover.
|
||||
|
||||
- `random` randomly chooses an upstream
|
||||
|
||||
- `random_choose <n>` selects two or more upstreams randomly, then chooses one with least load (`n` is usually 2)
|
||||
|
||||
- `first` chooses the first available upstream, from the order they are defined in the config
|
||||
- `first` chooses the first available upstream, from the order they are defined in the config, allowing for primary/secondary failover; remember to enable health checks along with this, otherwise failover will not occur
|
||||
|
||||
- `round_robin` iterates each upstream in turn
|
||||
|
||||
- `weighted_round_robin <weights...>` iterates each upstream in turn, respecting the weights provided. The amount of weight arguments should match the amount of upstreams configured. Weights should be non-zero positive integers. For example with two upstreams and weights `5 1`, the first upstream would be selected 5 times in a row before the second upstream is selected once, then the cycle repeats.
|
||||
|
||||
- `least_conn` choose upstream with fewest number of current requests; if more than one host has the least number of requests, then one of those hosts is chosen at random
|
||||
|
||||
- `ip_hash` maps the client IP to a sticky upstream
|
||||
- `ip_hash` maps the remote IP (the immediate peer) to a sticky upstream
|
||||
|
||||
- `client_ip_hash` maps the client IP to a sticky upstream; this is best paired with the [`servers > trusted_proxies` global option](/docs/caddyfile/options#trusted-proxies) which enables real client IP parsing, otherwise it behaves the same as `ip_hash`
|
||||
|
||||
- `uri_hash` maps the request URI (path and query) to a sticky upstream
|
||||
|
||||
- `header [field]` maps a request header to a sticky upstream, by hashing the header value; if the specified header field is not present, a random upstream is selected
|
||||
- `query [key]` maps a request query to a sticky upstream, by hashing the query value; if the specified key is not present, the fallback policy will be used to select an upstream (`random` by default)
|
||||
|
||||
- `cookie [<name> [<secret>]]` on the first request from a client (when there's no cookie), a random upstream is selected, and a `Set-Cookie` header is added to the response (default cookie name is `lb` if not specified). The cookie value is the upstream dial address of the chosen upstream, hashed with HMAC-SHA256 (using `<secret>` as the shared secret, empty string if not specified).
|
||||
- `header [field]` maps a request header to a sticky upstream, by hashing the header value; if the specified header field is not present, the fallback policy will be used to select an upstream (`random` by default)
|
||||
|
||||
- `cookie [<name> [<secret>]]` on the first request from a client (when there's no cookie), the fallback policy will be used to select an upstream (`random` by default), and a `Set-Cookie` header is added to the response (default cookie name is `lb` if not specified). The cookie value is the upstream dial address of the chosen upstream, hashed with HMAC-SHA256 (using `<secret>` as the shared secret, empty string if not specified).
|
||||
|
||||
On subsequent requests where the cookie is present, the cookie value will be mapped to the same upstream if it's available; if not available or not found, a new random upstream is selected and the cookie is added to the response.
|
||||
On subsequent requests where the cookie is present, the cookie value will be mapped to the same upstream if it's available; if not available or not found, a new upstream is selected with the fallback policy, and the cookie is added to the response.
|
||||
|
||||
If you wish to use a particular upstream for debugging purposes, you may hash the upstream address with the secret, and set the cookie in your HTTP client (browser or otherwise). For example, with PHP, you could run the following to compute the cookie value, where `10.1.0.10:8080` is the address of one of your upstreams, and `secret` is your configured secret.
|
||||
```php
|
||||
|
@ -286,13 +299,13 @@ Load balancing is used whenever more than one upstream is defined.
|
|||
|
||||
#### Active health checks
|
||||
|
||||
Active health checks perform health checking in the background on a timer:
|
||||
Active health checks perform health checking in the background on a timer. To enable this, `health_uri` or `health_port` are required.
|
||||
|
||||
- **health_uri** <span id="health_uri"/> is the URI path (and optional query) for active health checks.
|
||||
|
||||
- **health_port** <span id="health_port"/> is the port to use for active health checks, if different from the upstream's port.
|
||||
|
||||
- **health_interval** <span id="health_interval"/> is a [duration value](/docs/conventions#durations) that defines how often to perform active health checks.
|
||||
- **health_interval** <span id="health_interval"/> is a [duration value](/docs/conventions#durations) that defines how often to perform active health checks. Default: `30s`.
|
||||
|
||||
- **health_timeout** <span id="health_timeout"/> is a [duration value](/docs/conventions#durations) that defines how long to wait for a reply before marking the backend as down.
|
||||
|
||||
|
@ -306,7 +319,7 @@ Active health checks perform health checking in the background on a timer:
|
|||
|
||||
#### Passive health checks
|
||||
|
||||
Passive health checks happen inline with actual proxied requests:
|
||||
Passive health checks happen inline with actual proxied requests. To enable this, `fail_duration` is required.
|
||||
|
||||
- **fail_duration** <span id="fail_duration"/> is a [duration value](/docs/conventions#durations) that defines how long to remember a failed request. A duration > `0` enables passive health checking; the default is `0` (off). A reasonable starting point might be `30s` to balance error rates with responsiveness when bringing an unhealthy upstream back online; but feel free to experiment to find the right balance for your usecase.
|
||||
|
||||
|
@ -324,7 +337,15 @@ Passive health checks happen inline with actual proxied requests:
|
|||
|
||||
### Streaming
|
||||
|
||||
By default, the proxy partially buffers the response for wire efficiency:
|
||||
By default, the proxy partially buffers the response for wire efficiency.
|
||||
|
||||
The proxy also supports WebSocket connections, performing the HTTP upgrade request then transitioning the connection to a bidirectional tunnel.
|
||||
|
||||
<aside class="tip">
|
||||
|
||||
By default, WebSocket connections are forcibly closed (with a Close control message sent to both the client and upstream) when the config is reloaded. Each request holds a reference to the config, so closing old connections is necessary to keep memory usage in check. This closing behaviour can be customized with the [`stream_timeout`](#stream_timeout) and [`stream_close_delay`](#stream_close_delay) options.
|
||||
|
||||
</aside>
|
||||
|
||||
- **flush_interval** <span id="flush_interval"/> is a [duration value](/docs/conventions#durations) that adjusts how often Caddy should flush the response buffer to the client. By default, no periodic flushing is done. A negative value (typically -1) suggests "low-latency mode" which disables response buffering completely and flushes immediately after each write to the client, and does not cancel the request to the backend even if the client disconnects early. This option is ignored and responses are flushed immediately to the client if one of the following applies from the response:
|
||||
- `Content-Type: text/event-stream`
|
||||
|
@ -335,6 +356,10 @@ By default, the proxy partially buffers the response for wire efficiency:
|
|||
|
||||
- **response_buffers** <span id="response_buffers"/> will cause the proxy to read up to `<size>` amount of bytes from the response body to be read into a buffer before being returned to the client. This should be avoided if at all possible for performance reasons, but could be useful if the backend has tighter memory constraints. This accepts all size formats supported by [go-humanize](https://github.com/dustin/go-humanize/blob/master/bytes.go).
|
||||
|
||||
- **stream_timeout** <span id="stream_timeout"/> is a [duration value](/docs/conventions#durations) after which streaming requests such as WebSockets will be forcibly closed atthe end of the timeout. This essentially cancels connections if they stay open too long. A reasonable starting point might be `24h` to cull connections older than a day. Default: no timeout.
|
||||
|
||||
- **stream_close_delay** <span id="stream_close_delay"/> is a [duration value](/docs/conventions#durations) which delays streaming requests such as WebSockets from being forcibly closed when the config is unloaded; instead, the stream will remain open until the delay is complete. In other words, enabling this prevents streams from immediately closing when Caddy's config is reloaded. Enabling this may be a good idea to avoid a thundering herd of reconnecting clients which had their connections closed by the previous config closing. A reasonable starting point might be something like `5m` to allow users 5 minutes to leave the page naturally after a config reload. Default: no delay.
|
||||
|
||||
|
||||
|
||||
### Headers
|
||||
|
@ -364,12 +389,18 @@ To delete a request header, preventing it from reaching the backend:
|
|||
header_up -Some-Header
|
||||
```
|
||||
|
||||
To delete all matching request, using a suffix match:
|
||||
To delete all matching request headers, using a suffix match:
|
||||
|
||||
```caddy-d
|
||||
header_up -Some-*
|
||||
```
|
||||
|
||||
To delete _all_ request headers, to be able to individually add the ones you want (not recommended):
|
||||
|
||||
```caddy-d
|
||||
header_up -*
|
||||
```
|
||||
|
||||
To perform a regular expression replacement on a request header:
|
||||
|
||||
```caddy-d
|
||||
|
@ -391,7 +422,7 @@ By default, Caddy passes thru incoming headers—including `Host`—to t
|
|||
|
||||
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` with a list of IP ranges (CIDRs) from which incoming requests are trusted to have sent good values for these headers.
|
||||
|
||||
It is recommended that you configure this via the [`servers > trusted_proxies` global option](/docs/caddyfile/options#trusted-proxies) so that this applies to all proxy handlers in your server, without repetition.
|
||||
It is strongly recommended that you configure this via the [`servers > trusted_proxies` global option](/docs/caddyfile/options#trusted-proxies) instead of in the proxy, so that this applies to all proxy handlers in your server, and this has the benefit of enabling client IP parsing.
|
||||
|
||||
<aside class="tip">
|
||||
|
||||
|
@ -446,6 +477,7 @@ transport http {
|
|||
read_buffer <size>
|
||||
write_buffer <size>
|
||||
max_response_header <size>
|
||||
proxy_protocol v1|v2
|
||||
dial_timeout <duration>
|
||||
dial_fallback_delay <duration>
|
||||
response_header_timeout <duration>
|
||||
|
@ -475,6 +507,8 @@ transport http {
|
|||
|
||||
- **max_response_header** <span id="max_response_header"/> is the maximum amount of bytes to read from response headers. It accepts all formats supported by [go-humanize](https://github.com/dustin/go-humanize/blob/master/bytes.go). Default: `10MiB`.
|
||||
|
||||
- **proxy_protocol** <span id="proxy_protocol"/> enables [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) (popularized by HAProxy) on the connection to the upstream, prepending the real client IP data. This is best paired with the [`servers > trusted_proxies` global option](/docs/caddyfile/options#trusted-proxies) if Caddy is behind another proxy. Versions `v1` and `v2` are supported. This should only be used if you know the upstream server is able to parse PROXY protocol. By default, this is disabled.
|
||||
|
||||
- **dial_timeout** <span id="dial_timeout"/> is the maximum [duration](/docs/conventions#durations) to wait when connecting to the upstream socket. Default: `3s`.
|
||||
|
||||
- **dial_fallback_delay** <span id="dial_fallback_delay"/> is the maximum [duration](/docs/conventions#durations) to wait before spawning an RFC 6555 Fast Fallback connection. A negative value disables this. Default: `300ms`.
|
||||
|
|
|
@ -12,6 +12,8 @@ It is based on [github.com/open-telemetry/opentelemetry-go](https://github.com/o
|
|||
|
||||
It uses [gRPC](https://github.com/grpc/) as an exporter protocol and W3C [tracecontext](https://www.w3.org/TR/trace-context/) and [baggage](https://www.w3.org/TR/baggage/) as propagators.
|
||||
|
||||
The trace ID is added to [access logs](/docs/caddyfile/directives/log) as the standard `traceID` field.
|
||||
|
||||
## Syntax
|
||||
|
||||
```caddy-d
|
||||
|
|
|
@ -39,6 +39,7 @@ $(function() {
|
|||
- [Path matchers](#path-matchers)
|
||||
- [Named matchers](#named-matchers)
|
||||
- [Standard matchers](#standard-matchers)
|
||||
- [client_ip](#client-ip)
|
||||
- [expression](#expression)
|
||||
- [file](#file)
|
||||
- [header](#header)
|
||||
|
@ -184,6 +185,41 @@ Full matcher documentation can be found [in each respective matcher module's doc
|
|||
|
||||
Requests can be matched the following ways:
|
||||
|
||||
|
||||
|
||||
### client_ip
|
||||
|
||||
```caddy-d
|
||||
client_ip <ranges...>
|
||||
|
||||
expression client_ip('<ranges...>')
|
||||
```
|
||||
|
||||
By the client IP address. Accepts exact IPs or CIDR ranges. IPv6 zones are supported.
|
||||
|
||||
This matcher is best used when the [`trusted_proxies`](/docs/caddyfile/options#trusted-proxies) global option is configured, otherwise it acts identically to the [`remote_ip`](#remote-ip) matcher. Only requests from trusted proxies will have their client IP parsed at the start of the request; untrusted requests will use the remote IP address of the immediate peer.
|
||||
|
||||
As a shortcut, `private_ranges` can be used to match all private IPv4 and IPv6 ranges. It's the same as specifying all of these ranges: `192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 127.0.0.1/8 fd00::/8 ::1`
|
||||
|
||||
There can be multiple `client_ip` matchers per named matcher, and their ranges will be merged and OR'ed together.
|
||||
|
||||
#### Example:
|
||||
|
||||
Match requests from private IPv4 addresses:
|
||||
|
||||
```caddy-d
|
||||
client_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 127.0.0.1/8
|
||||
```
|
||||
|
||||
This matcher is commonly paired with the [`not`](#not) matcher to invert the match. For example, to abort all connections from _public_ IPv4 and IPv6 addresses (which is the inverse of all private ranges):
|
||||
|
||||
```caddy-d
|
||||
@denied not client_ip private_ranges
|
||||
abort @denied
|
||||
```
|
||||
|
||||
|
||||
|
||||
### expression
|
||||
|
||||
```caddy-d
|
||||
|
@ -599,10 +635,12 @@ expression remote_ip('<ranges...>')
|
|||
expression 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. IPv6 zones are supported.
|
||||
By remote IP address (i.e. the IP address of the immediate peer). Accepts exact IPs or CIDR ranges. IPv6 zones are supported.
|
||||
|
||||
As a shortcut, `private_ranges` can be used to match all private IPv4 and IPv6 ranges. It's the same as specifying all of these ranges: `192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 127.0.0.1/8 fd00::/8 ::1`
|
||||
|
||||
⚠️ The `forwarded` option is deprecated, and will be removed in a future version. Its implementation is insecure. Use the [`client_ip`](#client-ip) matcher instead, which allows for securely matching the real client IP if parsed from an HTTP header. If enabled, 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.
|
||||
|
||||
There can be multiple `remote_ip` matchers per named matcher, and their ranges will be merged and OR'ed together.
|
||||
|
||||
#### Example:
|
||||
|
|
|
@ -76,6 +76,7 @@ Possible options are:
|
|||
auto_https off|disable_redirects|ignore_loaded_certs|disable_certs
|
||||
email <yours>
|
||||
default_sni <name>
|
||||
fallback_sni <name>
|
||||
local_certs
|
||||
skip_install_trust
|
||||
acme_ca <directory_url>
|
||||
|
@ -108,6 +109,7 @@ Possible options are:
|
|||
idle <duration>
|
||||
}
|
||||
trusted_proxies <module> ...
|
||||
client_ip_headers <headers...>
|
||||
metrics
|
||||
max_header_size <size>
|
||||
log_credentials
|
||||
|
@ -284,6 +286,10 @@ Your email address. Mainly used when creating an ACME account with your CA, and
|
|||
Sets a default TLS ServerName for when clients do not use SNI in their ClientHello.
|
||||
|
||||
|
||||
##### `fallback_sni`
|
||||
If configured, the fallback becomes the TLS ServerName in the ClientHello if the original ServerName doesn't match any certificates in the cache. The uses for this are very niche; typically if a client is a CDN and passes through the ServerName of the downstream handshake but can accept a certificate with the origin's hostname instead, then you would set this as your origin's hostname. Note that Caddy must be managing a certificate for this name. <i>⚠️ Experimental</i>
|
||||
|
||||
|
||||
##### `local_certs`
|
||||
Causes all certificates to be issued internally by default, rather than through a (public) ACME CA such as Let's Encrypt. This is useful in development environments.
|
||||
|
||||
|
@ -447,7 +453,7 @@ listener_wrappers {
|
|||
}
|
||||
```
|
||||
|
||||
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:
|
||||
Also included is the [`proxy_protocol`](/docs/json/apps/http/servers/listener_wrappers/proxy_protocol/) listener wrapper (prior to v2.7.0 it was only available via a plugin), which enables [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) parsing (popularized by HAProxy). This must be used _before_ the `tls` listener wrapper since it parses plaintext data at the start of the connection:
|
||||
|
||||
```caddy-d
|
||||
listener_wrappers {
|
||||
|
@ -476,10 +482,13 @@ listener_wrappers {
|
|||
|
||||
Allows configuring IP ranges (CIDRs) of proxy servers from which requests should be trusted. By default, no proxies are trusted.
|
||||
|
||||
On its own, this configuration will not do anything, but it can be used to signal to handlers or matchers in HTTP routes that the request is trusted. See the [`reverse_proxy`](/docs/caddyfile/directives/reverse_proxy#defaults) handler for example, which uses this to trust sensitive incoming `X-Forwarded-*` headers.
|
||||
Enabling this causes trusted requests to have the _real_ client IP parsed from HTTP headers (by default, `X-Forwarded-For`; see [`client_ip_headers`](#client-ip-headers) to configure other headers). If trusted, the client IP is added to [access logs](/docs/caddyfile/directives/log), is available as a `{client_ip}` [placeholder](/docs/caddyfile/concepts#placeholders), and allows the use of the [`client_ip` matcher](/docs/caddyfile/matchers#client-ip). If the request is not from a trusted proxy, then the client IP is set to the remote IP address of the direct incoming connection.
|
||||
|
||||
Some matchers or handlers may use the trust status of the request to make additional decisions. For example, if trusted, the [`reverse_proxy`](/docs/caddyfile/directives/reverse_proxy#defaults) handler will proxy and augment the sensitive `X-Forwarded-*` request headers.
|
||||
|
||||
Currently, only the `static` [IP source module](/docs/json/apps/http/servers/trusted_proxies/) is included with the standard distribution of Caddy, but this can be [extended](/docs/extending-caddy) with plugins to maintain a dynamic list of IP ranges.
|
||||
|
||||
|
||||
###### `static`
|
||||
|
||||
Takes a static (unchanging) list of IP ranges (CIDRs) to trust.
|
||||
|
@ -501,6 +510,11 @@ Here's a complete example, trusting an example IPv4 range and an IPv6 range:
|
|||
```
|
||||
|
||||
|
||||
##### `client_ip_headers`
|
||||
|
||||
Pairing with [`trusted_proxies`](#trusted-proxies), allows configuring which headers to use to determine the client's IP address. By default, only `X-Forwarded-For` is considered. Multiple header fields can be specified, in which case the first non-empty header value is used.
|
||||
|
||||
|
||||
|
||||
##### `metrics`
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue