Skip to main content
logoTetrate Enterprise Gateway for EnvoyVersion: v0.0.0-latest

Securing Your First Application Exposed Using TEG

This guide builds upon the steps in Expose Your Application, where the httpbin application is exposed to external clients using Tetrate Envoy Gateway (TEG). Initially, traffic was sent in clear text (HTTP). In this guide, you will learn how to secure that communication using:

  • TLS (HTTPS)
  • Mutual TLS (mTLS)
caution

Self-signed certificates are used for demonstration purposes only. For production, always use certificates issued by a trusted Certificate Authority (CA).

Enabling HTTPS (Server-side TLS Termination)

In this section, you will enable HTTPS access to your application using TLS termination at the gateway. The communication between the client and the gateway will be encrypted.

  1. Generate Self-Signed 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

    openssl req -out www.example.com.csr \
    -newkey rsa:2048 -nodes \
    -keyout www.example.com.key \
    -subj "/CN=www.example.com/O=example organization"

    openssl x509 -req -days 365 \
    -CA example.com.crt \
    -CAkey example.com.key \
    -set_serial 0 \
    -in www.example.com.csr \
    -out www.example.com.crt
  2. Create a TLS Secret in Kubernetes

    kubectl create secret tls example-cert \
    --key=www.example.com.key \
    --cert=www.example.com.crt \
    -n httpbin
  3. Add an HTTPS Listener to the Gateway

    kubectl patch gateway dedicated-gateway -n httpbin --type=json --patch '[{
    "op": "add",
    "path": "/spec/listeners/-",
    "value": {
    "name": "https",
    "protocol": "HTTPS",
    "port": 443,
    "tls": {
    "mode": "Terminate",
    "certificateRefs": [{
    "kind": "Secret",
    "group": "",
    "name": "example-cert"
    }]
    }
    }
    }]'
  4. Test HTTPS Access

    As described in Expose Your Application, the client needs Tetrate Envoy Gateway's external IP address or port-forwarded address.

    We will set the $GATEWAY_ADDRESS to the external IP.

    export GATEWAY_ADDRESS=$(kubectl get gateway/dedicated-gateway -n httpbin -o jsonpath='{.status.addresses[0].value}')

    Test https access:

    curl --head -HHost:www.example.com \
    --resolve "www.example.com:443:${GATEWAY_ADDRESS}" \
    --cacert example.com.crt \
    https://www.example.com/httpbin/status/200

    Expected Output

    HTTP/2 200
    access-control-allow-credentials: true
    access-control-allow-origin: *
    content-type: text/plain; charset=utf-8
    date: ...

Enforcing Mutual TLS (mTLS) for External Clients

Mutual TLS ensures both client and server authenticate each other. This section demonstrates configuring mTLS between external clients and the gateway.

  1. Generate TLS Certificates

    Reuse example.com.crt and example.com.key from previous steps.

    Create CA and client certs:

    openssl req -out client.example.com.csr \
    -newkey rsa:2048 -nodes \
    -keyout client.example.com.key \
    -subj "/CN=client.example.com/O=example organization"

    openssl x509 -req -days 365 \
    -CA example.com.crt \
    -CAkey example.com.key \
    -set_serial 0 \
    -in client.example.com.csr \
    -out client.example.com.crt
  2. Create Required Secrets

    kubectl create secret generic example-ca-cert --from-file=ca.crt=example.com.crt -n httpbin
  3. Create ClientTrafficPolicy

    apiVersion: gateway.envoyproxy.io/v1alpha1
    kind: ClientTrafficPolicy
    metadata:
    name: enable-mtls
    namespace: httpbin
    spec:
    targetRefs:
    - group: gateway.networking.k8s.io
    kind: Gateway
    name: dedicated-gateway
    tls:
    clientValidation:
    caCertificateRefs:
    - kind: "Secret"
    group: ""
    name: "example-ca-cert"
    kubectl apply -f client-traffic-policy.yaml
  4. Test mTLS Access

    We will set the $GATEWAY_ADDRESS to the external IP.

    export GATEWAY_ADDRESS=$(kubectl get gateway/dedicated-gateway -n httpbin -o jsonpath='{.status.addresses[0].value}')

    curl --head -HHost:www.example.com \
    --resolve "www.example.com:443:${GATEWAY_ADDRESS}" \
    --cert client.example.com.crt \
    --key client.example.com.key \
    --cacert example.com.crt \
    https://www.example.com/httpbin/status/200

    Expected output:

    HTTP/2 200
    access-control-allow-credentials: true
    access-control-allow-origin: *
    content-type: text/plain; charset=utf-8
    date: ...

    Repeat the curl test without providing the client certificate and key (omit the --cert client.example.com.crt and --key client.example.com.key options).

    Expected error:

    curl: (35) Peer does not recognize and trust the CA that issued your certificate.

Troubleshooting

This section will be handy if you are experiencing any issues, such as certificate verification failures, 404 errors, or connectivity problems when accessing your application over HTTPS or mTLS.

  • Error: Certificate verify failed Ensure --cacert is correctly pointing to your CA certificate.
  • Gateway returns 404 Check Host header matches the Route configuration.
  • No response / timeout Confirm Gateway external IP is reachable and Listener is on port 443.