envoy icon indicating copy to clipboard operation
envoy copied to clipboard

External Authz filter is not rewriting Host and does not work for an Ext server behind LB

Open juanmolle opened this issue 1 year ago • 6 comments

Title: External Authz filter is not rewriting Host and does not work for an Ext server behind LB

Description: When the filter is doing the request to the http external auth server, it copies all the original request headers ( path is an special case, a prefix is added if it set in config) If the external service is under a LB, Host is not rewrite and 404 is always returned. My first though was HOST could be used during auth logic. but grpc is apparently not changing it. Is this a miss-configuration? do I miss something, or a new config option in the filter to replace it and copy the original host in an x-original-host header or similar?

Repro steps: Start envoy with config make a call

curl -XGET -H "Authorization: Bearer token1" http://localhost:8000/ -I

Request to ext auth contains HOST: localhost:8088 server behind LB replay 404

Config:

static_resources:
 listeners:
 - address:
     socket_address:
       address: 0.0.0.0
       port_value: 8000
   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
         codec_type: AUTO
         stat_prefix: ingress_http
         route_config:
           name: local_route
           virtual_hosts:
           - name: upstream
             domains:
             - "*"
             routes:
             - match:
                 prefix: "/"
               route:
                 host_rewrite_literal: httpbin.org
                 cluster: httpbin.default.svc
         http_filters:
         - name: envoy.filters.http.ext_authz
           typed_config:
             "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
             transport_api_version: V3
             allowed_headers:
               patterns:
                 - exact: authorization
             http_service:
               server_uri:
                 uri: <auth-server>
                 cluster: ext-authz-svc
                 timeout: 5s
         - name: envoy.filters.http.router
           typed_config:
             "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

 clusters:
 - name: httpbin.default.svc
   type: LOGICAL_DNS
   connect_timeout: 5s
   dns_lookup_family: V4_ONLY
   transport_socket:
     name: envoy.transport_sockets.tls
     typed_config:
       '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
       common_tls_context:
         validation_context:
           trusted_ca:
             filename: /etc/ssl/certs/ca-certificates.crt
           match_typed_subject_alt_names:
             - san_type: DNS
               matcher:
                 exact: httpbin.org
                 ignore_case: true
       sni: httpbin.org
   load_assignment:
     cluster_name: httpbin.default.svc
     endpoints:
       - lb_endpoints:
           - endpoint:
               address:
                 socket_address:
                   address: httpbin.org
                   port_value: 443
   typed_extension_protocol_options:
     envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
       '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
       common_http_protocol_options:
         idle_timeout: 60s
       auto_config: {}
 - name: ext-authz-svc
   type: LOGICAL_DNS
   connect_timeout: 5s
   dns_lookup_family: V4_ONLY
   transport_socket:
     name: envoy.transport_sockets.tls
     typed_config:
       '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
       common_tls_context:
         validation_context:
           trusted_ca:
             filename: /etc/ssl/certs/ca-certificates.crt
           match_typed_subject_alt_names:
             - san_type: DNS
               matcher:
                 exact: <auth-server>
                 ignore_case: true
       sni: <auth-server>
   load_assignment:
     cluster_name: ext-authz-svc
     endpoints:
       - lb_endpoints:
           - endpoint:
               hostname: <auth-server>
               address:
                 socket_address:
                   address: <auth-server>
                   port_value: 443
   typed_extension_protocol_options:
     envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
       '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
       common_http_protocol_options:
         idle_timeout: 60s
       auto_config: {}

juanmolle avatar May 15 '24 12:05 juanmolle

@esmet

ravenblackx avatar May 16 '24 15:05 ravenblackx

Is this a bug, or a misconfiguration?

juanmolle avatar May 27 '24 17:05 juanmolle

@tyxia since @esmet didn't respond (based on CODEOWNERS of ext_authz)

ravenblackx avatar May 28 '24 14:05 ravenblackx

When clientMatcher is empty, the HOST will NOT be added to client response https://github.com/envoyproxy/envoy/blob/main/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc#L149-L150

You will need to configure something like allowed_client_headers\ allowed_client_headers_on_success to enable this

tyxia avatar May 28 '24 15:05 tyxia

My problem is that host is the client host and it is not rewrited. in route we have the possibility to set auto_host_rewrite = true. and the request to the upstream will contain the destination host. then is the upstream is behind a LB it will find the route. but in this case, the filter directly call the auth server (using the client host) and there is no possibility to rewrite_host. then fails with 404

juanmolle avatar May 28 '24 20:05 juanmolle

@tyxia do I explain correctly the issue?

juanmolle avatar May 30 '24 14:05 juanmolle

for grpc service there is a config to set the authority for the POST resquest to the server, probably we could add it to the http service case. and eventually copy the original :authority into another header if the server needs to use it.

https://github.com/envoyproxy/envoy/blob/9f494c0ba71f1a6d11864d8c4fc9afe298e4339a/api/envoy/config/core/v3/grpc_service.proto#L43

juanmolle avatar May 31 '24 15:05 juanmolle

@tyxia do you think it is a good idea to add a similar config for http server type? If you do, I can submit a PR with a proposal for that

juanmolle avatar Jun 12 '24 12:06 juanmolle

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.

github-actions[bot] avatar Jul 12 '24 16:07 github-actions[bot]

This issue has been automatically closed because it has not had activity in the last 37 days. If this issue is still valid, please ping a maintainer and ask them to label it as "help wanted" or "no stalebot". Thank you for your contributions.

github-actions[bot] avatar Jul 19 '24 20:07 github-actions[bot]