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

How to disable URL decoding (slash escaping) for specific HTTPRoutes ONLY? #4848

Open
ferdinandosimonetti opened this issue Dec 4, 2024 · 2 comments

Comments

@ferdinandosimonetti
Copy link

We installed Envoy Gateway version v1.2.1 (docker.io/envoyproxy/gateway:v1.2.1, envoyproxy/envoy:distroless-v1.32.1).

Here are the configurations at EnvoyProxy, GatewayClass and Gateway level.

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: private-dev
  namespace: envoy-gateway-system
spec:
  logging:
    level:
      default: debug
  mergeGateways: true
  provider:
    kubernetes:
      envoyDeployment:
        container:
          resources:
            limits:
              cpu: 150m
              memory: 500Mi
            requests:
              cpu: 150m
              memory: 500Mi
        pod:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: node.type
                    operator: In
                    values:
                    - apps.low
          annotations:
            prometheus.io/port: "19001"
            prometheus.io/scrape: "true"
          labels: {}
          tolerations:
          - effect: NoSchedule
            key: node.type
            operator: Equal
            value: apps.low
          topologySpreadConstraints: []
        replicas: 2
      envoyService:
        annotations:
          service.beta.kubernetes.io/azure-load-balancer-internal: "true"
          service.beta.kubernetes.io/azure-load-balancer-ipv4: 10.100.62.11
        externalTrafficPolicy: Local
        type: LoadBalancer
    type: Kubernetes
  routingType: Service
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: private-dev
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
  parametersRef:
    group: gateway.envoyproxy.io
    kind: EnvoyProxy
    name: private-dev
    namespace: envoy-gateway-system
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway-private
  namespace: balancers-dev
spec:
  gatewayClassName: private-dev
  listeners:
  - allowedRoutes:
      namespaces:
        from: All
    name: http
    port: 80
    protocol: HTTP
  - allowedRoutes:
      namespaces:
        from: All
    name: https
    port: 443
    protocol: HTTPS
    tls:
      certificateRefs:
      - group: ""
        kind: Secret
        name: cf-wildcard-cert-secret
      mode: Terminate
...

We have an HTTPRoute for reaching a RabbitMQ management Web UI

---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  labels:
  name: rabbit-route
  namespace: rabbit-dev
spec:
  hostnames:
  - rabbit-dev.farmhub.nadara.com
  - rabbit-dev.farmhub.renantis.com
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: gateway-private
    namespace: balancers-dev
    sectionName: https
  rules:
  - backendRefs:
    - group: ""
      kind: Service
      name: esb
      port: 15672
      weight: 1
    matches:
    - path:
        type: PathPrefix
        value: /

but, unfortunately, some of our Exchanges got slashes in their names (don't ask, don't even ask, please).

image

And so, their corresponding detail URLs are built this way

image

and, without this ClientTrafficPolicy applied to the whole Gateway

---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
  name: rabbit-undecode
  namespace: balancers-dev
spec:
  path:
    escapedSlashesAction: KeepUnchanged
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: gateway-private

we end up with Envoy decoding the %2F in / so that the URL passed to the destination backend becomes

https://rabbit-dev.farmhub.nadara.com/#/exchanges/farmhub/esb/exchange/agent.jobs

instead of

https://rabbit-dev.farmhub.nadara.com/#/exchanges/farmhub/esb%2Fexchange%2Fagent.jobs

How can we avoid preparing another Gateway (thus, consuming another private Azure IP and LoadBalancer for its exposure) only to keep our RabbitMQ Web UI HTTPRoute functioning?

Thanks in advance.
I'm more than willing to provide clarifications.

@arkodg
Copy link
Contributor

arkodg commented Dec 4, 2024

since the feature lives in the HCM (attached to an xds listener) https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#extensions-filters-network-http-connection-manager-v3-httpconnectionmanager, its can't be set on a per route level, can you instead use a different hostname or port for that traffic, you could then attach the HTTPRoute to that specific listener and attach the CTP to a speciific Gateway API listener using sectionName

@tekulvw
Copy link

tekulvw commented Dec 15, 2024

ArgoCD is also extremely prone to this problem. It will make requests with a Helm repo URL encoded in the request URL anytime the "Parameters" tab is accessed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants