envoy path and port rewrite

50 views Asked by At

I need to forward requests to target cluster/ backend service dynamically depending upon custom headers... I have following headers in my original request that hits envoy listener

X-Fwd-Host
X-Fwd-Port
X-Fwd-Path

I'm able to re-write the host using host_rewrite_header: X-Fwd-Host With this i get the following entry in envoy log

"GET /hello HTTP/1.1" 503 UF 0 91 5005 - "-" "-" "60c1023b-86f9-49e3-8c30-b9f04e02ddbe" "backservice-hello-dotnet.default.svc.cluster.local" "10.101.69.26:80"

looking at it you can see that its trying to redirect "/hello" to "backservice-hello-dotnet.default.svc.cluster.local" on port 80

but actually i want it to redirect to "backservice-hello-dotnet.default.svc.cluster.local:6001/hello" here 6001 needs to be taken from header X-Fwd-Port

and /hello will be taken from X-Fwd-Path

how to do that?

here is my complete envoy.yaml file

admin:
  address:
    socket_address:
      protocol: TCP
      address: 0.0.0.0
      port_value: 9901
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 9001
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: egress_http
          access_log:
          - name: envoy.access_loggers.stdout
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
                #log_format: format: "%[START_TIME]ms %req[id]%RESP[%STATUS]% [PROTOCOL]% %[REQUEST_SCHEME]% %[REQUEST_METHOD]% %[REQUEST_URL]% %[UPSTREAM_STATUS]% %[RESP_CONTENT_LENGTH]% %[RESP_DURATION_MS]% %[TERMINAL_PROTOCOL]% %[USER_AGENT]%\n"
          - name: envoy.access_loggers.stderr
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StderrAccessLog
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: dynamic_forward_proxy_cluster
                  host_rewrite_header: X-Fwd-Host
          http_filters:
          - name: envoy.filters.http.dynamic_forward_proxy
            typed_config:
              '@type': type.googleapis.com/envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig
              dns_cache_config:
                name: dynamic_forward_proxy_cache_config
                dns_lookup_family: V4_ONLY
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
  - name: dynamic_forward_proxy_cluster
    lb_policy: CLUSTER_PROVIDED
    cluster_type:
      name: envoy.clusters.dynamic_forward_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig
        dns_cache_config:
          name: dynamic_forward_proxy_cache_config
          dns_lookup_family: V4_ONLY
  - name: backend_cluster
    connect_timeout: 3s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: backend_cluster
      endpoints: []
1

There are 1 answers

0
Raheel On

I got the answer... as mentioned here https://github.com/envoyproxy/envoy/issues/8768#issuecomment-549179275

dns will take care of extracting the port from host, so I added a new custom header X-Fwd-HostAndPort that has value something like myservice:myport and used that in host_rewrite_header: X-Fwd-HostAndPort

Also, there is no need to update the path, by default envoy will forward the request to the same path that was requested. However, if there is a need to change the path during forwarding, we have to use prefix_rewrite or regex_rewrite.