This is the "latest" release of Envoy Gateway, which contains the most recent commits from the main branch.
This release might not be stable.
Please refer to the /docs documentation for the most current information.
TLS Passthrough
5 minute read
This task will walk through the steps required to configure TLS Passthrough via Envoy Gateway. Unlike configuring Secure Gateways, where the Gateway terminates the client TLS connection, TLS Passthrough allows the application itself to terminate the TLS connection, while the Gateway routes the requests to the application based on SNI headers.
Prerequisites
- OpenSSL to generate TLS assets.
Installation
Follow the steps below to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP.
Expand for instructions
Install the Gateway API CRDs and Envoy Gateway using Helm:
Gateway API CRD compatibilityThis command installs Gateway API CRDs. If your Kubernetes provider already manages compatible Gateway API CRDs for the cluster, use the provider-managed Gateway API CRD install steps instead.
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespaceInstall the GatewayClass, Gateway, HTTPRoute and example app:
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml -n defaultVerify Connectivity:
Get the External IP of the Gateway:
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')Curl the example app through Envoy proxy:
curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/getThe above command should succeed with status code 200.
Get the name of the Envoy service created the by the example Gateway:
export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')Get the deployment of the Envoy service created the by the example Gateway:
export ENVOY_DEPLOYMENT=$(kubectl get deploy -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')Port forward to the Envoy service:
kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &Curl the example app through Envoy proxy:
curl --verbose --header "Host: www.example.com" http://localhost:8888/getThe above command should succeed with status code 200.
TLS Certificates
Generate the certificates and keys used by the Service to terminate client TLS connections. For the application, we’ll deploy a sample echoserver app, with the certificates loaded in the application Pod.
Note: These certificates will not be used by the Gateway, but will remain in the application scope.
Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt
Create a certificate and a private key for passthrough.example.com:
openssl req -out passthrough.example.com.csr -newkey rsa:2048 -nodes -keyout passthrough.example.com.key -subj "/CN=passthrough.example.com/O=some organization"
openssl x509 -req -sha256 -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in passthrough.example.com.csr -out passthrough.example.com.crt
Store the cert/keys in A Secret:
kubectl create secret tls server-certs --key=passthrough.example.com.key --cert=passthrough.example.com.crt
Deployment
Deploy TLS Passthrough application Deployment, Service and TLSRoute:
kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/tls-passthrough.yaml
Patch the Gateway from the Quickstart to include a TLS listener that listens on port 6443 and is configured for
TLS mode Passthrough:
kubectl patch gateway eg --type=json --patch '
- op: add
path: /spec/listeners/-
value:
name: tls
protocol: TLS
hostname: passthrough.example.com
port: 6443
tls:
mode: Passthrough
'
Testing
You can also test the same functionality by sending traffic to the External IP of the Gateway:
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
Curl the example app through the Gateway, e.g. Envoy proxy.
Use the CA certificate (example.com.crt) with --cacert. That is the
issuer of passthrough.example.com.crt. Prefer the CA over the leaf server
certificate: some TLS stacks accept an explicitly trusted leaf as a trust
anchor, but others report SSL certificate problem: unable to get local issuer certificate. The CA path is the portable choice.
curl -v -HHost:passthrough.example.com --resolve "passthrough.example.com:6443:${GATEWAY_HOST}" \
--cacert example.com.crt https://passthrough.example.com:6443/get
Get the name of the Envoy service created the by the example Gateway:
export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
Port forward to the Envoy service:
kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 6043:6443 &
Curl the example app through Envoy proxy. As above, --cacert must be the
CA (example.com.crt), not the leaf passthrough.example.com.crt:
curl -v --resolve "passthrough.example.com:6043:127.0.0.1" \
-HHost:passthrough.example.com \
--cacert example.com.crt \
https://passthrough.example.com:6043/get
Troubleshooting certificate verification
If curl reports unable to get local issuer certificate or unknown CA:
Verify the client trust anchor:
- For the sample certificates generated in this guide, confirm
--cacertpoints atexample.com.crt(the CA that signed the application certificate), not atpassthrough.example.com.crt. - If you replaced the sample certificates with a publicly trusted certificate (e.g., Let’s Encrypt), omit the
--cacertflag so curl uses the system trust store. - If using a private or internal CA, point
--cacertat that CA’s root certificate bundle.
- For the sample certificates generated in this guide, confirm
Confirm the app Secret still holds the keypair created earlier:
kubectl get secret server-certs -o yamlIf you replaced the sample certs with an intermediate-signed certificate, the TLS Secret presented by the application must include the full chain the client needs (leaf plus intermediates). Kubernetes
tls.crtmay contain multiple PEM blocks concatenated leaf-first:cat passthrough.example.com.crt intermediate.crt > fullchain.crt kubectl create secret tls server-certs \ --key=passthrough.example.com.key \ --cert=fullchain.crt \ --dry-run=client -o yaml | kubectl apply -f -The sample Deployment mounts the Secret and loads the keypair at process start. After replacing
server-certs, restart the app so it presents the new certificate:kubectl rollout restart deployment/passthrough-echoserver kubectl rollout status deployment/passthrough-echoserverFor a quick connectivity check only,
curl -kskips verification; do not use that as a substitute for fixing the CA/chain in real deployments.
Because this task uses TLS Passthrough, Envoy does not terminate TLS and does not use a Gateway TLS Secret for this listener. Certificate problems in the curl client almost always come from the backend certificate and the CA file passed to curl, not from Gateway TLS settings.
Clean-Up
Follow the steps from the Quickstart to uninstall Envoy Gateway and the example manifest.
Delete the Secret:
kubectl delete secret/server-certs
Next Steps
Checkout the Developer Guide to get involved in the project.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.