Skip to content

External Processor skipped when Host header is missing #38022

Description

@e-n-0

Title: External Processor skipped when Host header is missing

Description:

When the External Processing filter is configured, all requests and responses should be routed through the External Processor. However, if a malformed request is sent, Envoy bypasses the External Processor and forwards the request directly to the backend server, resulting in a 400 response from the backend. That response is however correctly routed through the External Processor.

Repro steps:

  1. Start envoy with an External Processor filter (envoy config below in the provided files)

  2. Start services:

  • Start a basic External Processor grpc on port 443
  • Start a basic HTTP app (for instance I took a really basic http app that returns 200 every time jasonrm/dummy-server)
  1. Send a malformed request (in this case without the Host header)
cat <(echo 'GET / HTTP/1.1\r\n\r\n') - | nc localhost 80
  1. The request is sent to the backend server. The backend server answer with a 400 that is routed through the External Processor.

Admin and Stats Output:
Logs:

I couldn't run the Envoy_collect tool so I gathered all information from endpoint manually and copy pasted the logs.
Envoy has been set to trace level mode.

envoy_issue.tar.gz

In the log I spotted this line:

[17][debug][http] [source/common/http/filter_manager.cc:1075] [Tags: "ConnectionId":"4","StreamId":"16013602903896685747"] Sending local reply with details missing_host_header

And I strongly think that is related. My guess is that a local reply is generated and never sent to the actual External Processor when a Host header is missing. If I set other headers to the shell command above, the issue stays the same, but as soon I add the Host header, the request is sent to the External Processor.

Config:

Envoy configuration with a External Processor filter: `envoy.yaml`
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 80
      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: ingress_http
                codec_type: AUTO
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: backend
                      domains:
                        - "*"
                      routes:
                        - match:
                            prefix: "/"
                          route:
                            cluster: web_service
                http_filters:
                  - name: envoy.filters.http.ext_proc
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
                      grpc_service:
                        envoy_grpc:
                          cluster_name: ext_proc_cluster
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
    - name: web_service
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: web_service
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: webserver
                      port_value: 8080

    - name: ext_proc_cluster
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      http2_protocol_options: {}
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
          sni: localhost
      load_assignment:
        cluster_name: ext_proc_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: extproc
                      port_value: 443

admin:
  access_log_path: "/tmp/admin_access.log"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/ext_procbugstalestalebot believes this issue/PR has not been touched recently

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions