Open arkodg opened 9 months ago
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
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.
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
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
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"`
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.path
to 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
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.path
to 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.
/assign @lianglli
The Kubernetes project currently lacks enough contributors to adequately respond to all issues.
This bot triages un-triaged issues according to the following rules:
lifecycle/stale
is appliedlifecycle/stale
was applied, lifecycle/rotten
is appliedlifecycle/rotten
was applied, the issue is closedYou can:
/remove-lifecycle stale
/close
Please send feedback to sig-contributor-experience at kubernetes/community.
/lifecycle stale
/remove-lifecycle stale
@lianglli were you able to make any progress on a GEP for this feature?
@lianglli were you able to make any progress on a GEP for this feature?
Yes, I will create a GEP firstly.
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.
Yes, get it.
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"
@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.
Such feature can be helpful for two use cases:
Envoy Gateway just added this as a filter in v1.2, here's an example
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:
HTTPRoute