TLS Inspector Listener Filter

This example demonstrates how the TLS inspector can be used to select FilterChains to distribute the traffic between upstream clusters according to the matched transport_protocol and/or application_protocols.

It also demonstrates the admin statistics generated by the TLS inspector listener filter.

Step 1: Build the sandbox

Change directory to examples/tls-inspector in the Envoy repository, and bring up the services.

This starts one proxy listening on localhost:10000, and with an admin interface listening on port 12345.

It also starts three upstream HTTP services that echo back received headers in json format.

The first 2 services are HTTPS services listening on port 443 and the other has no TLS and listens on port 80.

$ pwd
envoy/examples/tls-inspector
$ docker compose pull
$ docker compose up --build -d
$ docker compose ps

              Name                               Command               State                         Ports
---------------------------------------------------------------------------------------------------------------------------------
tls-inspector_service-http_1            docker-entrypoint.sh node  ... Up
tls-inspector_service-https-http1.1_1   docker-entrypoint.sh node  ... Up
tls-inspector_service-https-http2_1     docker-entrypoint.sh node  ... Up
tls-inspector_tls-inspector_1           /docker-entrypoint.sh /usr ... Up      0.0.0.0:10000->10000/tcp, 0.0.0.0:12345->12345/tcp

Step 2: Access services

Querying the service at port 10000 with a different HTTP version specified over TLS, or with HTTP protocol without TLS, the requests will be handled by different upstream services.

Query the proxy with HTTP1.1 and TLS

$ curl -sk --http1.1 https://localhost:10000  | jq  '.os.hostname'
"service-https-http1.1"

The upstream service-https-http1.1 handles the request.

Query the proxy with HTTP2 and TLS

$ curl -sk --http2  https://localhost:10000  | jq  '.os.hostname'
"service-https-http2"

The upstream service-https-http2 handles the request.

Query the proxy with no TLS

$ curl -sk http://localhost:10000  | jq  '.os.hostname'
"service-http"

The upstream service-http handles the request. Since TLS Inspector listener filter detects the transport is plaintext, it will not set transport_protocol to TLS.

Step 3: View the admin statistics

TLS inspector has a statistics tree rooted at tls_inspector, which can be extracted with the admin access entrypoint configured.

$ curl -sk http://localhost:12345/stats |grep tls_inspector
tls_inspector.alpn_found: 2
tls_inspector.alpn_not_found: 0
tls_inspector.client_hello_too_large: 0
tls_inspector.connection_closed: 0
tls_inspector.read_error: 0
tls_inspector.sni_found: 2
tls_inspector.sni_not_found: 0
tls_inspector.tls_found: 2
tls_inspector.tls_not_found: 1

Viewing the admin statistics we can see that TLS, SNI and ALPN are all detected since we access services twice via HTTP over TLS. It also shows one tls_not_found from the plaintext query.