All Products
Search
Document Center

Alibaba Cloud Service Mesh:Enable TLS pass-through on an ingress gateway

Last Updated:Feb 22, 2024

All data between an ingress gateway and a sidecar proxy is transmitted through a Mutual Transport Layer Security (mTLS) tunnel. If sidecar proxies are injected into an application, we recommend that you configure TLS termination on the ingress gateway to ensure end-to-end encryption. If sidecar proxies are not injected into an application or other special circumstances occur, the ingress gateway supports TLS pass-through. This topic describes how to enable TLS pass-through on an ingress gateway to ensure secure access to HTTPS services in a cluster.

Prerequisites

Step 1: Prepare a server certificate and a private key

If you have an available server certificate and private key for the sample.aliyun.com domain name, rename the private key to sample.aliyun.com.key and the server certificate to sample.aliyun.com.crt. Alternatively, run the following openssl commands to create a server certificate and a private key for sample.aliyun.com.

  1. Run the following command to create a root certificate and a private key:

    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. Run the following commands to generate a server certificate and a private key for the server of sample.aliyun.com:

    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

Step 2: Define an internal service

The internal services in this example are implemented based on NGINX. You must create a configuration file for the NGINX server first. In this example, an internal service of the aliyun.com domain name is used. Define the requested root path to directly return the sentence Welcome to aliyun.com without TLS Termination! and status code 200. The following sample code provides an example of the mynginx.conf file:

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;
    location / {
        return 200 'Welcome to aliyun.com without TLS Termination!';
        add_header Content-Type text/plain;
    }
    server_name www.aliyun.com;
    ssl_certificate /etc/nginx-server-certs/tls.crt;
    ssl_certificate_key /etc/nginx-server-certs/tls.key;
  }
}
  1. Use kubectl to connect to the cluster to which the ingress gateway pod belongs based on the information in the kubeconfig file. Then, run the following command to create a ConfigMap for storing the configuration of the NGINX server:

    kubectl create configmap mynginx-configmap --from-file=nginx.conf=./mynginx.conf​
  2. Use kubectl to connect to the cluster to which the ingress gateway pod belongs based on the information in the kubeconfig file. Then, run the following command to create a secret that contains the server certificate and the private key in the default namespace:

    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 about the procedure, see Enable automatic sidecar proxy injection.

  4. Create a mynginxapp.yaml file that contains the following content. Then, run the kubectl apply -f mynginxapp.yaml command to create an internal service for the aliyun.com domain name.

    Expand to view the mynginxapp.yaml file

    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    
  5. Run the following command to send a request from the sidecar proxy to the NGINX server to check whether the NGINX server is deployed:

    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

Step 3: Create an Istio gateway

  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. On the details page of the ASM instance, choose ASM Gateways > Gateway in the left-side navigation pane. On the page that appears, click Create from YAML.

  5. On the Create page, perform the following steps to define an Istio gateway. Then, click Create.

    1. Select a namespace as required. In this example, the default namespace is selected.

    2. In the code editor, define an Istio gateway by using the following YAML code:

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: istio-mynginx-customingressgateway
      spec:
        selector:
          istio: ingressgateway
        servers:
        - hosts:
          - 'sample.aliyun.com'
          port:
            name: https
            number: 443
            protocol: HTTPS
          tls:
            mode: PASSTHROUGH

    On the Gateway page, you can view the created Istio gateway.

Step 4: Create a virtual 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. On the details page of the ASM instance, choose Traffic Management Center > VirtualService in the left-side navigation pane. On the page that appears, click Create from YAML.

  5. On the Create page, perform the following steps to define a virtual service. Then, click Create.

    1. Select a namespace as required. In this example, the default namespace is selected.

    2. In the code editor, define a virtual service by using the following YAML code:

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: istio-mynginx-customvirtualservice
      spec:
        hosts:
        - "sample.aliyun.com"
        gateways:
        - istio-mynginx-customingressgateway
        tls:
        - match:
          - port: 443
            sniHosts:
            - sample.aliyun.com
          route:
          - destination:
              host: mynginxapp.default.svc.cluster.local
              port:
                number: 443

    On the VirtualService page, you can view the created virtual service.

View the results

  1. Use one of the following methods to obtain the IP address of the ingress gateway:

    1. Method 1: by using the ASM console. For more information, see Substep 1 of Step 3 in the Use Istio resources to route traffic to different versions of a service topic.

    2. Method 2: by running a kubectl command.

      Use kubectl to connect to the cluster to which the ingress gateway pod belongs based on the information in the kubeconfig file. Then, run the following command to obtain the IP address of the ingress gateway:

      kubectl get svc -n istio-system -l istio=ingressgateway
  2. Run the following command to access the aliyun.com domain name over HTTPS:

    curl -v --cacert aliyun.root.crt --resolve sample.aliyun.com:443:xx.xx.xx.xx   https://sample.aliyun.com

    Expected output:

    Welcome to aliyun.com without TLS Termination!%