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

traefik removes trailing slash, redirect loop with nginx and others behind #3782

Closed
fRzzy opened this issue Aug 17, 2018 · 6 comments
Closed
Assignees
Milestone

Comments

@fRzzy
Copy link

fRzzy commented Aug 17, 2018

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

Bug

What did you do?

I have Traefik setup with consulCatalog as provider, Docker Registry 2 and other Nginx services all registered successfully.

Docker pull/push doesn't work, resulted in "Get /v2/: stopped after 10 redirects" error, tried to go to the same URL with browser resulted in redirect loop between "/v2" and "/v2/"

Go to any other site served by Nginx doesn't work if the URL doesn't end in an existed file. For example "/dir/index.html" works but "/dir" got redirected to "/dir/" by Nginx and again to "/dir" by Treafik.

What did you expect to see?

Traefik preserve and forward the exact request path.

What did you see instead?

Traefik remove trailing slash from path.

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

Version:      v1.7.0-rc3
Codename:     maroilles
Go version:   go1.10.3
Built:        2018-08-01_01:37:51PM
OS/Arch:      linux/amd64

What is your environment & configuration (arguments, toml, provider, platform, ...)?

defaultEntryPoints = ['https', 'http']

[entryPoints]
  [entryPoints.https]
  address = ':443'
    [entryPoints.https.tls]
    [entryPoints.https.proxyProtocol]
    trustedIPs = ['haproxy IP']
  [entryPoints.http]
  address = ':80'
    [entryPoints.http.redirect]
    entryPoint = 'https'

[api]
[ping]
[metrics]
  [metrics.prometheus]

[acme]
email = 'me@example.com'
entryPoint = 'https'
onHostRule = true
storage = '/acme/storage'

Traefik docker container started with:

"--consul --consul.endpoint='consul:8500' --consul.prefix='production/traefik' --consul.watch=true --consulcatalog --consulcatalog.endpoint='consul:8500' --consulcatalog.exposedbydefault=false --consulcatalog.watch=true --api"

If applicable, please paste the log output in DEBUG level (--logLevel=DEBUG switch)

sorry I can't turn on DEBUG log on production server

@fRzzy
Copy link
Author

fRzzy commented Aug 17, 2018

sorry I didn't mention that this only affect traefik:1.7-alpine, my main production server on traefik:1.6-alpine doesn't have this bug.

@fRzzy
Copy link
Author

fRzzy commented Aug 17, 2018

this issue is more complicated than I thought, it just happened again while on traefik:1.6-alpine, I can't remember what exactly happened during the time it worked until it didn't.

but I resolved the issue by recreating the container with traefik:1.7-alpine (wouldn't work from the start) then immediately recreate the container with traefik:1.6-alpine.

I've been on 1.7 RC3 for a few days and everything seems great, a day or two back I added consulcatalog provider (along with already running consul provider) and launched a few services. Maybe this is related.

@juliens juliens self-assigned this Aug 20, 2018
@juliens
Copy link
Member

juliens commented Aug 20, 2018

Thanks for your interest in the project.

Could you provide us with a detailed reproducible use case?

@fRzzy
Copy link
Author

fRzzy commented Aug 20, 2018

Hello, it hasn't happened again in the last two days, so I haven't been able to narrow down the cause, will keep my eyes on this and update when I can.

@holygeek
Copy link

holygeek commented Sep 29, 2018

Here's a repro for this issue:

Problem: Traefik redirect path with trailing slash to one that has no trailing slash with the following config:

[backends]
    [backends.foo]
    [backends.foo.servers.server1]
    url = "http://localhost:8080"
    weight = 1
    
[frontends]
    [frontends.foo]
    backend = "foo"
    [frontends.foo.routes.match]
    rule = "Path: /bar/{foo:.*}"   # this is what triggers the problem

e.g: When requesting for http://localhost/bar/a/ traefik responds with http 301 moved permanently to /bar/a.

Problem seem to be rooted in routeRegexpGroup.setMatch. This diff shows the printf debug that I inserted to show the problem:

diff --git vendor/github.com/containous/mux/regexp.go vendor/github.com/containous/mux/regexp.go
index da8114ca..64ea8b74 100644
--- vendor/github.com/containous/mux/regexp.go
+++ vendor/github.com/containous/mux/regexp.go
@@ -273,14 +273,17 @@ func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route)
                if len(matches) > 0 {
                        extractVars(path, matches, v.path.varsN, m.Vars)
                        // Check if we should redirect.
                        if v.path.strictSlash {
                                p1 := strings.HasSuffix(path, "/")
                                p2 := strings.HasSuffix(v.path.template, "/")
                                if p1 != p2 {
+                                       fmt.Printf("path          %s\n", path)
+                                       fmt.Printf("path.template %s\n", v.path.template)
+
                                        u, _ := url.Parse(req.URL.String())
                                        if p1 {
                                                u.Path = u.Path[:len(u.Path)-1]
                                        } else {
                                                u.Path += "/"
                                        }
                                        m.Handler = http.RedirectHandler(u.String(), 301)

Request to path with trailing slash is erroneously redirected to one without:

$ curl -v http://traefik:8181/bar/a/           
*   Trying 127.0.0.2...
* Connected to traefik (127.0.0.2) port 8181 (#0)
> GET /bar/a/ HTTP/1.1
> Host: traefik:8181
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=utf-8
< Location: /bar/a
< Date: Sat, 29 Sep 2018 15:34:05 GMT
< Content-Length: 41
< 
<a href="/bar/a">Moved Permanently</a>.

Here's the corresponding log from traefik:

$ src/github.com/containous/traefik/traefik -c traefik.toml --accesslog.                                                                 filePath=
path          /bar/a/
path.template /bar/{foo:.*}
127.0.0.1 - - [29/Sep/2018:15:23:14 +0000] "GET /bar/a/ HTTP/1.1" - - "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36            (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" 1 - - 0ms
127.0.0.1 - - [29/Sep/2018:15:23:14 +0000] "GET /bar/a HTTP/1.1" 200 6 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36           (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" 2 "foo" "http://localhost:8080" 1ms

The check for strings.HasSuffix(..., "/") fails for path and path.template hence the erroneous redirect.

@nmengin nmengin added area/rules kind/bug/possible a possible bug that needs analysis before it is confirmed or fixed. and removed contributor/waiting-for-feedback status/0-needs-triage labels Oct 1, 2018
@juliens juliens added kind/bug/confirmed a confirmed bug (reproducible). and removed kind/bug/possible a possible bug that needs analysis before it is confirmed or fixed. labels Oct 17, 2018
@traefiker traefiker added this to the 1.7 milestone Oct 17, 2018
@traefiker
Copy link
Contributor

Closed by #4062.

@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

5 participants