All Products
Search
Document Center

Alibaba Cloud Service Mesh:Verify whether mTLS is enabled in an ASM instance

Last Updated:Mar 05, 2025

Mutual Transport Layer Security (mTLS) is an important basic feature of Service Mesh (ASM). You need to only inject sidecar proxies into your application pods to enable mTLS, without the need to modify the code of your applications. However, whether mTLS is enabled is imperceptible to users. You cannot intuitively determine whether traffic is encrypted. This topic demonstrates how to check whether mTLS is enabled in an ASM instance.

Background information

Transport Layer Security (TLS) is a security protocol widely used on the Internet, which aims to provide a secure data transmission channel for both ends of communication. Usually, only one-way authentication is performed for common TLS communication. For example, when you use a browser to visit a website over HTTPS, only the website server needs to provide the certificate of the website to prove to you that the server is the legal owner of the website, and you are not required to provide your certificate to prove your identity.

However, in mTLS, the client must also provide its certificate to the server, and both parties need to verify the identity of each other. This ensures that only authorized clients can access the specified server.

The authorization mechanism in ASM uses mTLS to verify the identities of clients. This mutual authentication mechanism ensures that every service call in ASM comes from a trusted client, thereby providing additional security protection for microservices communication.

In the following example, a sleep application is used to access the HTTPBin application. This example demonstrates how to check whether mTLS is enabled in ASM in a direct manner and in an indirect manner.

Prerequisites

Step 1: Deploy a sleep application

  1. Use kubectl to connect to the ACK managed cluster that is added to the ASM instance. Then, create a sleep.yaml file with the following content:

    Expand to view the YAML content

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2
            command: ["/bin/sleep", "infinity"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
    ---
  2. Run the following command to deploy the sleep application, which is the test client:

    kubectl apply -f sleep.yaml

Step 2: Check whether mTLS is enabled

Check whether mTLS is enabled in an indirect manner by using the header ID

X-FORWARDED-CLIENT-CERT (XFCC) is a proxy header, which indicates certificate information of part or all of the clients or proxies that a request passes through on its way from the client to the server. For more information, see HTTP header manipulation.

When you use the curl command in the sleep application to access the HTTPBin application, the request received by the HTTPBin application carries an XFCC header, which indicates that the request was sent by the sleep application. This header can be used to indirectly determine that mTLS is enabled in communication between the two ends.

  1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

  2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose Observability Management Center > Observability Settings.

  3. On the Global tab, select X-FORWARDED-CLIENT-CERT in the Log Settings section, and then click Submit.

    image

  4. Use kubectl to connect to the ACK managed cluster that is added to the ASM instance. Then, run the following command to access the HTTPBin application from the sleep pod:

    kubectl exec <sleep pod name> -- curl httpbin:8000 -I
  5. Run the following command to view the logs of the HTTPBin pod:

    kubectl logs <httpbin pod> -c istio-proxy | tail -1

    Expected output:

    {"bytes_received":"0","bytes_sent":"0","downstream_local_address":"192.168.34.76:80","downstream_remote_address":"192.168.34.74:45042","duration":"2","istio_policy_status":"-","method":"HEAD","path":"/","protocol":"HTTP/1.1","request_id":"7bd9862b-69d8-4d14-bc62-4520b2b45370","requested_server_name":"outbound_.8000_._.httpbin.default.svc.cluster.local","response_code":"200","response_flags":"-","route_name":"default","start_time":"2024-06-11T11:24:04.163Z","trace_id":"-","upstream_cluster":"inbound|80||","upstream_host":"192.168.34.76:80","upstream_local_address":"127.0.0.6:54963","upstream_service_time":"2","upstream_response_time":"2","upstream_transport_failure_reason":"-","user_agent":"curl/8.1.2","x_forwarded_for":"-","authority_for":"httpbin:8000","x_forwarded_client_cert":"By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=583116d4dfd7b548400031f5c8685ee4f8ca99f217aca2af8634022362988114;Subject="";URI=spiffe://cluster.local/ns/default/sa/sleep"}

    The XFCC header in the preceding output indicates that the client is the sleep application.

Check whether mTLS is enabled in a direct manner by running the tcpdump command to capture packets

In this section, the packets that are sent from the sidecar proxy of the sleep application to the sidecar proxy of the HTTPBin application are captured in the sleep pod. Two ways can be used to capture packets. You can choose one based on the actual situation.

Note

Before you capture packets, delete the existing HTTPBin pod to restart it and ensure that the persistent connection between sidecar proxies is forcibly disconnected.

Use ASMPacketInspector to capture packets (ASMPacketInspector is available in ASM instances of V1.21 and later)

  1. Use kubectl to connect to the ASM instance and create an ASMPacketInspector.yaml file that contains the following content:

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMPacketInspector
    metadata:
      name: test
    spec:
      pod:
        clusterId: ${ACK Cluster ID}
        namespace: default
        name: ${sleep pod name}
      tcpDumpParams: '-i any port 80'
      duration: 60s
      fileName: sleep.pcap
  2. Run the following command to deploy ASMPacketInspector resources:

    kubectl apply -f ASMPacketInspector.yaml
  3. After the ASMPacketInspector resources are deployed, ASM automatically captures packets whose destination port is port 80 in the sleep pod. Port 80 is the service port exposed by the HTTPBin application. The packet capture duration is 60s. During this period, use kubectl to connect to the ACK managed cluster that is added to the ASM instance and run the following command:

    kubectl exec -it <sleep pod name> -c sleep --  sh -c 'for i in $(seq 1 30); do curl httpbin:8000 -I ; echo "request $i done"; done'

    This command automatically sends 30 requests from the sleep pod to the HTTPBin application.

  4. Use kubectl to connect to the ASM instance and run the following command to view the packet capture results:

    kubectl get ASMPacketInspector test -o yaml

    Expected results:

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: ASMPacketInspector
    metadata:
      ******
    spec:
      ******
    status:
      completedAt: null
      conditions:
      - time: "2024-06-12T08:15:33Z"
        type: Inspecting
      - message: 'inspecting job status: Running'
        time: "2024-06-12T08:15:43Z"
        type: Inspecting
      - message: 'inspecting job status: Running'
        time: "2024-06-12T08:15:53Z"
        type: Inspecting
      - message: 'inspecting job status: Running'
        time: "2024-06-12T08:16:03Z"
        type: Inspecting
      - message: 'inspecting job status: Running'
        time: "2024-06-12T08:16:13Z"
        type: Inspecting
      - message: 'inspecting job status: Running'
        time: "2024-06-12T08:16:23Z"
        type: Inspecting
      filePath: /tmp/sleep.pcap
      phase: Inspecting
      runningOnNode: *******
      startAt: "2024-06-12T08:15:43Z"
      taskId: inspector-zumnmwdc

    runningOnNode in the status section indicates the node where the packets are captured. filePath indicates the path of the output file. Log on to the specified node to download the file to your local computer.

Capture packets on the node where the sleep pod resides

  1. Use kubectl to connect to the ACK managed cluster that is added to the ASM instance. Then, run the following command to check the node where the sleep application runs:

    kubectl  get pod -o wide 

    Expected output:

    NAME                       READY   STATUS    RESTARTS   AGE     IP           NODE                       NOMINATED NODE   READINESS GATES
    httpbin-6c8f47d9b9-stq72   2/2     Running   0          33m     172.16.*.*   cn-***.172.16.*.*   <none>           <none>
    sleep-84f9785988-ft9rm     2/2     Running   0          3h56m   172.16.*.*   cn-***.172.16.*.*   <none>           <none>
  2. Log on to the node where the sleep application runs. For more information, see Use Workbench to connect to a Linux instance over SSH.

    1. Run the following command to view the CONTAINER ID of the container where the sleep application resides:

      sudo crictl ps | grep <Pod name>

      Expected output:

      CONTAINER           IMAGE               CREATED             STATE                      
      a1a214d2*****       35d28df4*****       2 days ago          Running
    2. Run the following command with CONTAINER ID set to the one obtained in the preceding step to view the PID of the container:

      sudo crictl inspect  a1a214d2***** |grep -i PID

      Expected output:

         "pid": 2309838,    # The PID of the container. 
                  "pid": 1
                  "type": "pid"
    3. Run the following command to capture packets:

      sudo nsenter -t <Container PID> tcpdump -i any port 80 -w /tmp/test.pcap

      Download the test.pcap file generated after the command is executed to your local computer.

Make sure that Wireshark is installed on your computer. Use Wireshark to open the pcap file that you downloaded to your computer and set the protocol of the corresponding port to TLS. The following result is displayed.

lQLPJyD1OwZMe9nNAyLNCiSwkwADizrf70MGVI7OabFdAA_2596_802

The TLS packets indicate that the communication between sidecar proxies is encrypted by using mTLS.

Note

You can view only Client Hello and Server Hello packets, followed by Application Data packets. TLS certificate information is not displayed because TLSv1.3 encrypts subsequent certificate exchange messages. Therefore, the plaintext information of certificates cannot be directly viewed in WireShark, which is normal.