tomMoulard / htransformation

A Traefik plugin to change on the fly header's value of a request
MIT License
77 stars 13 forks source link

Plugin is broken since traefik v2.8.2 #34

Closed leshik closed 1 year ago

leshik commented 2 years ago

Here's the issue: https://github.com/traefik/traefik/issues/9269 Just thought it might be worth letting you know @tomMoulard

tomMoulard commented 2 years ago

Hello @leshik,

This is a duplicate of #33.

Your RewriteValueRule for X-Forwarded-Host is what caused the issue. It is not related with traefik whatsoever.

If you want to fix the issue, feel free to use the latest tag(v0.2.6 at the moment) of this plugin that should fix your issue.

leshik commented 2 years ago

Hey @tomMoulard , that's a different issue unrelated to the previous one that I've reported. Please, take a look.

tomMoulard commented 2 years ago

Using only this rule, and changing from v0.2.5, v0.2.6, I can see that v0.2.6 fixes the panic when serving the request. I do not see any impact of the Traefik version with v0.2.6.

tomMoulard commented 2 years ago

Can you provide a reproducible use case with v0.2.6 ?

leshik commented 2 years ago

@tomMoulard the issue that I reported in Traefik repo is with v0.2.6.

tomMoulard commented 2 years ago

v0.2.6 was released 23 min ago, after your issue on traefik was created

leshik commented 2 years ago

@tomMoulard your fix in master, which fixes missing continue statement in if, was published 15 days ago, before even v2.8.2 was released. I use your plugin from master, not a tag. And it worked fine for me till yesterday until I upgraded to v2.8.3. Please, try with my config from the issue with v2.8.1 and v2.8.3 to see the difference.

tomMoulard commented 2 years ago
Here's my configuration My `docker-compose.yml` file: ```yml version: '3.9' services: traefik: image: traefik:v2.8.1 command: - --providers.docker - --providers.file.directory=/dyn - --experimental.plugins.htransformation.modulename=github.com/tomMoulard/htransformation - --experimental.plugins.htransformation.version=v0.2.6 ports: - "80:80" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock - ./dyn:/dyn whoami: image: traefik/whoami labels: traefik.http.routers.whoami.rule: Host(`whoami.localhost`) traefik.http.routers.whoami.middlewares: my-htransformation@file ``` My `dyn/htransformation.yml` file: ```yml http: middlewares: my-htransformation: plugin: htransformation: Rules: - Header: X-Forwarded-Host Type: RewriteValueRule Value: "api.(.*)" ValueReplace: "$1" - Header: X-Client-Subdomain Type: Join Sep: "." HeaderPrefix: "^" Values: - "^X-Forwarded-Host" - Header: X-Client-Subdomain Type: Rename Value: X-Forwarded-Host ```

Here's my use case:

> docker compose up -d
[+] Running 3/3
 ⠿ Network foo_default      Created                                             0.1s
 ⠿ Container foo-traefik-1  Started                                             0.8s
 ⠿ Container foo-whoami-1   Started                                             0.8s
> curl whoami.localhost
Name: whoami
Hostname: ce2157198dcb
IP: 127.0.0.1
IP: 172.18.0.2
RemoteAddr: 172.18.0.3:37746
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/7.79.0-DEV
Accept: application/json, application/xml, text/plain, */*
Accept-Encoding: gzip
X-Forwarded-For: 172.18.0.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: f0bf1f980c13
X-Real-Ip: 172.18.0.1

> sed -i 's/traefik:v2.8.1/traefik:v2.8.3/g' docker-compose.yml
> docker compose up -d
[+] Running 3/3
 ⠿ Network foo_default      Created                                             0.1s
 ⠿ Container foo-traefik-1  Started                                             0.7s
 ⠿ Container foo-whoami-1   Started                                             0.8s
> curl whoami.localhost
Name: whoami
Hostname: 5bbc7a27e6a7
IP: 127.0.0.1
IP: 172.19.0.2
RemoteAddr: 172.19.0.3:34170
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/7.79.0-DEV
Accept: application/json, application/xml, text/plain, */*
Accept-Encoding: gzip
X-Forwarded-For: 172.19.0.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 50a7599d8438
X-Real-Ip: 172.19.0.1

>

I see no difference between traefik version whatsoever

leshik commented 2 years ago

@tomMoulard What are you testing here? Your plugin rules are not even evaluated in your test setup. Please, replace api.(.*) with whoami.(.*), and use -H 'X-Client-Subdomain: custom' for curl.

tomMoulard commented 2 years ago

Ok, here's what I get now:

> docker compose up -d
[+] Running 3/3
 ⠿ Network foo_default      Created                              0.1s
 ⠿ Container foo-traefik-1  Started                              0.7s
 ⠿ Container foo-whoami-1   Started                              0.7s
> curl -H 'X-Client-Subdomain: custom' whoami.localhost
Name: whoami
Hostname: 6dfc5f0a5a5c
IP: 127.0.0.1
IP: 172.23.0.2
RemoteAddr: 172.23.0.3:36700
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/7.79.0-DEV
Accept: application/json, application/xml, text/plain, */*
Accept-Encoding: gzip
X-Forwarded-For: 172.23.0.1
X-Forwarded-Host: custom.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: 2b1aec4302b2
X-Real-Ip: 172.23.0.1

> sed -i 's/traefik:v2.8.1/traefik:v2.8.3/g' docker-compose.yml
> docker compose down && docker compose up -d
[+] Running 3/3
 ⠿ Container foo-traefik-1  Removed                              0.5s
 ⠿ Container foo-whoami-1   Removed                              0.4s
 ⠿ Network foo_default      Removed                              0.2s
[+] Running 3/3
 ⠿ Network foo_default      Created                              0.1s
 ⠿ Container foo-whoami-1   Started                              0.8s
 ⠿ Container foo-traefik-1  Started                              0.8s
> curl -H 'X-Client-Subdomain: custom' whoami.localhost
Name: whoami
Hostname: d5a9381a75bf
IP: 127.0.0.1
IP: 172.24.0.2
RemoteAddr: 172.24.0.3:32962
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/7.79.0-DEV
Accept: application/json, application/xml, text/plain, */*
Accept-Encoding: gzip
X-Forwarded-For: 172.24.0.1
X-Forwarded-Host: custom.║24║^X-Forwarded-Host
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: b31ed92ea3fb
X-Real-Ip: 172.24.0.1

The X-Forwarded-Host has a value of custom.║24║^X-Forwarded-Host which is wrong. A workaround can be to define the rule as:

- Header: X-Client-Subdomain
  Type: Join
  Sep: "."
  HeaderPrefix: "^"
  Values: "^X-Forwarded-Host" # <-- THIS IS THE WORKAROUND
leshik commented 2 years ago

@tomMoulard why is this? Isn't Values supposed to be an array? Per documentation it is. Why the change in behavior between traefik versions?

leshik commented 2 years ago

@tomMoulard here is an example config that is still broken:

http:
  middlewares:
    my-htransformation:
      plugin:
        htransformation:
          Rules:
            - Header: X-Forwarded-Host
              Type: RewriteValueRule
              Value: "whoami.(.*)"
              ValueReplace: "$1"

            - Header: X-Client-Subdomain
              Type: Join
              Sep: "."
              HeaderPrefix: "^"
              Values:
                - testvalue
                - "^X-Forwarded-Host"

            - Header: X-Client-Subdomain
              Type: Rename
              Value: X-Forwarded-Host

And the only fix is to revert https://github.com/traefik/traefik/pull/9224. Please, reopen https://github.com/traefik/traefik/issues/9269.

tomMoulard commented 2 years ago

If you want a workaround, try with this rule:

- Header: X-Client-Subdomain
  Type: Join
  Sep: "."
  HeaderPrefix: "^"
  Values: "^X-Forwarded-Host,testvalue" # <-- THIS IS THE WORKAROUND
tomMoulard commented 1 year ago

Closing this issue as paerser was fixed.