gravitational / teleport

The easiest, and most secure way to access and protect all of your infrastructure.
https://goteleport.com
GNU Affero General Public License v3.0
17.41k stars 1.74k forks source link

Rewrite the "Location" header on redirect responses, replacing all host matches with the public address #43280

Open BulatSaif opened 3 months ago

BulatSaif commented 3 months ago

What would you like Teleport to do?

The current implementation is good at catching simple redirects, but it fails to handle more complex redirection that usually occurs if application has it own login page.

For simplicity I will use grafana app:

  apps:
    # Name of the application. Used for identification purposes.
  - name: "grafana"
    # Free-form application description.
    description: "This is an internal Grafana instance"
    # URI and port the application is available at.
    uri: "https://grafana.internal.dev"
    # Optional application public address to override.
    public_addr: "grafana.teleport.example.com"
    # Rewrites section.
    rewrite:
      # Rewrite the "Location" header on redirect responses replacing the
      # host with the public address of this application.
      redirect:
      - "grafana.internal.dev"

Current use case: Request: https://grafana.teleport.example.com/a

Response(app) : https://grafana.internal.dev/new-a Response(teleport): https://grafana.teleport.example.com/new-a Works as expected.

New use case: Request: https://grafana.teleport.example.com/a

Response(app): https://grafana.internal.dev/login?redirect=https%3A%2F%2Fgrafana.internal.dev%2Fnew-a Response(teleport): https://grafana.teleport.example.com/login?redirect=https%3A%2F%2Fgrafana.internal.dev%2Fnew-a

As you can see, grafana.internal.dev is set twice, both as the host and as part of the path. Teleport will replace only the host and leave the domain in the path, which will lead to an incorrect redirect later.

What problem does this solve? This will allow using Teleport with apps that are not aware of Teleport proxy.

webvictim commented 3 months ago

https://github.com/gravitational/teleport/pull/34705 would probably allow this, but hasn't moved forward for a while.

BulatSaif commented 3 months ago

34705 would probably allow this, but hasn't moved forward for a while.

PR #34705 is certainly useful, and I would appreciate having options to modify the body in future updates. However, it does not address my current issue with headers. To address this, I've created a small Proof of Concept (PoC) GitHub PR #43300. The idea behind this PoC is to replace all occurrences of hosts in the "Location" header.

BulatSaif commented 2 months ago

I updated my GitHub PR #43300 and added an alternative rewrite redirectRegex. It's designed to be more powerful and readable. Below are two configurations that achieve the same replacement:

Configuration 1:

apps:
  - name: "MyName"
    public_addr: "mydomain"
    rewrite:
      # Replace domain in Location header
      redirect:
      - "localhost"

Configuration 2:

apps:
  - name: "MyName"
    rewrite:
      # Replace Location header using regex
      redirectRegex:
        regex: ^http[s]?://localhost/(.*)
        replacement: http://mydomain/${1}

Here's a configuration that covers my use case, replacing all occurrences of localhost in the header:

apps:
  - name: "MyName"
    rewrite:
      # Replace Location header using regex
      redirectRegex:
        regex: localhost
        replacement: mydomain