All Products
Search
Document Center

Alibaba Cloud Service Mesh:Configure authorization policies for TCP requests

Last Updated:Jan 31, 2024

To implement fine-grained control over service-to-service TCP requests, you can configure authorization policies for TCP requests to manage service interaction permissions. This guarantees that only authorized requests can access a specific service and improves service security and reliability.

Prerequisites

Step 1: Deploy sample applications

Deploy the tcp-echo application as the TCP service that receives requests and the sleep application as the TCP service that sends requests.

  1. Deploy a TCP service to receive requests.

    1. Create a tcp-echo.yaml file that contains the following content.

      After tcp-echo receives a request, tcp-echo prefixes the request content with hello and returns the prefixed content as the response. For example, if tcp-echo receives world, hello world is returned.

      Expand to view the tcp-echo.yaml file

      apiVersion: v1
      kind: Service
      metadata:
        name: tcp-echo
        labels:
          app: tcp-echo
          service: tcp-echo
      spec:
        ports:
        - name: tcp
          port: 9000
        - name: tcp-other
          port: 9001
        selector:
          app: tcp-echo
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: tcp-echo
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: tcp-echo
            version: v1
        template:
          metadata:
            labels:
              app: tcp-echo
              version: v1
          spec:
            containers:
            - name: tcp-echo
              image: docker.io/istio/tcp-echo-server:1.2
              imagePullPolicy: IfNotPresent
              args: [ "9000,9001,9002", "hello" ]
              ports:
              - containerPort: 9000
              - containerPort: 9001
    2. Use kubectl to connect to the cluster. Run the following command to deploy the tcp-echo service as a TCP service to receive requests in the foo namespace.

      For more information about how to use kubectl to connect to the cluster, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.

      kubectl apply -f tcp-echo.yaml -n foo
  2. Deploy a TCP service to send requests.

    1. Create a sleep.yaml file that contains the following content:

      Expand to view the sleep.yaml file

      #Sleep service
      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: curlimages/curl
              command: ["/bin/sleep", "3650d"]
              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 service in the foo namespace to send TCP requests:

      kubectl apply -f sleep.yaml -n foo

Step 2: Check whether the tcp-echo service can be requested as expected before an authorization policy is configured

  1. Run the following command to check whether a request from the sleep service can access the tcp-echo service over port 9000:

    kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'

    Expected output:

    hello port 9000
    connection succeeded

    The output indicates that the request from the sleep service can access the tcp-echo service over port 9000.

  2. Run the following command to check whether a request from the sleep service can access the tcp-echo service over port 9001:

    kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'

    Expected output:

    hello port 9001
    connection succeeded

    The output indicates that the request from the sleep service can access the tcp-echo service over port 9001.

Step 3: Configure an authorization policy

Perform the following steps to configure an authorization policy to allow TCP requests to access the tcp-echo service over port 9000:

  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 Mesh Security Center > AuthorizationPolicy.

  3. Create an authorization policy by using one of the following methods:

    Important

    When you configure an authorization policy for TCP requests, do not turn on the Methods switch in the Add Request Target section. This switch is suitable only for HTTP requests but not for TCP requests. An ALLOW rule that is set by using this switch for TCP requests is invalid. Service Mesh ignores invalid ALLOW rules. Therefore, if you turn on this switch for TCP requests, the TCP requests will be rejected and connection rejected will be returned.

    Method 1: Use YAML to create an authorization policy

    1. On the AuthorizationPolicy page, click Create from YAML.

    2. On the Create page, select foo from the Namespace drop-down list, select a template, copy the following content to the YAML code editor, and then click Create.

      kind: AuthorizationPolicy
      apiVersion: security.istio.io/v1beta1
      metadata:
        name: demo
        namespace: foo
      spec:
        action: ALLOW
        rules:
          - to:
              - operation:
                  ports:
                    - '9000'

    Method 2: Use the graphical user interface (GUI) to create an authorization policy

    1. On the AuthorizationPolicy page, click Create.

    2. On the Create page, set the parameters and click Create.

      Parameter

      Description

      Name

      The name of the authorization policy. In this example, the value is set to demo.

      Policy Type

      The authorization action. In this example, the value is set to ALLOW.

      Namespace

      The namespace in which you want to create the authorization policy. In this example, the Namespace parameter on the Workload Scope tab is set to foo.

      Effective Scope

      The effective scope of the authorization policy. In this example, the value is set to Namespace Scope.

      Request Matching Rules

      The request matching rule of the authorization policy. In this example, Ports is turned on in the Add Request Target section and the value is set to 9000.

Step 4: Check whether the authorization policy that you created takes effect

  1. Run the following command to check whether a request from the sleep service can access the tcp-echo service over port 9001:

    kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'

    Expected output:

    connection rejected

    The output indicates that the request from the sleep service fails to access the tcp-echo service over port 9001.

  2. Run the following command to check whether a request from the sleep service can access the tcp-echo service over port 9000:

    kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'

    Expected output:

    hello port 9000
    connection succeeded

    The output indicates that the request from the sleep service can access the tcp-echo service over port 9000.

References