[alpha7] HTTPs redirection

Hello guys. I’m having a little trouble with https redirection on traefik-v2. Below is my config…

## static configuration

[global]
  checkNewVersion = true
  sendAnonymousUsage = true

[serversTransport]
  insecureSkipVerify = true

[entryPoints]
  [entryPoints.web]
    address = ":80"
  [entryPoints.web-secure]
    address = ":443"

[api]
  debug = true

[log]
  level = "DEBUG"

[providers.file]

[providers.docker]
  exposedByDefault = false
 
## dynamic configuration (require the file provider)

    [[tls]]
      store = ["default"]
      [tls.certificate]
        certFile = "/opt/localcerts/arara-docker-dev.us.pem"
        keyFile  = "/opt/private/arara-docker.key"

    [tlsStores]
      [tlsStores.default]
        [tlsStores.default.defaultCertificate]
          certFile = "/opt/localcerts/arara-docker-dev.us.pem"
          keyFile  = "/opt/private/arara-docker.key"

And here is how i get my container running.

    docker run -d --name Espelho \
            -l 'traefik.enable=true' \
            -l 'traefik.http.routers.web.rule=Host(`espelho.dev.us`)' \
            -l "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https" \
            -l 'traefik.http.routers.web.middlewares=https_redirect' \
            -l 'traefik.http.routers.web-secure.rule=Host(`espelho.dev.us`)' \
            -l 'traefik.http.routers.web-secure.tls=true' \
            jboss5-1

What happens is that when i access ‘espelho.dev.ufs’ it is successfully redirected to the https site. However, when i access https://espelho.dev.us/admin i get a 404. When i remove the web-secure.tls i can use the application successfully without https. What’s happening, why isn’t https working?

Hi leonardobsjr,

You define a redirect middleware named test-redirectscheme and you apply to the router a middleware named https_redirect, so I’m surprized that the redirection works.

Could you please check if you have the right middleware name and a 302 when you try an http request ?

Ops, sorry. You’re right, it was just a bad copy-paste by me. It’s quite wonky tho, because i need duplicate the routes on whatever application i need to work on.

It is possible to define default routes and middlewares, with default host rules?

Let’s talk about some tips to have less docker label for the same configuration.

First point, you can modify the defaultRule to match your domain. It will avoid you to specify the rule on each router.

Then, you can specify a middleware in a label or in a configuration file thanks to the file provider.
When you define a middleware in a file, you can use it in docker with a reference like myMiddleware@file (since the v2.0.0-alpha7).

If you need to have multiple middlewares by default, you can define all in the file and add their names in the router configuration, or, you can create a chain middleware and reference its name in the routers configuration like myChainMiddleware@file.

With these tips, you can:

  • limit the number of docker labels needed
  • limit the number of middlewares references in the router configuration
  • create a kind of library of middlewares available for all your routers

Let’s see an example with a simple https redirect use case:

# traefik.toml
# static configuration
[log]
    level= "DEBUG"

[api]

[entryPoints.web]
    Address = ":80"

[entryPoints.web-secured]
    Address = ":443"

[Providers.Docker]
     defaultRule = "Host(`{{ .Name }}.example.com`)"
     exposedByDefault = false

[Providers.file]

# dynamic configuration
[http.middlewares]
  [http.middlewares.redirect.redirectscheme]
    scheme = "https"

[[tls]]
  [tls.certificate]
    certFile = "/app/certs/server/server.pem"
    keyFile = "/app/certs/server/server.pem"
# docker-compose.yml
version: '3.5'
services:

  rproxy:
    image: traefik:v2.0.0-alpha7
    volumes:
      - ./certs/:/app/certs/
      - ./traefik.toml:/etc/traefik/traefik.toml:ro
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - '443:443'
      - '80:80'
      - '8080:8080'

  api:
    image: containous/whoami
    labels:
      - traefik.port=80
      - traefik.enable=true
      - traefik.http.routers.web.entrypoints=web
      - traefik.http.routers.web.middlewares=redirect@file
      - traefik.http.routers.web-secured.entrypoints=web-secured
      - traefik.http.routers.web-secured.tls=true

I hope that will help you! :smile:

2 Likes

Thanks a lot for the input and sorry for the delayed answer. One additional question: it is possible to reuse the routers too, the same way you reused the middleware? I’ve tried, but the generated data (/rawdata) doesn’t match, and, ofc, doesn’t work.

After your tips, the /rawdata of the working application is now

{
  "routers": {
    "web-secure@docker": {
      "entryPoints": [
        "web-secure"
      ],
      "service": "/Espelho",
      "rule": "Host(`Espelho.dev.ufs.br`)",
      "tls": {}
    },
    "web-secure@file": {
      "entryPoints": [
        "web-secure"
      ],
      "tls": {},
      "error": "the service \"@file\" does not exist"
    },
    "web@docker": {
      "entryPoints": [
        "web"
      ],
      "middlewares": [
        "redirect@file"
      ],
      "service": "/Espelho",
      "rule": "Host(`Espelho.dev.ufs.br`)"
    },
    "web@file": {
      "entryPoints": [
        "web"
      ],
      "middlewares": [
        "redirect"
      ],
      "error": "the service \"@file\" does not exist"
    }
  },
  "middlewares": {
    "redirect@file": {
      "redirectScheme": {
        "scheme": "https"
      },
      "usedBy": [
        "web@docker",
        "web@file"
      ]
    }
  },
  "services": {
    "/Espelho@docker": {
      "loadbalancer": {
        "servers": [
          {
            "url": "http://172.17.0.36:8080"
          }
        ],
        "passHostHeader": true
      },
      "usedBy": [
        "web-secure@docker",
        "web@docker"
      ],
      "serverStatus": {
        "http://172.17.0.36:8080": "UP"
      }
    }
  }
}

I’ve tried to remove the labels, add the label 'traefik.http.routers=["web","web-secure"]' and to put the router definition on the file provider, but didn’t work.

{
  "routers": {
    "/Espelho@docker": {
      "entryPoints": null,
      "service": "/Espelho",
      "rule": "Host(`Espelho.dev.ufs.br`)"
    },
    "web-secure@file": {
      "entryPoints": [
        "web-secure"
      ],
      "tls": {},
      "error": "the service \"@file\" does not exist"
    },
    "web@file": {
      "entryPoints": [
        "web"
      ],
      "middlewares": [
        "redirect"
      ],
      "error": "the service \"@file\" does not exist"
    }
  },
  "middlewares": {
    "redirect@file": {
      "redirectScheme": {
        "scheme": "https"
      },
      "usedBy": [
        "web@file"
      ]
    }
  },
  "services": {
    "/Espelho@docker": {
      "loadbalancer": {
        "servers": [
          {
            "url": "http://172.17.0.36:8080"
          }
        ],
        "passHostHeader": true
      },
      "usedBy": [
        "/Espelho@docker"
      ],
      "serverStatus": {
        "http://172.17.0.36:8080": "UP"
      }
    }
  }
}

No, you can’t.

I encourage you to read the documentation on Routers and dynamic configuration for Docker and File. :slight_smile:

Hello guys,

@jbd Have you tried your configuration example in v2.0.0-beta1 or v2.0.0-rc1 ? It seems that it doesn't work.

Thanks

Hi @guilhome,

The configuration has changed between the alpha and the RC.

Now, you have to provide the file path (or directory path) for the file provider.

# traefik.toml / static configuration
[providers.file]
    filename = "dynamic_conf.toml" 

Then you can move the dynamic configuration inside this file with the new TLS configuration:

# dynamic_conf.toml
[http.middlewares]
  [http.middlewares.redirect.redirectscheme]
    scheme = "https"

[[tls.certificate]]
    certFile = "/app/certs/server/server.pem"
    keyFile = "/app/certs/server/server.pem"

I hope it will help you.