All Products
Search
Document Center

Alibaba Cloud Service Mesh:Enable TLS passthrough on an ingress gateway

Last Updated:Mar 11, 2026

With TLS passthrough, the ingress gateway forwards encrypted TLS traffic directly to backend services without decrypting it. The backend service handles TLS termination instead of the gateway, which keeps the TLS session intact from client to server.

This differs from TLS termination, where the gateway decrypts traffic before forwarding it:

ModeTLS terminated atUse case
TLS terminationIngress gatewaySidecar proxies are injected; traffic between gateway and sidecar travels through an mTLS tunnel
TLS passthroughBackend serviceSidecar proxies are not injected, or other special circumstances require end-to-end encryption without intermediate decryption
Note: If sidecar proxies are injected, all traffic between the ingress gateway and sidecar proxies travels through a mutual TLS (mTLS) tunnel. In that case, configure TLS termination on the ingress gateway instead.

TLS passthrough relies on Server Name Indication (SNI) to route traffic. Your clients must support the SNI TLS extension.

Prerequisites

Before you begin, make sure that you have:

Step 1: Prepare a server certificate and private key

If you already have a server certificate and private key for sample.aliyun.com, rename them to sample.aliyun.com.crt and sample.aliyun.com.key, then skip to Step 2.

Otherwise, run the following openssl commands to generate self-signed certificates for testing.

  1. Create a root certificate authority (CA):

       openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \
         -subj '/O=mynginx Inc./CN=aliyun.com' \
         -keyout aliyun.root.key -out aliyun.root.crt
  2. Generate a server certificate signed by the root CA:

       openssl req -out sample.aliyun.com.csr -newkey rsa:2048 -nodes \
         -keyout sample.aliyun.com.key \
         -subj "/CN=sample.aliyun.com/O=mynginx sample organization"
    
       openssl x509 -req -days 365 \
         -CA aliyun.root.crt -CAkey aliyun.root.key -set_serial 0 \
         -in sample.aliyun.com.csr -out sample.aliyun.com.crt

These commands produce the following files:

FilePurpose
aliyun.root.crt / aliyun.root.keyRoot CA certificate and private key
sample.aliyun.com.crt / sample.aliyun.com.keyServer certificate and private key for sample.aliyun.com
sample.aliyun.com.csrCertificate signing request (intermediate file)

Step 2: Deploy an HTTPS backend service

This step deploys an NGINX-based backend service that terminates TLS on port 443. The ingress gateway passes TLS traffic through to this service without decryption.

Create the NGINX configuration

Create a file named mynginx.conf with the following content:

events {
}
http {
  log_format main '$remote_addr - $remote_user [$time_local]  $status '
  '"$request" $body_bytes_sent "$http_referer" '
  '"$http_user_agent" "$http_x_forwarded_for"';
  access_log /var/log/nginx/access.log main;
  error_log  /var/log/nginx/error.log;
  server {
    listen 443 ssl;
    server_name www.aliyun.com;

    ssl_certificate /etc/nginx-server-certs/tls.crt;
    ssl_certificate_key /etc/nginx-server-certs/tls.key;

    location / {
        return 200 'Welcome to aliyun.com without TLS Termination!';
        add_header Content-Type text/plain;
    }
  }
}

Create supporting Kubernetes resources

  1. Create a ConfigMap to store the NGINX configuration:

       kubectl create configmap mynginx-configmap --from-file=nginx.conf=./mynginx.conf
  2. Create a Secret to store the server certificate and private key:

       kubectl create secret tls nginx-server-certs \
         --key sample.aliyun.com.key --cert sample.aliyun.com.crt
  3. Enable automatic sidecar proxy injection for the default namespace. For more information, see Enable automatic sidecar proxy injection.

Deploy the NGINX service

Create a file named mynginxapp.yaml with the following content, then run kubectl apply -f mynginxapp.yaml:

mynginxapp.yaml

apiVersion: v1
kind: Service
metadata:
  name: mynginxapp
  labels:
    app: mynginxapp
spec:
  ports:
  - port: 443
    protocol: TCP
  selector:
    app: mynginxapp
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mynginxapp
spec:
  selector:
    matchLabels:
      app: mynginxapp
  replicas: 1
  template:
    metadata:
      labels:
        app: mynginxapp
    spec:
      containers:
      - name: nginx
        image: nginx:1.15
        ports:
        - containerPort: 443
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx
          readOnly: true
        - name: nginx-server-certs
          mountPath: /etc/nginx-server-certs
          readOnly: true
      volumes:
      - name: nginx-config
        configMap:
          name: mynginx-configmap
      - name: nginx-server-certs
        secret:
          secretName: nginx-server-certs

Verify the backend service

Run the following command to send a test request from the sidecar proxy to the NGINX server:

kubectl exec -it $(kubectl get pod -l app=mynginxapp -o jsonpath={.items..metadata.name}) \
  -c istio-proxy -- curl -v -k --resolve sample.aliyun.com:443:127.0.0.1 https://sample.aliyun.com

If the NGINX server is running correctly, the response body contains:

Welcome to aliyun.com without TLS Termination!

Step 3: Create an Istio gateway with TLS passthrough

Define a Gateway resource that listens on port 443 and forwards TLS traffic to the backend without termination.

  1. Log on to the ASM console.

  2. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  3. On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.

  4. In the left-side navigation pane, choose ASM Gateways > Gateway. On the page that appears, click Create from YAML.

  5. Select the default namespace and paste the following YAML:

       apiVersion: networking.istio.io/v1alpha3
       kind: Gateway
       metadata:
         name: istio-mynginx-customingressgateway
       spec:
         selector:
           istio: ingressgateway  # binds to the default ingress gateway
         servers:
         - hosts:
           - 'sample.aliyun.com'
           port:
             name: https
             number: 443
             protocol: HTTPS
           tls:
             mode: PASSTHROUGH  # forward encrypted traffic without termination
  6. Click Create.

The new Gateway appears on the Gateway page.

Step 4: Create a virtual service for TLS routing

Define a VirtualService that routes TLS traffic matching the SNI host sample.aliyun.com to the backend service.

  1. Log on to the ASM console.

  2. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  3. On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.

  4. In the left-side navigation pane, choose Traffic Management Center > VirtualService. On the page that appears, click Create from YAML.

  5. Select the default namespace and paste the following YAML:

       apiVersion: networking.istio.io/v1alpha3
       kind: VirtualService
       metadata:
         name: istio-mynginx-customvirtualservice
       spec:
         hosts:
         - "sample.aliyun.com"
         gateways:
         - istio-mynginx-customingressgateway  # reference the Gateway from Step 3
         tls:
         - match:
           - port: 443
             sniHosts:
             - sample.aliyun.com  # route traffic by SNI hostname
           route:
           - destination:
               host: mynginxapp.default.svc.cluster.local  # backend service FQDN
               port:
                 number: 443
  6. Click Create.

The new VirtualService appears on the VirtualService page.

Verify the result

  1. Get the IP address of the ingress gateway using one of the following methods:

  2. Send an HTTPS request through the ingress gateway. Replace <ingress-gateway-ip> with the IP address from the previous step:

       curl -v --cacert aliyun.root.crt \
         --resolve sample.aliyun.com:443:<ingress-gateway-ip> \
         https://sample.aliyun.com

    Expected output:

       Welcome to aliyun.com without TLS Termination!

    This confirms that TLS traffic passes through the ingress gateway to the NGINX backend, which terminates TLS and returns the response.

Clean up

To remove the resources created in this tutorial, run the following commands:

kubectl delete gateway istio-mynginx-customingressgateway
kubectl delete virtualservice istio-mynginx-customvirtualservice
kubectl delete service mynginxapp
kubectl delete deployment mynginxapp
kubectl delete secret nginx-server-certs
kubectl delete configmap mynginx-configmap