traefik/docs/content/https/tailscale.md
Kevin Pollet 38d7011487
Add Tailscale certificate resolver
Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
2022-09-30 15:20:08 +02:00

6.7 KiB

title description
Traefik Tailscale Documentation Learn how to configure Traefik Proxy to resolve TLS certificates for your Tailscale services. Read the technical documentation.

Tailscale

Provision TLS certificates for your internal Tailscale services. {: .subtitle }

To protect a service with TLS, a certificate from a public Certificate Authority is needed. In addition to its vpn role, Tailscale can also provide certificates for the machines in your Tailscale network.

Certificate resolvers

To obtain a TLS certificate from the Tailscale daemon, a Tailscale certificate resolver needs to be configured as below.

!!! info "Referencing a certificate resolver"

Defining a certificate resolver does not imply that routers are going to use it automatically.
Each router or entrypoint that is meant to use the resolver must explicitly [reference](../routing/routers/index.md#certresolver) it.
certificatesResolvers:
    myresolver:
        tailscale: {}
[certificatesResolvers.myresolver.tailscale]
--certificatesresolvers.myresolver.tailscale=true

Domain Definition

A certificate resolver requests certificates for a set of domain names inferred from routers, according to the following:

  • If the router has a tls.domains option set, then the certificate resolver derives this router domain name from the main option of tls.domains.

  • Otherwise, the certificate resolver derives the domain name from any Host() or HostSNI() matchers in the router's rule.

!!! info "Tailscale Domain Format"

The domain is only taken into account if it is a Tailscale-specific one,
i.e. of the form `machine-name.domains-alias.ts.net`.

Configuration Example

!!! example "Enabling Tailscale certificate resolution"

```yaml tab="File (YAML)"
entryPoints:
  web:
    address: ":80"

  websecure:
    address: ":443"

certificatesResolvers:
  myresolver:
    tailscale: {}
```

```toml tab="File (TOML)"
[entryPoints]
  [entryPoints.web]
    address = ":80"

  [entryPoints.websecure]
    address = ":443"

[certificatesResolvers.myresolver.tailscale]
```

```bash tab="CLI"
--entrypoints.web.address=:80
--entrypoints.websecure.address=:443
# ...
--certificatesresolvers.myresolver.tailscale=true
```

!!! example "Domain from Router's Rule Example"

```yaml tab="Docker"
## Dynamic configuration
labels:
  - traefik.http.routers.blog.rule=Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)
  - traefik.http.routers.blog.tls.certresolver=myresolver
```

```yaml tab="Docker (Swarm)"
## Dynamic configuration
deploy:
  labels:
    - traefik.http.routers.blog.rule=Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)
    - traefik.http.routers.blog.tls.certresolver=myresolver
```

```yaml tab="Kubernetes"
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: blogtls
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)
      kind: Rule
      services:
        - name: blog
          port: 8080
  tls:
    certResolver: myresolver
```

```json tab="Marathon"
labels: {
  "traefik.http.routers.blog.rule": "Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)",
  "traefik.http.routers.blog.tls.certresolver": "myresolver",
}
```

```yaml tab="Rancher"
## Dynamic configuration
labels:
  - traefik.http.routers.blog.rule=Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)
  - traefik.http.routers.blog.tls.certresolver=myresolver
```

```yaml tab="File (YAML)"
## Dynamic configuration
http:
  routers:
    blog:
      rule: "Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)"
      tls:
        certResolver: myresolver
```

```toml tab="File (TOML)"
## Dynamic configuration
[http.routers]
  [http.routers.blog]
  rule = "Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)"
  [http.routers.blog.tls]
    certResolver = "myresolver"
```

!!! example "Domain from Router's tls.domain Example"

```yaml tab="Docker"
## Dynamic configuration
labels:
  - traefik.http.routers.blog.rule=Path(`/metrics`)
  - traefik.http.routers.blog.tls.certresolver=myresolver
  - traefik.http.routers.blog.tls.domains[0].main=monitoring.yak-bebop.ts.net
```

```yaml tab="Docker (Swarm)"
## Dynamic configuration
deploy:
  labels:
    - traefik.http.routers.blog.rule=Path(`/metrics`)
    - traefik.http.routers.blog.tls.certresolver=myresolver
    - traefik.http.routers.blog.tls.domains[0].main=monitoring.yak-bebop.ts.net
```

```yaml tab="Kubernetes"
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: blogtls
spec:
  entryPoints:
    - websecure
  routes:
    - match: Path(`/metrics`)
      kind: Rule
      services:
        - name: blog
          port: 8080
  tls:
    certResolver: myresolver
    domains:
      - main: monitoring.yak-bebop.ts.net
```

```json tab="Marathon"
labels: {
  "traefik.http.routers.blog.rule": "Path(`/metrics`)",
  "traefik.http.routers.blog.tls.certresolver": "myresolver",
  "traefik.http.routers.blog.tls.domains[0].main": "monitoring.yak-bebop.ts.net",
}
```

```yaml tab="Rancher"
## Dynamic configuration
labels:
  - traefik.http.routers.blog.rule=Path(`/metrics`)
  - traefik.http.routers.blog.tls.certresolver=myresolver
  - traefik.http.routers.blog.tls.domains[0].main=monitoring.yak-bebop.ts.net
```

```yaml tab="File (YAML)"
## Dynamic configuration
http:
  routers:
    blog:
      rule: "Path(`/metrics`)"
      tls:
        certResolver: myresolver
        domains:
          - main: "monitoring.yak-bebop.ts.net"
```

```toml tab="File (TOML)"
## Dynamic configuration
[http.routers]
  [http.routers.blog]
    rule = "Path(`/metrics`)"
    [http.routers.blog.tls]
      certResolver = "myresolver"
      [[http.routers.blog.tls.domains]]
        main = "monitoring.yak-bebop.ts.net"
```

Automatic Renewals

Traefik automatically tracks the expiry date of each Tailscale certificate it fetches, and starts to renew a certificate 14 days before its expiry to match Tailscale daemon renew policy.