Add a new protocol
Co-authored-by: Gérald Croës <gerald@containo.us>
This commit is contained in:
parent
0ca2149408
commit
4a68d29ce2
231 changed files with 6895 additions and 4395 deletions
|
@ -1,338 +0,0 @@
|
|||
# ACME
|
||||
|
||||
Automatic HTTPS
|
||||
{: .subtitle }
|
||||
|
||||
Traefik can automatically generate certificates for your domains using an ACME provider (like Let's Encrypt).
|
||||
|
||||
!!! warning "Let's Encrypt and Rate Limiting"
|
||||
Note that Let's Encrypt has [rate limiting](https://letsencrypt.org/docs/rate-limits).
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "Configuring ACME on the Https EntryPoint"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.http-tls]
|
||||
address = ":443"
|
||||
[entryPoints.http-tls.tls] # enabling TLS
|
||||
|
||||
[acme]
|
||||
email = "your-email@your-domain.org"
|
||||
storage = "acme.json"
|
||||
entryPoint = "http-tls" # acme is enabled on http-tls
|
||||
onHostRule = true # dynamic generation based on the Host() matcher
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "web" # used during the challenge
|
||||
```
|
||||
|
||||
??? example "Configuring Wildcard Certificates"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.http-tls]
|
||||
address = ":443"
|
||||
[entryPoints.https.tls] # enabling TLS
|
||||
|
||||
[acme]
|
||||
email = "your-email@your-domain.org"
|
||||
storage = "acme.json"
|
||||
entryPoint = "http-tls" # acme is enabled on http-tls
|
||||
[acme.dnsChallenge]
|
||||
provider = "xxx"
|
||||
|
||||
[[acme.domains]]
|
||||
main = "*.mydomain.com"
|
||||
sans = ["mydomain.com"]
|
||||
```
|
||||
|
||||
!!! note "Configuration Reference"
|
||||
|
||||
There are many available options for ACME. For a quick glance at what's possible, browse the [configuration reference](../reference/acme.md).
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### The Different ACME Challenges
|
||||
|
||||
#### tlsChallenge
|
||||
|
||||
Use the `TLS-ALPN-01` challenge to generate and renew ACME certificates by provisioning a TLS certificate.
|
||||
|
||||
??? example "Using an EntryPoint Called https for the `tlsChallenge`"
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
entryPoint = "https"
|
||||
[acme.tlsChallenge]
|
||||
```
|
||||
|
||||
!!! note
|
||||
As described on the Let's Encrypt [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72), when using the `TLS-ALPN-01` challenge, `acme.entryPoint` must be reachable by Let's Encrypt through port 443.
|
||||
|
||||
#### `httpChallenge`
|
||||
|
||||
Use the `HTTP-01` challenge to generate and renew ACME certificates by provisioning an HTTP resource under a well-known URI.
|
||||
|
||||
??? example "Using an EntryPoint Called http for the `httpChallenge`"
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
entryPoint = "https"
|
||||
[acme.httpChallenge]
|
||||
entryPoint = "http"
|
||||
```
|
||||
|
||||
!!! note
|
||||
As described on the Let's Encrypt [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72), when using the `HTTP-01` challenge, `acme.httpChallenge.entryPoint` must be reachable by Let's Encrypt through port 80.
|
||||
|
||||
!!! note
|
||||
Redirection is fully compatible with the `HTTP-01` challenge.
|
||||
|
||||
#### `dnsChallenge`
|
||||
|
||||
Use the `DNS-01` challenge to generate and renew ACME certificates by provisioning a DNS record.
|
||||
|
||||
??? example "Configuring a `dnsChallenge` with the digitalocean Provider"
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
[acme.dnsChallenge]
|
||||
provider = "digitalocean"
|
||||
delayBeforeCheck = 0
|
||||
# ...
|
||||
```
|
||||
|
||||
!!! important
|
||||
A `provider` is mandatory.
|
||||
|
||||
??? list "Supported Providers"
|
||||
|
||||
Here is a list of supported `providers`, that can automate the DNS verification, along with the required environment variables and their [wildcard & root domain support](#wildcard-domains).
|
||||
Do not hesitate to complete it.
|
||||
|
||||
| Provider Name | Provider Code | Environment Variables | Wildcard & Root Domain Support |
|
||||
|-------------------------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
|
||||
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | Not tested yet |
|
||||
| [Alibaba Cloud](https://www.vultr.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | Not tested yet |
|
||||
| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | Not tested yet |
|
||||
| [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | Not tested yet |
|
||||
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | Not tested yet |
|
||||
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | YES |
|
||||
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | Not tested yet |
|
||||
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | YES |
|
||||
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | YES |
|
||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | YES |
|
||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | Not tested yet |
|
||||
| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | Not tested yet |
|
||||
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | YES |
|
||||
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | YES |
|
||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | Not tested yet |
|
||||
| External Program | `exec` | `EXEC_PATH` | YES |
|
||||
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | YES |
|
||||
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | YES |
|
||||
| [Gandi](https://www.gandi.net) | `gandi` | `GANDI_API_KEY` | Not tested yet |
|
||||
| [Gandi v5](http://doc.livedns.gandi.net) | `gandiv5` | `GANDIV5_API_KEY` | YES |
|
||||
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | Not tested yet |
|
||||
| [GoDaddy](https://godaddy.com/domains) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | Not tested yet |
|
||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials (2) (3), [`GCE_SERVICE_ACCOUNT_FILE`] | YES |
|
||||
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | Not tested yet |
|
||||
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` (1) | YES |
|
||||
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | Not tested yet |
|
||||
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | YES |
|
||||
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | Not tested yet |
|
||||
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | Not tested yet |
|
||||
| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | Not tested yet |
|
||||
| manual | - | none, but you need to run Traefik interactively, turn on `acmeLogging` to see instructions and press <kbd>Enter</kbd>. | YES |
|
||||
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | YES |
|
||||
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | YES |
|
||||
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | Not tested yet |
|
||||
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | Not tested yet |
|
||||
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | Not tested yet |
|
||||
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | Not tested yet |
|
||||
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | Not tested yet |
|
||||
| [OVH](https://www.ovh.com) | `ovh` | `OVH_ENDPOINT`, `OVH_APPLICATION_KEY`, `OVH_APPLICATION_SECRET`, `OVH_CONSUMER_KEY` | YES |
|
||||
| [Openstack Designate](https://docs.openstack.org/designate) | `designate` | `OS_AUTH_URL`, `OS_USERNAME`, `OS_PASSWORD`, `OS_TENANT_NAME`, `OS_REGION_NAME` | YES |
|
||||
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | Not tested yet |
|
||||
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | Not tested yet |
|
||||
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | Not tested yet |
|
||||
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | YES |
|
||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | Not tested yet |
|
||||
| [Selectel](https://selectel.ru/en/) | `selectel` | `SELECTEL_API_TOKEN` | YES |
|
||||
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | Not tested yet |
|
||||
| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | YES |
|
||||
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | Not tested yet |
|
||||
| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | YES |
|
||||
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | Not tested yet |
|
||||
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | YES |
|
||||
|
||||
- (1): more information about the HTTP message format can be found [here](https://go-acme.github.io/lego/dns/httpreq/)
|
||||
- (2): https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application
|
||||
- (3): https://github.com/golang/oauth2/blob/36a7019397c4c86cf59eeab3bc0d188bac444277/google/default.go#L61-L76
|
||||
|
||||
!!! note "`delayBeforeCheck`"
|
||||
By default, the `provider` verifies the TXT record _before_ letting ACME verify.
|
||||
You can delay this operation by specifying a delay (in seconds) with `delayBeforeCheck` (value must be greater than zero).
|
||||
This option is useful when internal networks block external DNS queries.
|
||||
|
||||
!!! note "`resolvers`"
|
||||
|
||||
Use custom DNS servers to resolve the FQDN authority.
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
[acme.dnsChallenge]
|
||||
# ...
|
||||
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
|
||||
```
|
||||
|
||||
### Known Domains, SANs, and Wildcards
|
||||
|
||||
You can set SANs (alternative domains) for each main domain.
|
||||
Every domain must have A/AAAA records pointing to Traefik.
|
||||
Each domain & SAN will lead to a certificate request.
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
[[acme.domains]]
|
||||
main = "local1.com"
|
||||
sans = ["test1.local1.com", "test2.local1.com"]
|
||||
[[acme.domains]]
|
||||
main = "local2.com"
|
||||
[[acme.domains]]
|
||||
main = "*.local3.com"
|
||||
sans = ["local3.com", "test1.test1.local3.com"]
|
||||
# ...
|
||||
```
|
||||
|
||||
!!! important
|
||||
The certificates for the domains listed in `acme.domains` are negotiated at Traefik startup only.
|
||||
|
||||
!!! note
|
||||
Wildcard certificates can only be verified through a `DNS-01` challenge.
|
||||
|
||||
#### Wildcard Domains
|
||||
|
||||
[ACME V2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates.
|
||||
As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/staging-endpoint-for-acme-v2/49605) wildcard certificates can only be generated through a [`DNS-01` challenge](#dnschallenge).
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
[[acme.domains]]
|
||||
main = "*.local1.com"
|
||||
sans = ["local1.com"]
|
||||
# ...
|
||||
```
|
||||
|
||||
!!! warning
|
||||
Take note that Let's Encrypt applies [rate limiting](https://letsencrypt.org/docs/rate-limits).
|
||||
|
||||
!!! note "Double Wildcard Certificates"
|
||||
It is not possible to request a double wildcard certificate for a domain (for example `*.*.local.com`).
|
||||
|
||||
Due to an ACME limitation it is not possible to define wildcards in SANs (alternative domains).
|
||||
Thus, the wildcard domain has to be defined as a main domain.
|
||||
Most likely the root domain should receive a certificate too, so it needs to be specified as SAN and 2 `DNS-01` challenges are executed.
|
||||
In this case the generated DNS TXT record for both domains is the same.
|
||||
Even though this behavior is [DNS RFC](https://community.letsencrypt.org/t/wildcard-issuance-two-txt-records-for-the-same-name/54528/2) compliant, it can lead to problems as all DNS providers keep DNS records cached for a given time (TTL) and this TTL can be greater than the challenge timeout making the `DNS-01` challenge fail.
|
||||
The Traefik ACME client library [LEGO](https://github.com/go-acme/lego) supports some but not all DNS providers to work around this issue.
|
||||
The [Supported `provider` table](#dnschallenge) indicates if they allow generating certificates for a wildcard domain and its root domain.
|
||||
|
||||
### caServer
|
||||
|
||||
??? example "Using the Let's Encrypt staging server"
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
# ...
|
||||
```
|
||||
|
||||
### onHostRule
|
||||
|
||||
Enable certificate generation on [routers](routers.md) `Host` rules (for routers active on the `acme.entryPoint`).
|
||||
|
||||
This will request a certificate from Let's Encrypt for each router with a Host rule.
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
onHostRule = true
|
||||
# ...
|
||||
```
|
||||
|
||||
!!! note "Multiple Hosts in a Rule"
|
||||
The rule `Host(test1.traefik.io,test2.traefik.io)` will request a certificate with the main domain `test1.traefik.io` and SAN `test2.traefik.io`.
|
||||
|
||||
!!! warning
|
||||
`onHostRule` option can not be used to generate wildcard certificates. Refer to [wildcard generation](#wildcard-domains) for further information.
|
||||
|
||||
### `storage`
|
||||
|
||||
The `storage` option sets the location where your ACME certificates are saved to.
|
||||
|
||||
```toml
|
||||
[acme]
|
||||
# ...
|
||||
storage = "acme.json"
|
||||
# ...
|
||||
```
|
||||
|
||||
The value can refer to two kinds of storage:
|
||||
|
||||
- a JSON file
|
||||
- a KV store entry
|
||||
|
||||
#### In a File
|
||||
|
||||
ACME certificates can be stored in a JSON file that needs to have a `600` file mode .
|
||||
|
||||
In Docker you can mount either the JSON file, or the folder containing it:
|
||||
|
||||
```bash
|
||||
docker run -v "/my/host/acme.json:acme.json" traefik
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run -v "/my/host/acme:/etc/traefik/acme" traefik
|
||||
```
|
||||
|
||||
!!! warning
|
||||
For concurrency reason, this file cannot be shared across multiple instances of Traefik. Use a key value store entry instead.
|
||||
|
||||
#### In a a Key Value Store Entry
|
||||
|
||||
ACME certificates can be stored in a key-value store entry.
|
||||
|
||||
```toml
|
||||
storage = "traefik/acme/account"
|
||||
```
|
||||
|
||||
!!! note "Storage Size"
|
||||
|
||||
Because key-value stores have limited entry size, the certificates list is compressed _before_ it is saved.
|
||||
For example, it is possible to store up to _approximately_ 100 ACME certificates in Consul.
|
||||
|
||||
## Fallbacks
|
||||
|
||||
If Let's Encrypt is not reachable, the following certificates will apply:
|
||||
|
||||
1. Previously generated ACME certificates (before downtime)
|
||||
1. Expired ACME certificates
|
||||
1. Provided certificates
|
||||
|
||||
!!! note
|
||||
For new (sub)domains which need Let's Encrypt authentification, the default Traefik certificate will be used until Traefik is restarted.
|
|
@ -6,76 +6,39 @@ Opening Connections for Incomming Requests
|
|||

|
||||
|
||||
Entrypoints are the network entry points into Traefik.
|
||||
They can be defined using:
|
||||
|
||||
- a port (80, 443, ...)
|
||||
- SSL (Certificates, Keys, authentication with a client certificate signed by a trusted CA, ...)
|
||||
They define the port which will receive the requests (whether HTTP or TCP).
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "HTTP only"
|
||||
??? example "Port 80 only"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":80"
|
||||
```
|
||||
|
||||
We define an `entrypoint` called `http` that will listen on port `80`.
|
||||
We define an `entrypoint` called `web` that will listen on port `80`.
|
||||
|
||||
??? example "HTTP & HTTPS"
|
||||
??? example "Port 80 & 443"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.https]
|
||||
[entrypoints.web-secure]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.https.tls]
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
[entrypoints.web-secure.tls]
|
||||
[[entrypoints.web-secure.tls.certificates]]
|
||||
certFile = "tests/traefik.crt"
|
||||
keyFile = "tests/traefik.key"
|
||||
```
|
||||
|
||||
- Two entrypoints are defined: one called `http`, and the other called `https`.
|
||||
- `http` listens on port `80`, and `https` on port `443`.
|
||||
- We enabled SSL on `https` by giving it a certificate and a key.
|
||||
|
||||
!!! note
|
||||
- Two entrypoints are defined: one called `web`, and the other called `web-secure`.
|
||||
- `web` listens on port `80`, and `web-secure` on port `443`.
|
||||
|
||||
In the example, `http` and `https` are the names for the entrypoints and have nothing to do with the underlying protocol.
|
||||
We could have written `entryPoints.foo` and `entryPoints.bar` instead.
|
||||
|
||||
!!! tip "Automatic HTTPS with ACME"
|
||||
|
||||
If you don't have certificate files and wish to automatically enable HTTPS, you should have a look at one of Traefik's most praised feature: [ACME & Let's Encrypt integration](./acme.md)
|
||||
|
||||
??? example "Client Certificate Authentication"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.https.tls]
|
||||
[entryPoints.https.tls.ClientCA]
|
||||
files = ["tests/clientca1.crt", "tests/clientca2.crt"]
|
||||
optional = false
|
||||
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "tests/traefik.crt"
|
||||
keyFile = "tests/traefik.key"
|
||||
```
|
||||
|
||||
- We enabled SSL on `https` by giving it a certificate and a key.
|
||||
- Files containing Certificate Authorities (PEM format) were added.
|
||||
|
||||
!!! note "Multiple CAs"
|
||||
|
||||
It is possible to have multiple CA:s in the same file or keep them in separate files.
|
||||
|
||||
## Configuration
|
||||
|
||||
### General
|
||||
|
@ -115,130 +78,6 @@ Entrypoints are part of the [static configuration](../getting-started/configurat
|
|||
command: --defaultentrypoints=powpow --entryPoints='Name:powpow Address::42 Compress:true'
|
||||
```
|
||||
|
||||
## TLS
|
||||
|
||||
### Static Certificates
|
||||
|
||||
To add SNI support, define `certFile` and `keyFile`.
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.https.tls]
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "integration/fixtures/https/snitest.com.cert"
|
||||
keyFile = "integration/fixtures/https/snitest.com.key"
|
||||
```
|
||||
|
||||
!!! note
|
||||
If you provide an empty TLS configuration, default self-signed certificates will be generated.
|
||||
|
||||
### Dynamic Certificates
|
||||
|
||||
To add / remove TLS certificates while Traefik is running, the [file provider](../providers/file.md) supports Dynamic TLS certificates in its `[[tls]]` section.
|
||||
|
||||
### Mutual Authentication
|
||||
|
||||
Traefik supports both optional and non optional (defaut value) mutual authentication.
|
||||
|
||||
- When `optional = false`, Traefik accepts connections only from client presenting a certificate signed by a CA listed in `ClientCA.files`.
|
||||
- When `optional = true`, Traefik authorizes connections from client presenting a certificate signed by an unknown CA.
|
||||
|
||||
??? example "Non Optional Mutual Authentication"
|
||||
|
||||
In the following example, both `snitest.com` and `snitest.org` will require client certificates.
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.https.tls]
|
||||
[entryPoints.https.tls.ClientCA]
|
||||
files = ["tests/clientca1.crt", "tests/clientca2.crt"]
|
||||
optional = false
|
||||
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "integration/fixtures/https/snitest.com.cert"
|
||||
keyFile = "integration/fixtures/https/snitest.com.key"
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "integration/fixtures/https/snitest.org.cert"
|
||||
keyFile = "integration/fixtures/https/snitest.org.key"
|
||||
```
|
||||
|
||||
!!! note "ClientCA.files"
|
||||
|
||||
You can use a file per `CA:s`, or a single file containing multiple `CA:s` (in `PEM` format).
|
||||
|
||||
`ClientCA.files` is not optional: every client will have to present a valid certificate. (This requirement will apply to every server certificate declared in the entrypoint.)
|
||||
|
||||
### Minimum TLS Version
|
||||
|
||||
??? example "Min TLS version & [cipherSuites](https://godoc.org/crypto/tls#pkg-constants)"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.https.tls]
|
||||
minVersion = "VersionTLS12"
|
||||
cipherSuites = [
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_RSA_WITH_AES_256_GCM_SHA384"
|
||||
]
|
||||
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "integration/fixtures/https/snitest.com.cert"
|
||||
keyFile = "integration/fixtures/https/snitest.com.key"
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "integration/fixtures/https/snitest.org.cert"
|
||||
keyFile = "integration/fixtures/https/snitest.org.key"
|
||||
```
|
||||
|
||||
### Strict SNI Checking
|
||||
|
||||
With strict SNI checking, Traefik won't allow connections without a matching certificate.
|
||||
|
||||
??? example "Strict SNI"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.https.tls]
|
||||
sniStrict = true
|
||||
|
||||
[[entryPoints.https.tls.certificates]]
|
||||
certFile = "integration/fixtures/https/snitest.com.cert"
|
||||
keyFile = "integration/fixtures/https/snitest.com.key"
|
||||
```
|
||||
|
||||
### Default Certificate
|
||||
|
||||
Traefik can use a default certificate for connections without an SNI, or without a matching domain.
|
||||
|
||||
If no default certificate is provided, Traefik generates a self-signed and use it instead.
|
||||
|
||||
??? example "Setting a Default Certificate"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.https]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.https.tls]
|
||||
[entryPoints.https.tls.defaultCertificate]
|
||||
certFile = "integration/fixtures/https/snitest.com.cert"
|
||||
keyFile = "integration/fixtures/https/snitest.com.key"
|
||||
```
|
||||
|
||||
!!! note "Only One Default Certificate"
|
||||
There can only be one `defaultCertificate` per entrypoint.
|
||||
|
||||
## ProxyProtocol
|
||||
|
||||
Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt).
|
||||
|
@ -246,11 +85,11 @@ Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy-
|
|||
??? example "Enabling Proxy Protocol with Trusted IPs"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.http.proxyProtocol]
|
||||
[entrypoints.web.proxyProtocol]
|
||||
trustedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
||||
|
@ -261,11 +100,11 @@ Traefik supports [ProxyProtocol](https://www.haproxy.org/download/1.8/doc/proxy-
|
|||
In a test environments, you can configure Traefik to trust every incomming connection. Doing so, every remote client address will be replaced (`trustedIPs` won't have any effect)
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.http.proxyProtocol]
|
||||
[entrypoints.web.proxyProtocol]
|
||||
insecure = true
|
||||
```
|
||||
|
||||
|
@ -281,21 +120,21 @@ You can configure Traefik to trust the forwarded headers information (`X-Forward
|
|||
??? example "Trusting Forwarded Headers from specific IPs"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.http.forwardedHeaders]
|
||||
[entrypoints.web.forwardedHeaders]
|
||||
trustedIPs = ["127.0.0.1/32", "192.168.1.7"]
|
||||
```
|
||||
|
||||
??? example "Insecure Mode -- Always Trusting Forwarded Headers"
|
||||
|
||||
```toml
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.http.forwardedHeaders]
|
||||
[entrypoints.web.forwardedHeaders]
|
||||
insecure = true
|
||||
```
|
||||
|
|
|
@ -5,51 +5,95 @@ What's Happening to the Requests?
|
|||
|
||||
Let's zoom on Traefik's architecture and talk about the components that enable the routes to be created.
|
||||
|
||||
First, when you start Traefik, you define [entrypoints](./entrypoints.md) (in their most basic forms, they are port numbers).
|
||||
Then, connected to these entrypoints, [routers](./routers.md) analyze the incoming requests to see if they match a set of [rules](../routers#rule).
|
||||
If they do, the router might transform the request using pieces of [middleware](../middlewares/overview.md) before forwarding them to your [services](./services.md).
|
||||
First, when you start Traefik, you define [entrypoints](../entrypoints) (in their most basic forms, they are port numbers).
|
||||
Then, connected to these entrypoints, [routers](../routers) analyze the incoming requests to see if they match a set of [rules](../routers#rule).
|
||||
If they do, the router might transform the request using pieces of [middleware](../middlewares/overview.md) before forwarding them to your [services](./services/index.md).
|
||||
|
||||

|
||||
|
||||
## Clear Responsibilities
|
||||
|
||||
- [_Providers_](../providers/overview.md) discover the services that live on your infrastructure (their IP, health, ...)
|
||||
- [_Entrypoints_](./entrypoints.md) listen for incomming traffic (ports, SSL, ...)
|
||||
- [_Routers_](./routers.md) analyse the requests (host, path, headers, ...)
|
||||
- [_Services_](./services.md) forward the request to your services (load balancing, ...)
|
||||
- [_Providers_](../providers/overview.md) discover the services that live on your infrastructure (their IP, health, ...)
|
||||
- [_Entrypoints_](./entrypoints.md) listen for incomming traffic (ports, ...)
|
||||
- [_Routers_](./routers/index.md) analyse the requests (host, path, headers, SSL, ...)
|
||||
- [_Services_](./services/index.md) forward the request to your services (load balancing, ...)
|
||||
- [_Middlewares_](../middlewares/overview.md) may update the request or make decisions based on the request (authentication, rate limiting, headers, ...)
|
||||
|
||||
|
||||
## Example with a File Provider
|
||||
|
||||
Below is an example of a full configuration file for the [file provider](../providers/file.md) that forwards `http://domain/whoami/` requests to a service reachable on `http://private/whoami-service/`.
|
||||
In the process, Traefik will make sure that the user is authenticated (using the [BasicAuth middleware](../middlewares/basicauth.md)).
|
||||
In the process, Traefik will make sure that the user is authenticated (using the [BasicAuth middleware](../middlewares/basicauth.md)).
|
||||
|
||||
```toml
|
||||
[EntryPoints]
|
||||
[EntryPoints.http]
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":8081" # Listen on port 8081 for incoming requests
|
||||
|
||||
[Providers]
|
||||
# Enable the file provider to define routers / middlewares / services in a file
|
||||
[Providers.file]
|
||||
[providers]
|
||||
[providers.file] # Enable the file provider to define routers / middlewares / services in a file
|
||||
|
||||
[Routers]
|
||||
[Routers.to-whoami] # Define a connection between requests and services
|
||||
rule = "Host(domain) && PathPrefix(/whoami/)"
|
||||
middlewares = ["test-user"] # If the rule matches, applies the middleware
|
||||
service = "whoami" # If the rule matches, forward to the whoami service (declared below)
|
||||
|
||||
[Middlewares]
|
||||
[Middlewares.test-user.basicauth] # Define an authentication mechanism
|
||||
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"]
|
||||
|
||||
[Services]
|
||||
[Services.whoami.loadbalancer] # Define how to reach an existing service on our infrastructure
|
||||
[[Services.whoami.loadbalancer.servers]]
|
||||
url = "http://private/whoami-service"
|
||||
[http] # http routing section
|
||||
[http.routers]
|
||||
[http.routers.to-whoami] # Define a connection between requests and services
|
||||
rule = "Host(domain) && PathPrefix(/whoami/)"
|
||||
middlewares = ["test-user"] # If the rule matches, applies the middleware
|
||||
service = "whoami" # If the rule matches, forward to the whoami service (declared below)
|
||||
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-user.basicauth] # Define an authentication mechanism
|
||||
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"]
|
||||
|
||||
[http.services]
|
||||
[http.services.whoami.loadbalancer] # Define how to reach an existing service on our infrastructure
|
||||
[[http.services.whoami.loadbalancer.servers]]
|
||||
url = "http://private/whoami-service"
|
||||
```
|
||||
|
||||
!!! note "The File Provider"
|
||||
|
||||
In this example, we use the [file provider](../providers/file.md).
|
||||
Even if it is one of the least magical way of configuring Traefik, it explicitly describes every available notion.
|
||||
|
||||
!!! note "HTTP / TCP"
|
||||
|
||||
In this example, we've defined routing rules for http requests only.
|
||||
Traefik also supports TCP requests. To add [TCP routers](./routers/index.md) and [TCP services](./services/index.md), declare them in a TCP section like in the following.
|
||||
|
||||
??? example "Adding a TCP route for TLS requests on whoami.traefik.io"
|
||||
|
||||
```toml
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
address = ":8081" # Listen on port 8081 for incoming requests
|
||||
|
||||
[providers]
|
||||
[providers.file] # Enable the file provider to define routers / middlewares / services in a file
|
||||
|
||||
[http] # http routing section
|
||||
[http.routers]
|
||||
[http.routers.to-whoami] # Define a connection between requests and services
|
||||
rule = "Host(`domain`) && PathPrefix(/whoami/)"
|
||||
middlewares = ["test-user"] # If the rule matches, applies the middleware
|
||||
service = "whoami" # If the rule matches, forward to the whoami service (declared below)
|
||||
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-user.basicauth] # Define an authentication mechanism
|
||||
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"]
|
||||
|
||||
[http.services]
|
||||
[http.services.whoami.loadbalancer] # Define how to reach an existing service on our infrastructure
|
||||
[[http.services.whoami.loadbalancer.servers]]
|
||||
url = "http://private/whoami-service"
|
||||
|
||||
[tcp]
|
||||
[tcp.routers]
|
||||
[tcp.routers.to-whoami-tcp]
|
||||
rule = "HostSNI(`whoami-tcp.traefik.io`)"
|
||||
service = "whoami-tcp"
|
||||
[tcp.routers.to-whoami-tcp.tls]
|
||||
|
||||
[tcp.services]
|
||||
[tcp.services.whoami-tcp.loadbalancer]
|
||||
[[tcp.services.whoami-tcp.loadbalancer.servers]]
|
||||
address = "xx.xx.xx.xx:xx"
|
||||
```
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
# Routers
|
||||
|
||||
Connecting Requests to Services
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
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](../middlewares/overview.md) to update the request, or act before forwarding the request to the service.
|
||||
|
||||
## Configuration Example
|
||||
|
||||
??? example "Requests /foo are Handled by service-foo -- Using the [File Provider](../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[Routers]
|
||||
[Routers.my-router]
|
||||
rule = "Path(/foo)"
|
||||
service = "service-foo"
|
||||
```
|
||||
|
||||
??? example "With a [Middleware](../middlewares/overview.md) -- using the [File Provider](../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[Routers]
|
||||
[Routers.my-router]
|
||||
rule = "Path(/foo)"
|
||||
middlewares = ["authentication"] # declared elsewhere
|
||||
service = "service-foo"
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### EntryPoints
|
||||
|
||||
If not specified, routers will accept requests from all defined entrypoints.
|
||||
If you want to limit the router scope to a set of entrypoint, set the entrypoints option.
|
||||
|
||||
??? example "Listens to Every EntryPoint"
|
||||
|
||||
```toml
|
||||
[EntryPoints]
|
||||
[EntryPoint.http]
|
||||
# ...
|
||||
[EntryPoint.https]
|
||||
# ...
|
||||
[EntryPoint.other]
|
||||
# ...
|
||||
|
||||
[Routers]
|
||||
[Routers.Router-1]
|
||||
# By default, routers listen to every entrypoints
|
||||
rule = "Host(traefik.io)"
|
||||
service = "service-1"
|
||||
```
|
||||
|
||||
??? example "Listens to Specific EntryPoints"
|
||||
|
||||
```toml
|
||||
[EntryPoints]
|
||||
[EntryPoint.http]
|
||||
# ...
|
||||
[EntryPoint.https]
|
||||
# ...
|
||||
[EntryPoint.other]
|
||||
# ...
|
||||
|
||||
[Routers]
|
||||
[Routers.Router-1]
|
||||
entryPoints = ["https", "other"] # won't listen to entrypoint http
|
||||
rule = "Host(traefik.io)"
|
||||
service = "service-1"
|
||||
```
|
||||
|
||||
### Rule
|
||||
|
||||
Rules are a set of matchers that determine if a particular request matches specific criteria.
|
||||
If the rule is verified, then the router becomes active and calls middlewares, then forward the request to the service.
|
||||
|
||||
??? example "Host is traefik.io"
|
||||
|
||||
```
|
||||
rule = "Host(`traefik.io`)"
|
||||
```
|
||||
|
||||
??? example "Host is traefik.io OR Host is containo.us AND path is /traefik"
|
||||
|
||||
```
|
||||
rule = "Host(`traefik.io`) || (Host(`containo.us`) && Path(`/traefik`))"
|
||||
```
|
||||
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 `regexp` |
|
||||
| ``Host(`domain-1`, ...)`` | Check if the request domain targets one of the given `domains`. |
|
||||
| ``HostRegexp(`traefik.io`, `{subdomain:[a-z]+}.traefik.io`, ...)`` | Check if the request domain matches the given `regexp`. |
|
||||
| `Method(methods, ...)` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) |
|
||||
| ``Path(`path`, `/articles/{category}/{id:[0-9]+}`, ...)`` | Match exact request path. It accepts a sequence of literal and regular expression paths. |
|
||||
| ``PathPrefix(`/products/`, `/articles/{category}/{id:[0-9]+}`)`` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. |
|
||||
| ``Query(`foo=bar`, `bar=baz`)`` | Match` Query String parameters. It accepts a sequence of key=value pairs. |
|
||||
|
||||
!!! important "Regexp Syntax"
|
||||
|
||||
In order to use regular expressions with `Host` and `Path` expressions,
|
||||
you must declare an arbitrarily named variable followed by the colon-separated regular expression, all enclosed in curly braces.
|
||||
Any pattern supported by [Go's regexp package](https://golang.org/pkg/regexp/) may be used (example: `/posts/{id:[0-9]+}`).
|
||||
|
||||
!!! tip "Combining Matchers Using Operators and Parenthesis"
|
||||
|
||||
You can combine multiple matchers using the AND (`&&`) and OR (`||) operators. You can also use parenthesis.
|
||||
|
||||
!!! important "Rule, Middleware, and Services"
|
||||
|
||||
The rule is evaluated "before" any middleware has the opportunity to work, and "before" the request is forwarded to the service.
|
||||
|
||||
!!! tip "Path Vs PathPrefix"
|
||||
|
||||
Use `Path` if your service listens on the exact path only. For instance, `Path: /products` would match `/products` but not `/products/shoes`.
|
||||
|
||||
Use a `*Prefix*` matcher if your service listens on a particular base path but also serves requests on sub-paths.
|
||||
For instance, `PathPrefix: /products` would match `/products` but also `/products/shoes` and `/products/shirts`.
|
||||
Since the path is forwarded as-is, your service is expected to listen on `/products`.
|
||||
|
||||
### Middlewares
|
||||
|
||||
You can attach a list of [middlewares](../middlewares/overview.md) to the routers.
|
||||
The middlewares will take effect only if the rule matches, and before forwarding the request to the service.
|
||||
|
||||
### Service
|
||||
|
||||
You must attach a [service](./services.md) per router.
|
||||
Services are the target for the router.
|
4
docs/content/routing/routers/.markdownlint.json
Normal file
4
docs/content/routing/routers/.markdownlint.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "../../../.markdownlint.json",
|
||||
"MD024": false
|
||||
}
|
298
docs/content/routing/routers/index.md
Normal file
298
docs/content/routing/routers/index.md
Normal file
|
@ -0,0 +1,298 @@
|
|||
# Routers
|
||||
|
||||
Connecting Requests to Services
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
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](../../middlewares/overview.md) to update the request, or act before forwarding the request to the service.
|
||||
|
||||
## Configuration Example
|
||||
|
||||
??? example "Requests /foo are Handled by service-foo -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[http.routers]
|
||||
[http.routers.my-router]
|
||||
rule = "Path(/foo)"
|
||||
service = "service-foo"
|
||||
```
|
||||
|
||||
??? example "With a [middleware](../../middlewares/overview.md) -- using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[http.routers]
|
||||
[http.routers.my-router]
|
||||
rule = "Path(/foo)"
|
||||
middlewares = ["authentication"] # declared elsewhere
|
||||
service = "service-foo"
|
||||
```
|
||||
|
||||
??? example "Forwarding all (non-tls) requests on port 3306 to a database service"
|
||||
|
||||
```toml
|
||||
[entrypoints]
|
||||
[entrypoints.mysql-default]
|
||||
address = ":80"
|
||||
[entrypoints.mysql-default]
|
||||
address = ":3306"
|
||||
|
||||
[tcp]
|
||||
[tcp.routers]
|
||||
[tcp.routers.to-database]
|
||||
entrypoints = ["mysql-default"]
|
||||
rule = "HostSNI(`*`)" # Catch every request (only available rule for non-tls routers. See below.)
|
||||
service = "database"
|
||||
```
|
||||
|
||||
## Configuring HTTP Routers
|
||||
|
||||
### EntryPoints
|
||||
|
||||
If not specified, HTTP routers will accept requests from all defined entrypoints.
|
||||
If you want to limit the router scope to a set of entrypoint, set the entrypoints option.
|
||||
|
||||
??? example "Listens to Every EntryPoint"
|
||||
|
||||
```toml
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
# ...
|
||||
[entrypoints.web-secure]
|
||||
# ...
|
||||
[entrypoints.other]
|
||||
# ...
|
||||
|
||||
[http.routers]
|
||||
[http.routers.Router-1]
|
||||
# By default, routers listen to every entrypoints
|
||||
rule = "Host(traefik.io)"
|
||||
service = "service-1"
|
||||
```
|
||||
|
||||
??? example "Listens to Specific EntryPoints"
|
||||
|
||||
```toml
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
# ...
|
||||
[entrypoint.web-secure]
|
||||
# ...
|
||||
[entrypoint.other]
|
||||
# ...
|
||||
|
||||
[http.routers]
|
||||
[http.routers.Router-1]
|
||||
entryPoints = ["web-secure", "other"] # won't listen to entrypoint web
|
||||
rule = "Host(traefik.io)"
|
||||
service = "service-1"
|
||||
```
|
||||
|
||||
### Rule
|
||||
|
||||
Rules are a set of matchers that determine if a particular request matches specific criteria.
|
||||
If the rule is verified, then the router becomes active and calls middlewares, then forward the request to the service.
|
||||
|
||||
??? example "Host is traefik.io"
|
||||
|
||||
```toml
|
||||
rule = "Host(`traefik.io`)"
|
||||
```
|
||||
|
||||
??? example "Host is traefik.io OR Host is containo.us AND path is /traefik"
|
||||
|
||||
```toml
|
||||
rule = "Host(`traefik.io`) || (Host(`containo.us`) && Path(`/traefik`))"
|
||||
```
|
||||
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 `regexp` |
|
||||
| ``Host(`domain-1`, ...)`` | Check if the request domain targets one of the given `domains`. |
|
||||
| ``HostRegexp(`traefik.io`, `{subdomain:[a-z]+}.traefik.io`, ...)`` | Check if the request domain matches the given `regexp`. |
|
||||
| `Method(methods, ...)` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) |
|
||||
| ``Path(`path`, `/articles/{category}/{id:[0-9]+}`, ...)`` | Match exact request path. It accepts a sequence of literal and regular expression paths. |
|
||||
| ``PathPrefix(`/products/`, `/articles/{category}/{id:[0-9]+}`)`` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. |
|
||||
| ``Query(`foo=bar`, `bar=baz`)`` | Match` Query String parameters. It accepts a sequence of key=value pairs. |
|
||||
|
||||
!!! important "Regexp Syntax"
|
||||
|
||||
In order to use regular expressions with `Host` and `Path` expressions,
|
||||
you must declare an arbitrarily named variable followed by the colon-separated regular expression, all enclosed in curly braces.
|
||||
Any pattern supported by [Go's regexp package](https://golang.org/pkg/regexp/) may be used (example: `/posts/{id:[0-9]+}`).
|
||||
|
||||
!!! tip "Combining Matchers Using Operators and Parenthesis"
|
||||
|
||||
You can combine multiple matchers using the AND (`&&`) and OR (`||) operators. You can also use parenthesis.
|
||||
|
||||
!!! important "Rule, Middleware, and Services"
|
||||
|
||||
The rule is evaluated "before" any middleware has the opportunity to work, and "before" the request is forwarded to the service.
|
||||
|
||||
!!! tip "Path Vs PathPrefix"
|
||||
|
||||
Use `Path` if your service listens on the exact path only. For instance, `Path: /products` would match `/products` but not `/products/shoes`.
|
||||
|
||||
Use a `*Prefix*` matcher if your service listens on a particular base path but also serves requests on sub-paths.
|
||||
For instance, `PathPrefix: /products` would match `/products` but also `/products/shoes` and `/products/shirts`.
|
||||
Since the path is forwarded as-is, your service is expected to listen on `/products`.
|
||||
|
||||
### Middlewares
|
||||
|
||||
You can attach a list of [middlewares](../../middlewares/overview.md) to each HTTP router.
|
||||
The middlewares will take effect only if the rule matches, and before forwarding the request to the service.
|
||||
|
||||
### Service
|
||||
|
||||
You must attach a [service](../services/index.md) per router.
|
||||
Services are the target for the router.
|
||||
|
||||
!!! note "HTTP Only"
|
||||
|
||||
HTTP routers can only target HTTP services (not TCP services).
|
||||
|
||||
### TLS
|
||||
|
||||
When specifying a TLS section, you tell Traefik that the current router is dedicated to HTTPS requests only (and that the router should ignore HTTP (non tls) requests).
|
||||
Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services).
|
||||
|
||||
??? example "Configuring the router to accept HTTPS requests only"
|
||||
|
||||
```toml
|
||||
[http.routers]
|
||||
[http.routers.Router-1]
|
||||
rule = "Host(`foo-domain`) && Path(`/foo-path/`)"
|
||||
service = "service-id"
|
||||
[http.routers.Router-1.tls] # will terminate the TLS request
|
||||
```
|
||||
|
||||
!!! note "HTTPS & ACME"
|
||||
|
||||
In the current version, with [ACME](../../https-tls/acme.md) enabled, automatic certificate generation will apply to every router declaring a TLS section.
|
||||
In the near future, options will be available to enable fine-grain control of the TLS parameters.
|
||||
|
||||
!!! note "Passthrough"
|
||||
|
||||
On TCP routers, you can configure a passthrough option so that Traefik doesn't terminate the TLS connection.
|
||||
|
||||
!!! important "Routers for HTTP & HTTPS"
|
||||
|
||||
If you need to define the same route for both HTTP and HTTPS requests, you will need to define two different routers: one with the tls section, one without.
|
||||
|
||||
??? example "HTTP & HTTPS routes"
|
||||
|
||||
```toml
|
||||
[http.routers]
|
||||
[http.routers.Router-1-https]
|
||||
rule = "Host(`foo-domain`) && Path(`/foo-path/`)"
|
||||
service = "service-id"
|
||||
[http.routers.Router-1.tls] # will terminate the TLS request
|
||||
|
||||
[http.routers.Router-1-http]
|
||||
rule = "Host(`foo-domain`) && Path(`/foo-path/`)"
|
||||
service = "service-id"
|
||||
```
|
||||
|
||||
## Configuring TCP Routers
|
||||
|
||||
### General
|
||||
|
||||
If both HTTP routers and TCP routers listen to the same entrypoints, the TCP routers will apply *before* the HTTP routers.
|
||||
If no matching route is found for the TCP routers, then the HTTP routers will take over.
|
||||
|
||||
### EntryPoints
|
||||
|
||||
If not specified, TCP routers will accept requests from all defined entrypoints.
|
||||
If you want to limit the router scope to a set of entrypoints, set the entrypoints option.
|
||||
|
||||
??? example "Listens to Every EntryPoint"
|
||||
|
||||
```toml
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
# ...
|
||||
[entrypoints.web-secure]
|
||||
# ...
|
||||
[entrypoints.other]
|
||||
# ...
|
||||
|
||||
[tcp.routers]
|
||||
[tcp.routers.Router-1]
|
||||
# By default, routers listen to every entrypoints
|
||||
rule = "Host(traefik.io)"
|
||||
service = "service-1"
|
||||
```
|
||||
|
||||
??? example "Listens to Specific EntryPoints"
|
||||
|
||||
```toml
|
||||
[entrypoints]
|
||||
[entrypoints.web]
|
||||
# ...
|
||||
[entrypoint.web-secure]
|
||||
# ...
|
||||
[entrypoint.other]
|
||||
# ...
|
||||
|
||||
[tcp.routers]
|
||||
[tcp.routers.Router-1]
|
||||
entryPoints = ["web-secure", "other"] # won't listen to entrypoint web
|
||||
rule = "Host(traefik.io)"
|
||||
service = "service-1"
|
||||
[tcp.routers.Router-1.tls] # will route TLS requests (and ignore non tls requests)
|
||||
```
|
||||
|
||||
### Rule
|
||||
|
||||
| Rule | Description |
|
||||
|--------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
|
||||
| ``HostSNI(`domain-1`, ...)`` | Check if the Server Name Indication corresponds to the given `domains`. |
|
||||
|
||||
!!! important "HostSNI & TLS"
|
||||
|
||||
It is important to note that the Server Name Indication is an extension of the TLS protocol.
|
||||
Hence, only TLS routers will be able to specify a domain name with that rule.
|
||||
However, non-TLS routers will have to explicitly use that rule with `*` (every domain) to state that every non-TLS request will be handled by the router.
|
||||
|
||||
### Services
|
||||
|
||||
You must attach a TCP [service](../services/index.md) per TCP router.
|
||||
Services are the target for the router.
|
||||
|
||||
!!! note "TCP Only"
|
||||
|
||||
TCP routers can only target TCP services (not HTTP services).
|
||||
|
||||
### TLS
|
||||
|
||||
When specifying a TLS section, you tell Traefik that the current router is dedicated to TLS requests only (and that the router should ignore non-tls requests).
|
||||
By default, Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services), but you can tell Traefik that the request should pass through (keeping the encrypted data) and be forwarded to the service "as is".
|
||||
|
||||
??? example "Configuring TLS Termination"
|
||||
|
||||
```toml
|
||||
[tcp.routers]
|
||||
[tcp.routers.Router-1]
|
||||
rule = "Host(`foo-domain`)"
|
||||
service = "service-id"
|
||||
[tcp.routers.Router-1.tls] # will terminate the TLS request by default
|
||||
```
|
||||
|
||||
??? example "Configuring passthrough"
|
||||
|
||||
```toml
|
||||
[tcp.routers]
|
||||
[tcp.routers.Router-1]
|
||||
rule = "Host(`foo-domain`)"
|
||||
service = "service-id"
|
||||
[tcp.routers.Router-1.tls]
|
||||
passthrough=true
|
||||
```
|
||||
|
||||
!!! note "TLS & ACME"
|
||||
|
||||
In the current version, with [ACME](../../https-tls/acme.md) enabled, automatic certificate generation will apply to every router declaring a TLS section.
|
||||
In the near future, options will be available to enable fine-grain control of the TLS parameters.
|
4
docs/content/routing/services/.markdownlint.json
Normal file
4
docs/content/routing/services/.markdownlint.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "../../../.markdownlint.json",
|
||||
"MD024": false
|
||||
}
|
|
@ -3,50 +3,61 @@
|
|||
Configuring How to Reach the Services
|
||||
{: .subtitle }
|
||||
|
||||

|
||||

|
||||
|
||||
The `Services` are responsible for configuring how to reach the actual services that will eventually handle the incoming requests.
|
||||
|
||||
## Configuration Example
|
||||
|
||||
??? example "Declaring a Service with Two Servers (with Load Balancing) -- Using the [File Provider](../providers/file.md)"
|
||||
??? example "Declaring an HTTP Service with Two Servers -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.my-service.LoadBalancer]
|
||||
[http.services]
|
||||
[http.services.my-service.LoadBalancer]
|
||||
method = "wrr" # Load Balancing based on weights
|
||||
|
||||
[[Services.my-service.LoadBalancer.servers]]
|
||||
[[http.services.my-service.LoadBalancer.servers]]
|
||||
url = "http://private-ip-server-1/"
|
||||
weight = 30 # 30% of the requests will go to that instance
|
||||
[[Services.my-service.LoadBalancer.servers]]
|
||||
[[http.services.my-service.LoadBalancer.servers]]
|
||||
url = "http://private-ip-server-2/"
|
||||
weight = 70 # 70% of the requests will go to that instance
|
||||
```
|
||||
|
||||
## Configuration
|
||||
??? example "Declaring a TCP Service with Two Servers -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[tcp.services]
|
||||
[tcp.services.my-service.LoadBalancer]
|
||||
[[tcp.services.my-service.LoadBalancer.servers]]
|
||||
address = "xx.xx.xx.xx:xx"
|
||||
[[tcp.services.my-service.LoadBalancer.servers]]
|
||||
address = "xx.xx.xx.xx:xx"
|
||||
```
|
||||
|
||||
## Configuring HTTP Services
|
||||
|
||||
### General
|
||||
|
||||
Currently, the `LoadBalancer` service is the only supported kind of `Service` (see below).
|
||||
However, since Traefik is an ever evolving project, other kind of Services will be available in the future,
|
||||
reason why you have to specify what kind of service you declare.
|
||||
Currently, `LoadBalancer` is the only supported kind of HTTP `Service` (see below).
|
||||
However, since Traefik is an ever evolving project, other kind of HTTP Services will be available in the future,
|
||||
reason why you have to specify it.
|
||||
|
||||
### Load Balancer
|
||||
|
||||
The `LoadBalancer` service is able to load balance the requests between multiple instances of your programs.
|
||||
The load balancers are able to load balance the requests between multiple instances of your programs.
|
||||
|
||||
??? example "Declaring a Service with Two Servers (with Load Balancing) -- Using the [File Provider](../providers/file.md)"
|
||||
??? example "Declaring a Service with Two Servers (with Load Balancing) -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.my-service.LoadBalancer]
|
||||
[http.services]
|
||||
[http.services.my-service.LoadBalancer]
|
||||
method = "wrr" # Load Balancing based on weights
|
||||
|
||||
[[Services.my-service.LoadBalancer.servers]]
|
||||
[[http.services.my-service.LoadBalancer.servers]]
|
||||
url = "http://private-ip-server-1/"
|
||||
weight = 50 # 50% of the requests will go to that instance
|
||||
[[Services.my-service.LoadBalancer.servers]]
|
||||
[[http.services.my-service.LoadBalancer.servers]]
|
||||
url = "http://private-ip-server-2/"
|
||||
weight = 50 # 50% of the requests will go to that instance
|
||||
```
|
||||
|
@ -60,14 +71,14 @@ The `weight` option defines the weight of the server for the load balancing algo
|
|||
!!! note
|
||||
Paths in the servers' `url` have no effet.
|
||||
If you want the requests to be sent to a specific path on your servers,
|
||||
configure your [`routers`](./routers.md) to use a corresponding [Middleware](../middlewares/overview.md) (e.g. the [AddPrefix](../middlewares/addprefix.md) or [ReplacePath](../middlewares/replacepath.md)) middlewares.
|
||||
|
||||
??? example "A Service with One Server -- Using the [File Provider](../providers/file.md)"
|
||||
|
||||
configure your [`routers`](../routers/index.md) to use a corresponding [middleware](../../middlewares/overview.md) (e.g. the [AddPrefix](../../middlewares/addprefix.md) or [ReplacePath](../../middlewares/replacepath.md)) middlewares.
|
||||
|
||||
??? example "A Service with One Server -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.my-service.LoadBalancer]
|
||||
[[Services.my-service.LoadBalancer.servers]]
|
||||
[http.services]
|
||||
[http.services.my-service.LoadBalancer]
|
||||
[[http.services.my-service.LoadBalancer.servers]]
|
||||
url = "http://private-ip-server-1/"
|
||||
```
|
||||
|
||||
|
@ -77,16 +88,16 @@ Various methods of load balancing are supported:
|
|||
|
||||
- `wrr`: Weighted Round Robin.
|
||||
- `drr`: Dynamic Round Robin: increases weights on servers that perform better than others (rolls back to original weights when the server list is updated)
|
||||
|
||||
??? example "Load Balancing Using DRR -- Using the [File Provider](../providers/file.md)"
|
||||
|
||||
|
||||
??? example "Load Balancing Using DRR -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.my-service.LoadBalancer]
|
||||
[http.services]
|
||||
[http.services.my-service.LoadBalancer]
|
||||
method = "drr"
|
||||
[[Services.my-service.LoadBalancer.servers]]
|
||||
[[http.services.my-service.LoadBalancer.servers]]
|
||||
url = "http://private-ip-server-1/"
|
||||
[[Services.my-service.LoadBalancer.servers]]
|
||||
[[http.services.my-service.LoadBalancer.servers]]
|
||||
url = "http://private-ip-server-1/"
|
||||
```
|
||||
|
||||
|
@ -106,17 +117,17 @@ On subsequent requests, the client is forwarded to the same server.
|
|||
??? example "Adding Stickiness"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.my-service]
|
||||
[Services.my-service.LoadBalancer.stickiness]
|
||||
[http.services]
|
||||
[http.services.my-service]
|
||||
[http.services.my-service.LoadBalancer.stickiness]
|
||||
```
|
||||
|
||||
??? example "Adding Stickiness with a Custom Cookie Name"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.my-service]
|
||||
[Services.my-service.LoadBalancer.stickiness]
|
||||
[http.services]
|
||||
[http.services.my-service]
|
||||
[http.services.my-service.LoadBalancer.stickiness]
|
||||
cookieName = "my_stickiness_cookie_name"
|
||||
```
|
||||
|
||||
|
@ -148,9 +159,9 @@ Below are the available options for the health check mechanism:
|
|||
??? example "Custom Interval & Timeout -- Using the File Provider"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Servicess.Service-1]
|
||||
[Services.Service-1.healthcheck]
|
||||
[http.services]
|
||||
[http.servicess.Service-1]
|
||||
[http.services.Service-1.healthcheck]
|
||||
path = "/health"
|
||||
interval = "10s"
|
||||
timeout = "3s"
|
||||
|
@ -159,9 +170,9 @@ Below are the available options for the health check mechanism:
|
|||
??? example "Custom Port -- Using the File Provider"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.Service-1]
|
||||
[Services.Service-1.healthcheck]
|
||||
[http.services]
|
||||
[http.services.Service-1]
|
||||
[http.services.Service-1.healthcheck]
|
||||
path = "/health"
|
||||
port = 8080
|
||||
```
|
||||
|
@ -169,9 +180,9 @@ Below are the available options for the health check mechanism:
|
|||
??? example "Custom Scheme -- Using the File Provider"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.Service-1]
|
||||
[Services.Service-1.healthcheck]
|
||||
[http.services]
|
||||
[http.services.Service-1]
|
||||
[http.services.Service-1.healthcheck]
|
||||
path = "/health"
|
||||
scheme = "http"
|
||||
```
|
||||
|
@ -179,12 +190,53 @@ Below are the available options for the health check mechanism:
|
|||
??? example "Additional HTTP Headers -- Using the File Provider"
|
||||
|
||||
```toml
|
||||
[Services]
|
||||
[Services.Service-1]
|
||||
[Servicess.Service-1.healthcheck]
|
||||
[http.services]
|
||||
[http.services.Service-1]
|
||||
[http.servicess.Service-1.healthcheck]
|
||||
path = "/health"
|
||||
|
||||
[Service.Service-1.healthcheck.headers]
|
||||
My-Custom-Header = "foo"
|
||||
My-Header = "bar"
|
||||
```
|
||||
|
||||
## Configuring TCP Services
|
||||
|
||||
### General
|
||||
|
||||
Currently, `LoadBalancer` is the only supported kind of TCP `Service`.
|
||||
However, since Traefik is an ever evolving project, other kind of TCP Services will be available in the future,
|
||||
reason why you have to specify it.
|
||||
|
||||
### Load Balancer
|
||||
|
||||
The load balancers are able to load balance the requests between multiple instances of your programs.
|
||||
|
||||
??? example "Declaring a Service with Two Servers -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[tcp.services]
|
||||
[tcp.services.my-service.LoadBalancer]
|
||||
[[tcp.services.my-service.LoadBalancer.servers]]
|
||||
address = "xx.xx.xx.xx:xx"
|
||||
[[tcp.services.my-service.LoadBalancer.servers]]
|
||||
address = "xx.xx.xx.xx:xx"
|
||||
```
|
||||
|
||||
#### Servers
|
||||
|
||||
Servers declare a single instance of your program.
|
||||
The `address` option (IP:Port) point to a specific instance.
|
||||
|
||||
??? example "A Service with One Server -- Using the [File Provider](../../providers/file.md)"
|
||||
|
||||
```toml
|
||||
[tcp.services]
|
||||
[tcp.services.my-service.LoadBalancer]
|
||||
[[tcp.services.my-service.LoadBalancer.servers]]
|
||||
address = "xx.xx.xx.xx:xx"
|
||||
```
|
||||
|
||||
!!! note "Weight"
|
||||
|
||||
The TCP LoadBalancer is currently a round robin only implementation and doesn't yet support weights.
|
Loading…
Add table
Add a link
Reference in a new issue