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
Copy to clipboard

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"
Copy to clipboard

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"
Copy to clipboard

The upstream service-https-http2 handles the request.

Query the proxy with no TLS

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

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
Copy to clipboard

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.