Http to https redirection through middlewares does not work unless globally enforced

Hi,

I've opened a very detailed issue on Github about this but it got automatically closed: Http to https redirection through middlewares does not work unless globally enforced · Issue #6995 · traefik/traefik · GitHub

In essence if you configure a router with http and https entry points and then add a middleware which redirects to https it won't work. To me this looks like a bug and not a misconfiguration, but I might be wrong.

It seems like somebody else has had a similar issue as well:

Does anybody know what I'm doing wrong? Is this actually a bug or not?

Your config directs the router to be TLS, bound to enttyPoints http(80),HTTPS(443) , is for Host whoami.domain.com and uses middleware redirect-to-https.

When you connect http to port 80 that configuration is not matched. No router on that service is http.
(You can demonstrate this by doing a request on https://whoami.domain.com:80)

Based on the commented section in the static configuration Default http - > https redirect is not what you want.

You have to define another router on that service that is on entryPoint http and does not have tls enabled. Remove http from the existing routers entryPoints too,

1 Like

Thanks for your reply!

It looks like I have missed this part of the documentation:

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.
Routers | Traefik | v2.2

1 Like

I had to create an account just to reply to this, because this is very unintuitive.

Why would I need a "loose" router? Its unintuitive that a TLS router would only catch TLS traffic, especially when I put an HTTP -> HTTPS middleware onto it as well.

At least maybe show some logs, because the only kind of debugging that I have access to with Traefik is "404 page not found" and thats it. Nothing in the logs, just an access log with useless request information. NOWHERE does it mention that the route is not matched.

And when I have HTTP -> HTTPS redirecting middleware on top of my TLS enabled (or well, its just TLS or so it turns out, not "enabled", but "required and exclusively TLS"), there's no damn warning about the fact that this middleware is completely useless to use, because it will never be used.

Just horribly unintuitive.

/rant

What is your problem? We usually try to be constructive here and help everyone out.

By the way, you replied to a 3 year old post.

So its still a valid problem, and has been, for the past 3 years.
Sorry, I quit smoking 2 days ago and this was driving me crazy

It actually makes sense to have two distinctive routers - one for TLS an one for HTTP because of multiple reasons:

  1. separation of concern
  2. letsencrypt requires http for web verification
  3. you could have multiple domains running on plain HTTP, but just X,Y,Z running on HTTPS (for whatever valid reason)

The problem back then was that it wasn't very well documented and at the time v2 was very new (not sure of the current state of the docs)

there's no damn warning about the fact that this middleware is completely useless and stupid to use, because it will never be used.

You just pointed out the obvious - because it will never be used. How could it print an error/notice, if the code is never executed? :smiley:

Anyway, just so it's more clear for anybody who might still bump into this issue and find this thread:

  1. You need 2 routers: HTTP and HTTPS. This will then make traefik use ports 80 and 443
  2. You add the redirect-to-https middleware to the HTTP router. Whenever somebody visits http://x.y.z, the HTTP router will go through the redirect-to-https middleware and redirect the client to https.

Hope this helps :slight_smile:

p.s. Good job on quitting smoking!

1 Like

I'll probably be making a couple of pull requests, because it just doesn't make sense.

When I open my router in the interface;

  • Entrypoints are :443 and :80
  • Points to the HTTP router
  • Points to the HTTP middlewares (ipwhitelist + https scheme redirect)
  • Points to my service

Router details:
Shows web and websecure entrypoints, shows hostname, shows TLS is enabled with default options, shows Redirect to HTTPS.

What this SHOULD say:

  • Entrypoint: :443 (HTTPS only)
  • HTTPS Router
  • HTTPS Middleware
  • Router details: Entrypoint websecure only
  • TLS: Exclusively enabled
    Middleware -> Redirect to HTTPS: < Warning, this route already is HTTPS only >

And then we have the fact that nothing is logged. When a route is not matched, I expect to at least see something in the logs, preferably the accesslogs, and especially when I have debug logs enabled.

EDIT: Yes, still probably a case of RTFM, but a descriptive UI and some logging would help. Also @bluepuma77 I'm sorry for my wording, I've changed it, I shouldn't be yelling to people like that

In general you can have http and https entrypoints. For http you can place a redirect directly on the entrypoint. LetsEncrypt works fine with tlsChallenge on https alone.

Traefik v3 let’s you set the default entrypoint for all routers globally, so http is only redirect.

See simple Traefik example.

I appreciate the conversation happened so far and would love to follow on and support @wellthatjustdumb

I have been dumbfounded by this quirk of Traefik and posted a separate stackoverflow question as well (docker - Traefik HTTP to HTTPS non-global redirect - is there a better way? - Stack Overflow)

The usecase, in my opinion, is quite simple.
Whenever I configure a new router for a service, if I set https there is never any reason for http to really be exposed on that same router (host), unless I'm missing something? Most web clients when seeing an https available and tls enabled will always default to https. Therefore, I'd love to be able to specify once that I want all http redirected to https instead of creating a whole new router just for the reditet. Something like this:

# External .dev
      - traefik.http.routers.whoami.rule=Host(`whoami.example.com`)
      - traefik.http.routers.whoami.entrypoints=http, https
      - traefik.http.routers.whoami.tls.certresolver=lets-encrypt-tls
      - traefik.http.routers.whoami.middlewares=redirect-https@file

You can specify a global redirect directly on entrypoint (doc).

And with Traefik v3 you can declare a default entrypoint, so all you routers can listen on websecure only by default (doc).

1 Like

if I set https there is never any reason for http to really be exposed on that same router

You need http in order to redirect clients arriving at the http entrypoint (meaning port 80) of your host to the https one. If there is nothing listening at port 80 (http) then the browser arriving at that entrypoint will return some form of 404 or ERR_CONNECTION_REFUSED.

This can be hurtful to SEO and could mislead the person arriving at the http entrypoint that the site is offline.

Most web clients when seeing an https available and tls enabled will always default to https

SOME browsers MAY default to https when you enter xyz.com (without http:// or https://).
This does not mean ALL browsers ALWAYS redirect, which makes your assumption invalid. :slight_smile:

Certainly, that's one option, but I also want to retain individual control over this as, for example, I don't want to bother and issue SSL certificates for my .local domains for internal IPs managed on the same Traefik container, which means that I need to configure it per-service, which means many and many extra unnecessary routers.

Exactly right, that's why I feel like being able to redirect from one entrypoint to another (http -> https) via one line instead of creating a whole other separate router would be wonderful, as not everyone is comfortable with defaulting their entire stack to be redirected from http to https.