Regex redirect fails with HTTPS

I'm back :slight_smile:

Ok so what I'd like is a redirect that does the following:

[1]: http://a.localhost/b/c/d -> https://whoami.localhost/a/b/c/d
[2]: https://a.localhost/b/c/d -> https://whoami.localhost/a/b/c/d

So far I've got this working for the first case (http->https) but not the second. In the second case, visiting https://a.localhost/b/c/d returns a 404. My example is based on the containous example for global http->https redirection. Can anyone work out why the second case doesn't work? I have tested the regex and it should hold for both http and https.

docker-compose.yml:

version: "3.3"

services:
  traefik:
    image: "traefik:v2.0.0"
    command:
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --providers.docker
      - --providers.docker.exposedbydefault=false
      - --api
      - --certificatesresolvers.leresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
      - --certificatesresolvers.leresolver.acme.email=your@email.com
      - --certificatesresolvers.leresolver.acme.storage=/acme.json
      - --certificatesresolvers.leresolver.acme.tlschallenge=true
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"

        # global redirect
        # example: http[s]://foo.localhost/bar/baz -> https://whoami.localhost/foo/bar/baz
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=web,websecure"
      - "traefik.http.routers.http-catchall.middlewares=global-redir"
      - "traefik.http.middlewares.global-redir.redirectregex.regex=^https?://([a-zA-Z0-9-]+).localhost(/.*)?$$"
      - "traefik.http.middlewares.global-redir.redirectregex.replacement=https://whoami.localhost/$${1}$${2}"

  my-app:
    image: containous/whoami:v1.3.0
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.my-app.rule=Host(`whoami.localhost`)"
      - "traefik.http.routers.my-app.middlewares=auth"
      - "traefik.http.routers.my-app.entrypoints=websecure"
      - "traefik.http.routers.my-app.tls=true"
      - "traefik.http.routers.my-app.tls.certresolver=leresolver"
      - "traefik.http.middlewares.auth.basicauth.users=user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/" # user/password

Hi, I have almost the same problem: I don't get 404 but redirect obtained with redirectregex only work for http and not for https.
Any hints?

hello,

version: "3.7"

services:
  traefik:
    image: traefik:v2.1.3
    command:
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --providers.docker
      - --providers.docker.exposedbydefault=false
      - --api
      - --certificatesresolvers.leresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
      - --certificatesresolvers.leresolver.acme.email=your@email.com
      - --certificatesresolvers.leresolver.acme.storage=/acme.json
      - --certificatesresolvers.leresolver.acme.tlschallenge=true
    ports:
      - 80:80
      - 443:443
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      traefik.enable: true

      # dashboard
      traefik.http.routers.api.rule: Host(`traefik.localhost`)
      traefik.http.routers.api.entrypoints: web
      traefik.http.routers.api.service: api@internal
 
      # global redirect
      traefik.http.routers.http_redirect.rule: hostregexp(`{host:.+}`)
      traefik.http.routers.http_redirect.entrypoints: web
      traefik.http.routers.http_redirect.middlewares: redir
 
      traefik.http.routers.https_redirect.rule: hostregexp(`{host:.+}`)
      traefik.http.routers.https_redirect.entrypoints: websecure
      traefik.http.routers.https_redirect.tls: true
      traefik.http.routers.https_redirect.priority: 1 # low priority
      traefik.http.routers.https_redirect.middlewares: redir
 
      traefik.http.middlewares.redir.redirectregex.regex: ^https?://([a-zA-Z0-9-]+).localhost(.*)$$
      traefik.http.middlewares.redir.redirectregex.replacement: https://whoami.localhost/$${1}$${2}

  my-app:
    image: containous/whoami:v1.4.0
    labels:
      traefik.enable: true
      traefik.http.routers.my-app.rule: Host(`whoami.localhost`)
      traefik.http.routers.my-app.middlewares: auth
      traefik.http.routers.my-app.entrypoints: websecure
      traefik.http.routers.my-app.tls: true
      traefik.http.routers.my-app.tls.certresolver: leresolver
      traefik.http.middlewares.auth.basicauth.users: user:$$apr1$$q8eZFHjF$$Fvmkk//V6Btlaf2i/ju5n/ # user/password

Thanks Idez,

I dont' think I'm using a very different approach even though it's in the target label (my-app). I need to redirect between two different names and I'm doing exactly this:

      labels:
         traefik.enable: true
         traefik.http.routers.grazie-web.rule: Host(`grazie.e-den.it`, `october.e-den.it`)
         traefik.http.routers.grazie-web.entrypoints: web
         #traefik.http.routers.grazie-web.middlewares: redirect-to-https                                                                                                                                                                                                                               
         traefik.http.routers.grazie-web.middlewares: grazie-redirectregex
         #traefik.http.middlewares.redirect-to-https.redirectscheme.scheme: https                                                                                                                                                                                                                      

         traefik.http.routers.grazie-secured.rule: Host(`grazie.e-den.it`, `october.e-den.it`)
         traefik.http.routers.grazie-secured.entrypoints: web-secured
         traefik.http.routers.grazie-secured.tls.certresolver: leresolver
         traefik.http.routers.grazie-web.middlewares: grazie-redirectregex                                                                                                                                                                                                                      

         traefik.http.middlewares.grazie-redirectregex.redirectregex.regex: ^https?://(october|grazie).e-den.it/(.*)
         traefik.http.middlewares.grazie-redirectregex.redirectregex.replacement: https://grazie.e-den.it/$${2}
         traefik.http.middlewares.grazie-redirectregex.redirectregex.permanent: true

When testing http://october.e-den.it I am correctly redirected to https://grazie.... but when connecting via https I have been served directly the page (w/ no errors).

Here is how I test it with script that uses python requets:

$ jmb test domain october.e-den.it/la-base/
http://october.e-den.it/la-base/ => 301  (https://grazie.e-den.it/la-base/) [0.11s]
https://october.e-den.it/la-base/ => 200 (La base) [0.53s]

I'm very new to traefik, so maybe I don't understand correctly the implications passing from global to local in defining the redirect.

I'm using traefik 2.1.4.

Thanks, that solved my problem

Hi microbug, would you mind to share the configuration that worked for you? I'm still stuck with the situation described above. I can't redirect from https => https.

sandro

SOLVED, copy-paste fault here...
In the second block for the secured router I forgot to modify the router, so that the used router was always the same...

- traefik.http.routers.grazie-web.middlewares: grazie-redirectregex 
+ traefik.http.routers.grazie-secured.middlewares: grazie-redirectregex 

the final configuration was fine tuned:

labels:
   traefik.enable: true
   traefik.http.routers.grazie-web.rule: Host(`grazie.e-den.it`, `october.e-den.it`)
   traefik.http.routers.grazie-web.entrypoints: web
   traefik.http.routers.grazie-web.middlewares: grazie-redirectregex

   traefik.http.routers.grazie-secured.rule: Host(`grazie.e-den.it`, `october.e-den.it`)
   traefik.http.routers.grazie-secured.entrypoints: web-secured
   traefik.http.routers.grazie-secured.tls.certresolver: leresolver
   traefik.http.routers.grazie-secured.tls: true
   traefik.http.routers.grazie-secured.middlewares: grazie-redirectregex

   traefik.http.middlewares.grazie-redirectregex.redirectregex.regex: ^(https?://october|http://grazie).e-den.it(.*)
   traefik.http.middlewares.grazie-redirectregex.redirectregex.replacement: https://grazie.e-den.it$${2}
   traefik.http.middlewares.grazie-redirectregex.redirectregex.permanent: true

I confirm that now I have correct https => https and in the prev example I have generation of certificate with main and sans

the result show the correct behaviour:

$ jmb test domain october.e-den.it/la-base/
http://october.e-den.it/la-base/ => 301  (https://grazie.e-den.it/la-base/) [0.1s]
https://october.e-den.it/la-base/ => 301  (https://grazie.e-den.it/la-base/) [0.19s]

$ jmb test domain grazie.e-den.it/la-base/
http://grazie.e-den.it/la-base/ => 301  (https://grazie.e-den.it/la-base/) [0.1s]
https://grazie.e-den.it/la-base/ => 200 (La base) [0.54s]