Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirect all requests on entrypoint, even without frontend #2109

Closed
deitch opened this issue Sep 12, 2017 · 38 comments
Closed

Redirect all requests on entrypoint, even without frontend #2109

deitch opened this issue Sep 12, 2017 · 38 comments
Assignees
Milestone

Comments

@deitch
Copy link
Contributor

deitch commented Sep 12, 2017

Do you want to request a feature or report a bug?

Feature

What did you do?

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    regex = "^http://(.*)$"
    replacement = "https://$1"
  [entryPoints.https]
  address = ":443"

What did you expect to see?

Any request to http://<host>/* would be redirected to https://<host>/*

What did you see instead?

It only redirects for matching frontends on the entrypoint. Thus, if I have a frontend defined for /foo but not /bar, then http://<host/foo -> https://<host>/foo but http://<host>/bar does not redirect to https://<host>/bar

Output of traefik version: (What version of Traefik are you using?)

1.3.8

Use case

If I want to enforce https across the board, then I would want to:

  1. Remove http from the defaultEntryPoints array.
  2. Set a global redirect: anything into http gets sent to https. It is not overridable at any point

InfoSec/Compliance teams often insist (rightly) that nothing gets returned from an http requests except a 302 redirect: not a 404 (because no frontend defined), nothing.

@timoreimann
Copy link
Contributor

I think what you want is possible already. See the documentation here.

Does this address your need?

@deitch
Copy link
Contributor Author

deitch commented Sep 12, 2017

Thanks @timoreimann ; that is precisely what I am doing above. It doesn't work, though, unless a frontend is defined. I want an across-the-board 302 (or 301) for requests to one entrypoint to go to another. Right now, the above returns a 404 unless a frontend is defined for that entrypoint.

@timoreimann
Copy link
Contributor

@deitch You might be able to create a dummy frontend using, say, the file provider.

@deitch
Copy link
Contributor Author

deitch commented Sep 12, 2017

@timoreimann that is what I did in the end:

      [backends.dummy]
        [backends.dummy.servers.server1]
        url = "http://localhost:80"
# skipping...
      [frontends.dummy]
      backend = "dummy"
      entrypoints = ["http"]
        [frontends.dummy.routes.all]
        rule = "PathPrefix:/"

Main issues are:

  1. It is not clear in the docs that it will not work without this.
  2. It probably should work without this (or at least be an option)

@LukeMauldin
Copy link

I ran into this same problem and fixed it by using the dummy frontend/backend above. I think the dummy frontend/backend requirement should be removed. Until that time, at least the documentation on http://docs.traefik.io/configuration/entrypoints/#redirect-http-to-https should mention the frontend/backend requirement.
Doing a http -> https redirect is something that HAProxy makes very simple and IMO Traefik should make it simple as well.

@ldez ldez added kind/bug/confirmed a confirmed bug (reproducible). and removed status/0-needs-triage labels Oct 5, 2017
@andig
Copy link

andig commented Jan 6, 2018

+1 for this request plus updating the docs. It just took me an hour to find out that http://docs.traefik.io/configuration/entrypoints/#redirect-http-to-https:

To redirect an http entrypoint to an https entrypoint

is exactly not what it's doing (1.4.6) unless that entrypoint also has a frontend assigned. With defaultEntryPoints = ["https"] that's apparently not the case only the dummy frontend (as above) forces it. Very confusing for beginners.

@bweston92
Copy link

bweston92 commented Jan 23, 2018

The following should work but for some reason it redirects fine but then 404s on the HTTPS page, if I remove frontend.entryPoints and frontend.redirect it works on both HTTP and HTTPS. If I add https to the frontend.entryPoints it will infinitely redirect.

version: "3.1"
services:
  api:
    image: [radecated]
    networks:
      - [radecated]
      - traefik
    deploy:
      labels:
        - "traefik.port=8000"
        - "traefik.domain=[radecated].com"
        - "traefik.frontend.rule=Host:[radecated].com"
        - "traefik.frontend.entryPoints=http"
        - "traefik.frontend.redirect.entryPoint=https"
        - "traefik.frontend.passHostHeader=true"
        - "traefik.docker.network=traefik-net"
      placement:
        constraints:
          - node.labels.lw.role == web
      restart_policy:
        condition: on-failure
      resources:
        limits:
          cpus: '0.25'
          memory: 50M

@meskis
Copy link

meskis commented Jan 26, 2018

Same problem here.

@mariusstaicu
Copy link

same here, maybe I don't know how to use it

@DMW007
Copy link

DMW007 commented Jan 28, 2018

I had the same issue and found out that it works using SSLRedirect header. See my post in the pull request of traefik.frontend.redirect=https (which seems broken, I tried many ways but ended in 404 errors or infinity loops like you): #2133 (comment)

@andig
Copy link

andig commented Jan 28, 2018

See deitch‘s workaround above- the dummy fe/be fixed it for me.

@DMW007
Copy link

DMW007 commented Jan 28, 2018

The reason why I linked my solution is that I think it's uncomfortable to set this in the entire traefik-config. It's more flexible to have it in our docker-compose file. For example, we avoid old entrys in the traefik configuration when containers were removed.

@ldez
Copy link
Member

ldez commented Jan 29, 2018

@bweston92 @meskis @mariusstaicu @DMW007 @andig Could you open a dedicated issue ?

@ldez ldez self-assigned this Jan 29, 2018
@lucj
Copy link

lucj commented Jan 29, 2018

Got the same 404 returned after a redirect from http to http.
Noticed this message in the log:

level=debug msg="Unable to split host and port: address DOMAIN.TLD: missing port in address. Fallback to request host

Not sure if this is linked though.

@bweston92
Copy link

@lucj for me it works on https if I remove the redirect rule, is this the case for you?

@lucj
Copy link

lucj commented Jan 30, 2018 via email

@ldez
Copy link
Member

ldez commented Jan 30, 2018

@lucj could you go to the Traefik community Slack

@ldez
Copy link
Member

ldez commented Jan 30, 2018

For all, could stop the "hijacking" of this issue, thanks 🙏

@ldez
Copy link
Member

ldez commented Feb 25, 2018

@bweston92 @meskis @mariusstaicu @DMW007 @andig the infinite loop is fixed by #2929

@andig
Copy link

andig commented Mar 5, 2018

@ldez sorry if I was hijacking this issue. Does #2929 mean that the dummy frontend/backend workaround mentioned by @deitch is no longer required for redirecting to work?

@ldez
Copy link
Member

ldez commented Mar 5, 2018

@andig yes.

Edit: the original issue is not closed.

@deitch
Copy link
Contributor Author

deitch commented Mar 5, 2018

@ldez so now I can do just this and it will work?

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entrypoint = "https"
  [entryPoints.https]
  address = ":443"

If so, what released version of traefik supports it?

@andig
Copy link

andig commented Mar 5, 2018

If so, what released version of traefik supports it?

According to ed65d00 it should be 1.5.3, however I'm still having to use the dummy workaround with the 1.5.3 docker image. Otherwise http requests end in 404. Shall we open a separate issue for that?

@deitch
Copy link
Contributor Author

deitch commented Mar 5, 2018

Dunno. If the issue isn't fixed, then we should leave it open?

@andig
Copy link

andig commented Mar 5, 2018

If the issue isn't fixed, then we should leave it open?

I was wondering if this issue isn't more about your specific redirect rule as @ldez mentioned the hijacking. I'm just using

    [entryPoints.http.redirect]
    entryPoint = "https"

Can you confirm that it's not working for you either with 1.5.3?

@deitch
Copy link
Contributor Author

deitch commented Mar 5, 2018

@andig I will try it.

@deitch
Copy link
Contributor Author

deitch commented Mar 5, 2018

It works only partially. I definitely get the redirect when a frontend exists, using the following config:

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [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 = "/etc/tls//my.cert"
        keyFile = "/etc/tls/my.key"

However, if the frontend does not exist, it still returns a 404, which was the original issue I raised here.

FWIW, I am running it with compose using the following sample compose file, a variant on the compose in the examples/ directory:

traefik:
  image: traefik:1.5.3
  command: -c /etc/traefik.toml --logLevel=DEBUG
  ports:
    - "80:80"
    - "8080:8080"
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - $PWD/traefik.toml:/etc/traefik.toml
    - $PWD/certs:/etc/tls

whoami1:
  image: emilevauge/whoami
  labels:
    - "traefik.backend=whoami1"
    - "traefik.frontend.rule=PathPrefix:/foo"

whoami2:
  image: emilevauge/whoami
  labels:
    - "traefik.backend=whoami2"
    - "traefik.frontend.rule=Host:whoami.docker.localhost"

whoami3:
  image: emilevauge/whoami
  labels:
    - "traefik.backend=whoami2"
    - "traefik.frontend.rule=Host:whoami.docker.localhost"

If I curl to a real front-end, I get a proper 302. However, if I curl one that does not exist, it returns a 404. So I still need the dummy frontend. @lucj I can confirm it doesn't work, this issue still is open..

$ curl -i localhost:80/foo/
HTTP/1.1 302 Found
Location: https://localhost:443/foo/
Date: Mon, 05 Mar 2018 16:13:39 GMT
Content-Length: 5
Content-Type: text/plain; charset=utf-8

Found

$ curl -i localhost:80/foo/bar/1
HTTP/1.1 302 Found
Location: https://localhost:443/foo/bar/1
Date: Mon, 05 Mar 2018 16:13:44 GMT
Content-Length: 5
Content-Type: text/plain; charset=utf-8

Found

$ curl -i localhost:80/abc
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Mon, 05 Mar 2018 16:13:48 GMT
Content-Length: 19

404 page not found

That last one should be a a 302 redirect to https://localhost:443/abc (and then a 404 of course).

@rms1000watt
Copy link

rms1000watt commented Mar 14, 2018

@deitch What happens when you update your /etc/hosts with:

127.0.0.1 whoami.docker.localhost

Then run:

curl -i whoami.docker.localhost:80/abc

My suspicion is the hostname isn't matching your frontend rule:

traefik.frontend.rule=Host:whoami.docker.localhost

@andig
Copy link

andig commented Mar 15, 2018

@rms1000watt in my case I'm curling to an existing host, only on HTTP. Unless here is at least one frontend attached to the entrypoint it ends in 404 instead of redirect to https. I can provide the same details as deutch above if it helps.

@deitch
Copy link
Contributor Author

deitch commented Mar 15, 2018

@rms1000watt that is the point. I am intentionally curling to one that doesn't exist. Whether I have a matching frontend or no frontend, I want it to redirect (always return 302) with the redirect rule of

  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"

@ldez ldez added kind/enhancement a new or improved feature. status/0-needs-triage kind/bug/confirmed a confirmed bug (reproducible). and removed kind/bug/confirmed a confirmed bug (reproducible). kind/enhancement a new or improved feature. status/0-needs-triage labels Mar 24, 2018
@ktravelet
Copy link

Any update on this? What @deitch seems to be requesting should definitely be implemented. We want a "catch-all" redirect from HTTP -> HTTPS regardless if there's a configured service or not.

@andig
Copy link

andig commented Jul 11, 2018

It works only partially. I definitely get the redirect when a frontend exists, using the following config:

@deitch while playing with https://gist.github.com/dduportal/55fcb9e9d19c8f6694efa044714a04f8 I've realized that I can get the http->https redirect to always work even if not frontend is defined (actually, without any frontend defined).

The key point is that you'll need to include http in the default entrypoints if you don't want to create a frontend:

defaultEntryPoints = ["http", "https"]

The explanation is in https://docs.traefik.io/configuration/commons/#main-section:

defaultEntryPoints : Entrypoints to be used by frontends that do not specify any entrypoint.

@deitch
Copy link
Contributor Author

deitch commented Jul 15, 2018

The key point is that you'll need to include http in the default entrypoints if you don't want to create a frontend

Hmm, I didn't think of that (but probably should have).

Any downsides? Would it open anything else up that I wouldn't want?

@deitch
Copy link
Contributor Author

deitch commented Jul 15, 2018

I tried, still couldn't get it to work:

config:

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [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 = "/etc/tls/my.cert"
        keyFile = "/etc/tls/my.key"

and compose:

traefik:
  image: traefik:1.5.3
  command: -c /etc/traefik.toml --logLevel=DEBUG --docker
  ports:
    - "80:80"
    - "8080:8080"
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - $PWD/traefik.toml:/etc/traefik.toml
    - $PWD/certs:/etc/tls

whoami1:
  image: emilevauge/whoami
  labels:
    - "traefik.backend=whoami1"
    - "traefik.frontend.rule=PathPrefix:/foo"

whoami2:
  image: emilevauge/whoami
  labels:
    - "traefik.backend=whoami2"
    - "traefik.frontend.rule=Host:whoami.docker.localhost"

whoami3:
  image: emilevauge/whoami
  labels:
    - "traefik.backend=whoami2"
    - "traefik.frontend.rule=Host:whoami.docker.localhost"

and the test:

$ curl -i localhost:80/foo
HTTP/1.1 302 Found
Location: https://localhost:443/foo
Date: Sun, 15 Jul 2018 06:53:22 GMT
Content-Length: 5
Content-Type: text/plain; charset=utf-8

Found                                                                                                                                                                           $ curl -i localhost:80/bar
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Sun, 15 Jul 2018 06:53:27 GMT
Content-Length: 19

404 page not found

/foo works, as it has a front-end defined via the docker labels; /bar does not.

@andig
Copy link

andig commented Jul 15, 2018

@deitch I've tried your setup with 1.6.3. I can repro your results, but I'm not convinced that this is traefik's fault. Try

curl -v -H "Host:whoami.docker.localhost" http://localhost:80
* Rebuilt URL to: http://localhost:80/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> GET / HTTP/1.1
> Host:whoami.docker.localhost
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 302 Found
< Location: https://whoami.docker.localhost:443/
< Date: Sun, 15 Jul 2018 13:55:27 GMT
< Content-Length: 5
< Content-Type: text/plain; charset=utf-8
<
* Connection #0 to host localhost left intact

It seems it has to find any frontend which it can't do unless you supply the hostname?

@deitch
Copy link
Contributor Author

deitch commented Jul 15, 2018

Why would I need to supply a hostname? It is an option in the http protocol, not a requirement. In any case, if I define a catch-all frontend it does work.

@andig
Copy link

andig commented Jul 15, 2018

It is an option in the http protocol, not a requirement. In any case, if I define a catch-all frontend it does work.

Absolutely. I can only guess- but if there is no frontend at all (no dummy and no matching rule of any host) traefik might not do the redirect. Anyway, with matching hostname it's working for me.

@traefiker traefiker added this to the 1.7 milestone Oct 29, 2018
@traefiker
Copy link
Contributor

Closed by #4090.

@traefik traefik locked and limited conversation to collaborators Sep 1, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests