TLS Inspector Listener Filter

Requirements

Sandbox environment

Setup your sandbox environment with Docker and Docker Compose, and clone the Envoy repository with Git.

curl

Used to make HTTP requests.

jq

Parse json output from the upstream echo servers.

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.

  1. $ pwd
  2. envoy/examples/tls-inspector
  3. $ docker-compose pull
  4. $ docker-compose up --build -d
  5. $ docker-compose ps
  6. Name Command State Ports
  7. ---------------------------------------------------------------------------------------------------------------------------------
  8. tls-inspector_service-http_1 docker-entrypoint.sh node ... Up
  9. tls-inspector_service-https-http1.1_1 docker-entrypoint.sh node ... Up
  10. tls-inspector_service-https-http2_1 docker-entrypoint.sh node ... Up
  11. 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

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

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

Query the proxy with HTTP2 and TLS

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

The upstream service-https-http2 handles the request.

Query the proxy with no TLS

  1. $ curl -sk http://localhost:10000 | jq '.os.hostname'
  2. "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.

  1. $ curl -sk http://localhost:12345/stats |grep tls_inspector
  2. tls_inspector.alpn_found: 2
  3. tls_inspector.alpn_not_found: 0
  4. tls_inspector.client_hello_too_large: 0
  5. tls_inspector.connection_closed: 0
  6. tls_inspector.read_error: 0
  7. tls_inspector.sni_found: 2
  8. tls_inspector.sni_not_found: 0
  9. tls_inspector.tls_found: 2
  10. 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.