knowledge/technology/applications/web/traefik.md

795 lines
24 KiB
Markdown
Raw Normal View History

2023-12-04 10:02:23 +00:00
---
obj: application
website: https://traefik.io
repo: https://github.com/traefik/traefik
---
# traefik
Traefik is an open-source Edge Router (Reverse Proxy) that makes publishing your services a fun and easy experience. It receives requests on behalf of your system and finds out which components are responsible for handling them.
Traefik is based on the concept of EntryPoints, Routers, Middlewares and Services.
- EntryPoints: EntryPoints are the network entry points into Traefik. They define the port which will receive the packets, and whether to listen for [TCP](../../internet/TCP.md) or [UDP](../../internet/UDP.md).
- Routers: A router is in charge of connecting incoming requests to the services that can handle them.
- Middlewares: Attached to the routers, middlewares can modify the requests or responses before they are sent to your service
- Services: Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests.
## Docker Compose
```yaml
version: "3"
services:
traefik:
image: traefik:v2.10.4
ports:
- 80:80
- 443:443
- 28080:8080
volumes:
- ./conf:/etc/traefik
- ./logs:/var/log/traefik/
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
```
## Configuration
Configuration is done via the file `traefik.yaml`.
### Entrypoints
You need to define some entrypoints which accept incoming traffik.
```yaml
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
```
### Routers
A router is in charge of connecting incoming requests to the services that can handle them. In the process, routers may use pieces of middleware to update the request, or act before forwarding the request to the service.
Routers can handle [HTTP](../../internet/HTTP.md), [TCP](../../internet/TCP.md) and [UDP](../../internet/UDP.md) traffik.
Example:
```yaml
http:
routers:
my-router:
rule: "Path(`/foo`)"
service: service-foo
```
#### Entrypoints
If not specified, [HTTP](../../internet/HTTP.md) routers will accept requests from all defined entry points. If you want to limit the router scope to a set of entry points, set the entryPoints option.
Listen only to specific entrypoints:
```yaml
http:
routers:
Router-1:
# won't listen to entry point web
entryPoints:
- "websecure"
- "other"
rule: "Host(`example.com`)"
service: "service-1"
```
#### Rules
Rules are a set of matchers configured with values, that determine if a particular request matches specific criteria. If the rule is verified, the router becomes active, calls middlewares, and then forwards the request to the service.
```yaml
http:
routers:
Router:
rule: "Host(`example.com`)"
```
The table below lists all the available matchers:
| Rule | Description |
| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Headers(\`key\`, \`value\`) | Check if there is a key `key` defined in the headers, with the value `value` |
| HeadersRegexp(\`key\`, \`regexp\`) | Check if there is a key `key` defined in the headers, with a value that matches the [regular expression](../../tools/Regex.md) `regexp` |
| Host(\`example.com\`, ...) | Check if the request [domain](../../internet/Domain.md) (host header value) targets one of the given `domains`. |
| HostRegexp(\`example.com\`, \`{subdomain:\[a-z]+}.example.com\`, ...) | Match the request [domain](../../internet/Domain.md) |
| Method(\`GET\`, ...) | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`) |
| Path(\`/path\`, \`/articles/{cat:\[a-z]+}/{id:\[0-9]+}\`, ...) | Match exact request path |
| PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`) | Match request prefix path |
| Query(\`foo=bar\`, \`bar=baz\`) | Match Query String parameters. It accepts a sequence of `key=value` pairs. |
| ClientIP(\`10.0.0.0/16\`, \`::1\`) | Match if the request client IP is one of the given IP/CIDR. It accepts IPv4, IPv6 and CIDR formats. |
#### Middlewares
You can attach a list of middlewares to each [HTTP](../../internet/HTTP.md) router. The middlewares will take effect only if the rule matches, and before forwarding the request to the service.
```yaml
http:
routers:
my-router:
rule: "Path(`/foo`)"
middlewares:
- authentication
service: service-foo
```
#### Service
Each request must eventually be handled by a service, which is why each router definition should include a service target, which is basically where the request will be passed along to.
In general, a service assigned to a router should have been defined, but there are exceptions for label-based providers.
2023-12-12 16:47:06 +00:00
#### TLS
2023-12-04 10:02:23 +00:00
When a TLS section is specified, it instructs Traefik that the current router is dedicated to HTTPS requests only (and that the router should ignore [HTTP](../../internet/HTTP.md) (non TLS) requests). Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services).
```yaml
http:
routers:
Router-1:
rule: "Host(`foo-domain`) && Path(`/foo-path/`)"
service: service-id
# will terminate the TLS request
tls: {}
```
- `certResolver`
If `certResolver` is defined, Traefik will try to generate certificates based on routers `Host` & `HostSNI` rules.
```yaml
http:
routers:
routerfoo:
rule: "Host(`snitest.com`) && Path(`/foo`)"
tls:
certResolver: foo
```
- `domains`
You can set SANs (alternative domains) for each main [domain](../../internet/Domain.md). Every [domain](../../internet/Domain.md) must have A/AAAA records pointing to Traefik. Each [domain](../../internet/Domain.md) & SAN will lead to a certificate request.
```yaml
http:
routers:
routerbar:
rule: "Host(`snitest.com`) && Path(`/bar`)"
tls:
certResolver: "bar"
domains:
- main: "snitest.com"
sans:
- "*.snitest.com"
```
### Services
The Services are responsible for configuring how to reach the actual services that will eventually handle the incoming requests.
Example:
```yaml
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://<private-ip-server-1>:<private-port-server-1>/"
- url: "http://<private-ip-server-2>:<private-port-server-2>/"
tcp:
services:
my-service:
loadBalancer:
servers:
- address: "<private-ip-server-1>:<private-port-server-1>"
- address: "<private-ip-server-2>:<private-port-server-2>"
```
#### Load Balancing
Traefik can load balance across multiple servers with the `loadBalancer.servers` list.
```yaml
http:
services:
my-service:
loadBalancer:
servers:
- url: "http://server1:8080"
- url: "http://server2:8080
```
#### Servers Transport
`serversTransport` allows to reference a ServersTransport configuration for the communication between Traefik and your servers.
```yaml
http:
services:
Service01:
loadBalancer:
serversTransport: mytransport
```
Define a serverTransport configuration:
```yaml
http:
serversTransports:
mytransport:
```
You can define root CAs used for verifying SSL between traefik and your servers:
```yaml
http:
serversTransports:
mytransport:
rootCAs:
- foo.crt
- bar.crt
```
Or skip SSL verification:
```yaml
http:
serversTransports:
mytransport:
insecureSkipVerify: true
```
### TLS
Traefik supports HTTPS & TLS, which concerns roughly two parts of the configuration: routers, and the TLS connection (and its underlying certificates).
Traefik requires you to define "Certificate Resolvers" in the static configuration, which are responsible for retrieving certificates from an ACME server.
```yaml
certificatesResolvers:
myresolver:
# Enable ACME (Let's Encrypt): automatic SSL.
acme:
email: "test@example.com"
# File or key used for certificates storage.
storage: "acme.json"
# The certificates' duration in hours.
# It defaults to 2160 (90 days) to follow Let's Encrypt certificates' duration.
#
# Optional
# Default: 2160
#
certificatesDuration: 2160
# Use a TLS-ALPN-01 ACME challenge.
#
# Optional (but recommended)
#
tlsChallenge:
# Use a HTTP-01 ACME challenge.
#
# Optional
#
httpChallenge:
# EntryPoint to use for the HTTP-01 challenges.
#
# Required
#
entryPoint: web
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
# Note: mandatory for wildcard certificate generation.
#
# Optional
#
dnsChallenge:
# DNS provider used.
#
# Required
#
provider: digitalocean
# By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
# If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
# Useful if internal networks block external DNS queries.
#
# Optional
# Default: 0
#
delayBeforeCheck: 0
# Use following DNS servers to resolve the FQDN authority.
#
# Optional
# Default: empty
#
resolvers
- "1.1.1.1:53"
- "8.8.8.8:53"
```
### Middlewares
Attached to the routers, pieces of middleware are a means of tweaking the requests before they are sent to your service (or before the answer from the services are sent to the clients).
```yaml
http:
routers:
router1:
service: myService
middlewares:
- "foo-add-prefix"
rule: "Host(`example.com`)"
middlewares:
foo-add-prefix:
addPrefix:
prefix: "/foo"
services:
service1:
loadBalancer:
servers:
- url: "http://127.0.0.1:80"
```
#### [HTTP](../../internet/HTTP.md) Middlewares
##### Add Prefix
The AddPrefix middleware updates the path of a request before forwarding it. So `http://domain/path` would be `http://domain/prefix/path` if used.
```yaml
http:
middlewares:
add-foo:
addPrefix:
prefix: "/prefix"
```
##### BasicAuth
The BasicAuth middleware grants access to services to authorized users only.
- `users`
The `users` option is an array of authorized users. Each user must be declared using the name:hashed-password format.
```yaml
http:
middlewares:
test-auth:
basicAuth:
users:
- "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
- "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
```
- `usersFile`
The `usersFile` option is the path to an external file that contains the authorized users for the middleware.
```yaml
http:
middlewares:
test-auth:
basicAuth:
usersFile: "/path/to/my/usersfile"
```
- `headerField`
You can define a header field to store the authenticated user using the `headerFieldoption`.
```yaml
http:
middlewares:
my-auth:
basicAuth:
# ...
headerField: "X-WebAuth-User"
```
- `removeHeader`
Set the `removeHeader` option to `true` to remove the authorization header before forwarding the request to your service. (Default value is `false`.)
##### Compress
Compress Responses before Sending them to the Client. The Compress middleware uses gzip compression.
- `excludedContentTypes` specifies a list of content types to compare the Content-Type header of the incoming requests and responses before compressing. The responses with content types defined in `excludedContentTypes` are not compressed.
- `minResponseBodyBytes` specifies the minimum amount of bytes a response body must have to be compressed. The default value is 1024, which should be a reasonable value for most cases.
```yaml
http:
middlewares:
test-compress:
compress:
excludedContentTypes:
- text/event-stream
minResponseBodyBytes: 1200
```
##### ContentType
The Content-Type middleware - or rather its `autoDetect` option - specifies whether to let the Content-Type header, if it has not been defined by the backend, be automatically set to a value derived from the contents of the response.
```yaml
http:
middlewares:
autodetect:
contentType:
autoDetect: true
```
##### DigestAuth
Adding Digest Authentication. The configuration options are the same as BasicAuth middleware.
```yaml
http:
middlewares:
test-auth:
digestAuth:
users:
- "test:traefik:a2688e031edb4be6a3797f3882655c05"
- "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
```
##### Errors
The Errors middleware returns a custom page in lieu of the default, according to configured ranges of [HTTP](../../internet/HTTP.md) Status codes.
```yaml
http:
middlewares:
test-errors:
errors:
status:
- "500"
- "501"
- "503"
- "505-599"
service: serviceError
query: "/{status}.html"
```
- `status`
The status option defines which status or range of statuses should result in an error page.
The status code ranges are inclusive (`505-599` will trigger with every code between `505` and `599`, `505` and `599` included).
- `service`
The service that will serve the new requested error page.
- `query`
The [URL](../../internet/URL.md) for the error page (hosted by `service`).
There are multiple variables that can be placed in the query option to insert values in the [URL](../../internet/URL.md).
The table below lists all the available variables and their associated values.
| Variable | Value |
| ---------- | ------------------------- |
| `{status}` | The response status code. |
| `{url}` | The escaped request [URL](../../internet/URL.md). |
##### ForwardAuth
The ForwardAuth middleware delegates authentication to an external service. If the service answers with a 2XX code, access is granted, and the original request is performed. Otherwise, the response from the authentication server is returned.
```yaml
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
```
###### Forward-Request Headers
The following request properties are provided to the forward-auth target endpoint as X-Forwarded- headers:
| Property | Forward-Request Header |
| ----------------- | ---------------------- |
| [HTTP](../../internet/HTTP.md) Method | `X-Forwarded-Method` |
| Protocol | `X-Forwarded-Proto` |
| Host | `X-Forwarded-Host` |
| Request URI | `X-Forwarded-Uri` |
| Source IP-Address | `X-Forwarded-For` |
- `address`:
The `address` option defines the authentication server address.
```yaml
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
```
- `trustForwardHeader`
Set the `trustForwardHeader` option to `true` to trust all `X-Forwarded-*` headers.
```yaml
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
trustForwardHeader: true
```
- `authResponseHeaders`
The `authResponseHeaders` option is the list of headers to copy from the authentication server response and set on forwarded request, replacing any existing conflicting headers.
```yaml
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
authResponseHeaders:
- "X-Auth-User"
- "X-Secret"
```
- `authResponseHeadersRegex`
The `authResponseHeadersRegex` option is the [regex](../../tools/Regex.md) to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the [regex](../../tools/Regex.md).
```yaml
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
authResponseHeadersRegex: "^X-"
```
- `authRequestHeaders`
The `authRequestHeaders` option is the list of the headers to copy from the request to the authentication server. It allows filtering headers that should not be passed to the authentication server. If not set or empty then all request headers are passed.
```yaml
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
authRequestHeaders:
- "Accept"
- "X-CustomHeader"
```
- `tls`
Defines the TLS configuration used for the secure connection to the authentication server.
```yaml
http:
middlewares:
test-auth:
forwardAuth:
address: "https://example.com/auth"
tls:
# CA used for SSL
ca: "path/to/local.crt"
# Skip SSL
insecureSkipVerify: true
```
##### Headers
Managing Request/Response headers
```yaml
http:
middlewares:
testHeader:
headers:
customRequestHeaders:
X-Script-Name: "test"
customResponseHeaders:
X-Custom-Response-Header: "value"
```
- Add/Remove Headers
```yaml
http:
middlewares:
testHeader:
headers:
customRequestHeaders:
X-Script-Name: "test" # Adds
X-Custom-Request-Header: "" # Removes
customResponseHeaders:
X-Custom-Response-Header: "" # Removes
```
- CORS Headers
```yaml
http:
middlewares:
testHeader:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlAllowHeaders: "*"
accessControlAllowOriginList:
- https://foo.bar.org
- https://example.org
accessControlMaxAge: 100
addVaryHeader: true
```
##### IPWhiteList
Limiting Clients to Specific IPs
IPWhitelist accepts / refuses requests based on the client IP.
```yaml
http:
middlewares:
test-ipwhitelist:
ipWhiteList:
sourceRange:
- "127.0.0.1/32"
- "192.168.1.7"
```
##### Ratelimit
The RateLimit middleware ensures that services will receive a fair amount of requests, and allows one to define what fair is.
It is based on a token bucket implementation. In this analogy, the average parameter (defined below) is the rate at which the bucket refills, and the burst is the size (volume) of the bucket.
```yaml
http:
middlewares:
test-ratelimit:
rateLimit:
average: 100
burst: 50
```
- `average`
`average` is the maximum rate, by default in requests per second, allowed from a given source.
It defaults to `0`, which means no rate limiting.
The rate is actually defined by dividing `average` by `period`.
- `period`
`period`, in combination with `average`, defines the actual maximum rate.
It defaults to `1` second.
- `burst`
`burst` is the maximum number of requests allowed to go through in the same arbitrarily small period of time. It defaults to `1`.
You can exclude IPs from rate limiting:
```yaml
http:
middlewares:
test-ratelimit:
rateLimit:
sourceCriterion:
ipStrategy:
excludedIPs:
- "127.0.0.1/32"
- "192.168.1.7"
```
##### RedirectScheme
The RedirectScheme middleware redirects the request if the request scheme is different from the configured scheme.
```yaml
http:
middlewares:
test-redirectscheme:
redirectScheme:
scheme: https
permanent: true
```
##### RedirectRegex
The RedirectRegex redirects a request using [regex](../../tools/Regex.md) matching and replacement.
```yaml
http:
middlewares:
test-redirectregex:
redirectRegex:
regex: "^http://localhost/(.*)"
replacement: "http://mydomain/${1}"
```
##### ReplacePath
The ReplacePath middleware will:
- replace the actual path with the specified one.
- store the original path in a `X-Replaced-Path` header.
```yaml
http:
middlewares:
test-replacepath:
replacePath:
path: "/foo"
```
##### ReplacePathRegex
The ReplacePathRegex middleware will:
- replace the matching path with the specified one.
- store the original path in a `X-Replaced-Path` header.
```yaml
http:
middlewares:
test-replacepathregex:
replacePathRegex:
regex: "^/foo/(.*)"
replacement: "/bar/$1"
```
##### Retry
The Retry middleware reissues requests a given number of times to a backend server if that server does not reply. As soon as the server answers, the middleware stops retrying, regardless of the response status. The Retry middleware has an optional configuration to enable an exponential backoff.
```yaml
http:
middlewares:
test-retry:
retry:
attempts: 4
initialInterval: 100ms
```
##### StripPrefix
Remove the specified prefixes from the [URL](../../internet/URL.md) path.
```yaml
http:
middlewares:
test-stripprefix:
stripPrefix:
prefixes:
- "/foobar"
- "/fiibar"
```
##### StripPrefixRegex
Remove the matching prefixes from the [URL](../../internet/URL.md) path.
```yaml
http:
middlewares:
test-stripprefixregex:
stripPrefixRegex:
regex:
- "/foo/[a-z0-9]+/[0-9]+/"
```
### Access log
Access logs allow you to keep track of what request are made to your server.
To enable the access logs:
```yaml
accessLog: {}
```
- `filePath`:
2024-02-12 20:55:34 +00:00
By default access logs are written to the standard output. To write the logs into a [log file](../../dev/Log.md), use the `filePath` option.
2023-12-04 10:02:23 +00:00
```yaml
accessLog:
filePath: "/path/to/access.log"
```
- `format`:
By default, logs are written using the Common Log Format (CLF). To write logs in [JSON](../../files/JSON.md), use `json` in the `format` option. If the given format is unsupported, the default (CLF) is used instead.
> Common Log Format
> ```
><remote_IP_address> - <client_user_name_if_available> [<timestamp>] "<request_method> <request_path> <request_protocol>" <HTTP_status> <content-length> "<request_referrer>" "<request_user_agent>" <number_of_requests_received_since_Traefik_started> "<Traefik_router_name>" "<Traefik_server_URL>" <request_duration_in_ms>m
>```
- `bufferingSize`
To write the logs in an asynchronous fashion, specify a `bufferingSize` option. This option represents the number of log lines Traefik will keep in memory before writing them to the selected output. In some cases, this option can greatly help performances.
```yaml
# Configuring a buffer of 100 lines
accessLog:
filePath: "/path/to/access.log"
bufferingSize: 100
```
#### Filtering
To filter logs, you can specify a set of filters which are logically "OR-connected". Thus, specifying multiple filters will keep more access logs than specifying only one.
The available filters are:
- `statusCodes`, to limit the access logs to requests with a status codes in the specified range
- `retryAttempts`, to keep the access logs when at least one retry has happened
- `minDuration`, to keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format)
```yaml
# Configuring Multiple Filters
accessLog:
filePath: "/path/to/access.log"
format: json
filters:
statusCodes:
- "200"
- "300-302"
retryAttempts: true
minDuration: "10ms"
```
##### Limiting the Fields/Including Headers
You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.headers` options.
Each field can be set to:
- `keep` to keep the value
- `drop` to drop the value
- `redact` to replace the value with "redacted"
The `defaultMode` for `fields.names` is `keep`.
The `defaultMode` for `fields.headers` is `drop`.
```yaml
# Limiting the Logs to Specific Fields
accessLog:
filePath: "/path/to/access.log"
format: json
fields:
defaultMode: keep
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
User-Agent: redact
Authorization: drop
Content-Type: keep
```