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

Support DirectResponse HTTPRouteFilter #2826

Open
arkodg opened this issue Feb 28, 2024 · 17 comments
Open

Support DirectResponse HTTPRouteFilter #2826

arkodg opened this issue Feb 28, 2024 · 17 comments
Assignees
Labels
kind/feature Categorizes issue or PR as related to a new feature. triage/needs-information Indicates an issue needs more information in order to work on it.

Comments

@arkodg
Copy link
Contributor

arkodg commented Feb 28, 2024

What would you like to be added:

A new HTTPRouteFilter that allows users to directly respond to requests with a specific body and status w/o sending it to a backend.

Existing implementations that have this feature
Istio - https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPDirectResponse
Contour https://projectcontour.io/docs/1.28/config/api/#projectcontour.io/v1.HTTPDirectResponsePolicy

Why this is needed:

  • Adding a catch-all / fallback route to HTTPRoute
@arkodg arkodg added the kind/feature Categorizes issue or PR as related to a new feature. label Feb 28, 2024
@arkodg arkodg changed the title Support DIrectResponse HTTPRouteFilter Support DirectResponse HTTPRouteFilter Feb 28, 2024
@howardjohn
Copy link
Contributor

Obviously Istio has this as you noted, so I am in favor of this, but just want to note its a tricky tradeoff of how big we allow. Good for simple "return 404" but anything more complex becomes a bit dicey

@youngnick
Copy link
Contributor

Yes, I think that anything we add will need to have a strict limit about size. And an explanation that no, we really won't increase the limit.

@lianglli
Copy link

Why this is needed:

For example, some hosts want to disable crawl any of the website's pages.
If the request path is "/robots.txt", the gateway will return 200 OK with body
"User-agent: *
Disallow: /".

Based on the following HTTPRoute, the host "http.route.robots.com" with path "/robots.txt" will be disallowed always.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http-route-cookie
spec:
  hostnames:
  - http.route.robots.com
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: http-gateway
  rules:
  - backendRefs:
    - kind: Service 
       name: http-route-production
       port: 7001
    matches:
    - path:
         type: PathPrefix
         value: /
  - directResponse:
    - status: 200
       body: 
         string: "User-agent: *\nDisallow: /"
    matches:
    - path:
         type: Exact
         value: /robots.txt

@lianglli
Copy link

lianglli commented Mar 25, 2024

Why this is needed:

Moreover, if there is a L7 attack, the directResponse will return 404 based on a new HTTPRoute asap.

Then, the upstream service will be able to process the normal requests without any changes.

E.g., upstream service "http-route-production" try to add a HTTPRoute for protecting it against L7 attack ("http.route.com/acs") specifically:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http-route-cookie
spec:
  hostnames:
  - http.route.com
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: http-gateway
  rules:
  - backendRefs:
    - kind: Service 
       name: http-route-production
       port: 7001
    matches:
    - path:
         type: PathPrefix
         value: /
  - directResponse:
    - status: 404
    matches:
    - path:
         type: Exact
         value: /acs

@lianglli
Copy link

lianglli commented Mar 25, 2024

Yes, I think that anything we add will need to have a strict limit about size. And an explanation that no, we really won't increase the limit.

Yes, it is.
The directResponse should be a response with small body or no body.

E.g.,

// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=128
Value string `json:"value"`

@shaneutt shaneutt added the triage/needs-information Indicates an issue needs more information in order to work on it. label Mar 25, 2024
@NissesSenap
Copy link

I also have a use-case for this.
I have an application with x number of paths, and I want all of them to be exposed to the internet except 1.

Today I can write a httpRoute with rules.matches.pathto whitelist all paths I want to be available, but this becomes very boring if I have an app with a long list of paths. So instead of doing whitelist/allowlist, I would like to be able to do blacklist/blocklist.

For example:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: echo
spec:
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: http-gateway
  rules:
    - directResponse:
      - status: 404
      matches:
      - path:
           type: Exact
           value: /secretPath
    - backendRefs:
        - name: echo
          kind: Service
          port: 1027

@lianglli
Copy link

I also have a use-case for this. I have an application with x number of paths, and I want all of them to be exposed to the internet except 1.

Today I can write a httpRoute with rules.matches.pathto whitelist all paths I want to be available, but this becomes very boring if I have an app with a long list of paths. So instead of doing whitelist/allowlist, I would like to be able to do blacklist/blocklist.

For example:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: echo
spec:
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: http-gateway
  rules:
    - directResponse:
      - status: 404
      matches:
      - path:
           type: Exact
           value: /secretPath
    - backendRefs:
        - name: echo
          kind: Service
          port: 1027

The directResponse of HTTPRouteFilter is able to fit your requirement.

I'm working on a GEP for directResponse that focuses on background and past implementations first.

@lianglli
Copy link

/assign @lianglli

@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue as fresh with /remove-lifecycle stale
  • Close this issue with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jul 9, 2024
@jbohanon
Copy link

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Jul 16, 2024
@jbohanon
Copy link

@lianglli were you able to make any progress on a GEP for this feature?

@lianglli
Copy link

@lianglli were you able to make any progress on a GEP for this feature?

Yes, I will create a GEP firstly.

@youngnick
Copy link
Contributor

As for other Provisional GEPs, the critical parts are What this is, Why we need it, and Who it's for, along with what is currently supported in various data planes and/or implementations. Would love to see a Provisional GEP PR like that.

@lianglli
Copy link

Yes, get it.

@gganley
Copy link

gganley commented Sep 16, 2024

Per suggestion by Mike Morris in the Istio slack I'd like to add my use case

Right now we're moving from VMs fronted by HAProxy to K8s using K8s G8way + Istio (plus other stuff). One of the hang ups I've encountered in trying to recreate our existing behavior is the lack errorfile directive in haproxy or return in nginx. This allows an inline of an error code and a body. To recreate this in the existing k8s gateway api I need to create a null-backend service whose only job is to act as the backend to return 403 "<html><body><h1>\n403 Forbidden</h1>Request forbidden by administrative rules.\n</body></html>\n"

frontend fe_https
    default_backend null
    # lots of acls either http-request deny or allowing to specific backends
    acl deny path_beg /edge/api/internal
    acl api_backend path_beg /edge/api
    http-request deny if deny
    use_backend api if api_backend

backend api
    server edge-api ...

backend null
    errorfile 403 /usr/local/etc/haproxy/403.http
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: translation
spec:
  parentRefs:
  - name: external
  rules:
  - matches: # deny
    - path:
        type: PathPrefix
        value: /edge/api/internal
    filters:
    - type: DirectResponse
      directResponse:
        statusCode: 403
        body:
          string: "Finger wag"
  - matches: # api
    - path:
        type: PathPrefix
        value: /edge/api
    backendRefs:
    - name: edge-api
      port: 8080
  - filters: # default_backend
    - type: DirectResponse
      directResponse:
        statusCode: 403
        body:
          string: "Finger wag"
  

@bravenut
Copy link

bravenut commented Sep 16, 2024

@gganley we have a very similar use case and I would also appreciate the direct response filter within HTTPRoute a lot. Instead of using a custom service that returns arbitrary responses, we're applying an Envoy filter custom resource to the gateway, where you can simply patch the route configuration to use the direct response, works like a charm, but it would be nice to accomplish this without additional overhead and just configure it in the HTTPRoute.

@AhmadMS1988
Copy link

Such feature can be helpful for two use cases:

  1. API sunsetting without modifying applications
  2. The need of returning dummy fixed response for network or ingress health checking from external.
    Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. triage/needs-information Indicates an issue needs more information in order to work on it.
Projects
None yet
Development

No branches or pull requests