All Products
Search
Document Center

Alibaba Cloud Service Mesh:Use an authorization policy to control access traffic from services in an ASM instance to an external database

Last Updated:Jan 25, 2024

To secure a database, you need to restrict the services that are allowed to access the database. For example, you can specify that only services in specific namespaces in a production environment are allowed to access databases in the production environment. This way, you can deny access traffic from services in a development environment to the production environment. The zero-trust security system of Service Mesh (ASM) allows you to dynamically configure authorization policies to control access traffic from services in a namespace to an external database. This helps reduce risks. This topic describes how to use an authorization policy to control access traffic from services in a namespace to an external ApsaraDB RDS database. The demo-server namespace is used in the example.

Prerequisites

The cluster is added to the ASM instance. For more information, see Add a cluster to an ASM instance.

Step 1: Enable automatic sidecar proxy injection

Create a namespace named demo-server and enable automatic sidecar proxy injection for the namespace so that you can authorize and manage services in the namespace. For more information, see Manage global namespaces.

Step 2: Create a database client

In the demo-server namespace, create a client that is used to send requests to connect to a specific external database.

  1. Open a CLI on your on-premises PC and run the following command to encode the password that is used to connect to the external database in Base64:

    echo  <Database connection password> | base64 
  2. Obtain the kubeconfig file of the cluster and use kubectl to connect to the cluster. For more information, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.

  3. Create a MySQL client in the demo-server namespace.

    1. Create a k8s-mysql.yaml file that contains the following content:

      apiVersion: v1
      data:
        password: {yourPasswordBase64}  # The database connection password that is encoded in Base64. 
      kind: Secret
      metadata:
        name: mysql-pass
      type: Opaque
      ---
      
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        labels:
          name: lbl-k8s-mysql
        name: k8s-mysql
      spec:
        progressDeadlineSeconds: 600
        replicas: 1
        revisionHistoryLimit: 10
        selector:
          matchLabels:
            name: lbl-k8s-mysql
        strategy:
          rollingUpdate:
            maxSurge: 25%
            maxUnavailable: 25%
          type: RollingUpdate
        template:
          metadata:
            labels:
              name: lbl-k8s-mysql
          spec:
            containers:
              - env:
                  - name: MYSQL_ROOT_PASSWORD
                    valueFrom:
                      secretKeyRef:
                        key: password
                        name: mysql-pass
                image: 'mysql:latest'
                imagePullPolicy: Always
                name: mysql
                ports:
                  - containerPort: 3306
                    name: mysql
                    protocol: TCP
                resources:
                  limits:
                    cpu: 500m
                terminationMessagePath: /dev/termination-log
                terminationMessagePolicy: File
                volumeMounts:
                  - mountPath: /var/lib/mysql
                    name: k8s-mysql-storage
            dnsPolicy: ClusterFirst
            restartPolicy: Always
            schedulerName: default-scheduler
            securityContext: {}
            terminationGracePeriodSeconds: 30
            volumes:
              - emptyDir: {}
                name: k8s-mysql-storage
    2. Run the following command to create the MySQL client:

      kubectl apply -f k8s-mysql.yaml -n demo-server
  4. Verify that a sidecar proxy is injected into the MySQL client.

    1. Log on to the ACK console. In the left-side navigation pane, click Clusters.

    2. On the Clusters page, click the name of the cluster that you want to manage and choose Workloads > Pods in the left-side navigation pane.

    3. On the Pods page, click the pod name of the MySQL client.

      On the Container tab, a sidecar proxy named istio-proxy is displayed. This indicates that a sidecar proxy is injected into the MySQL client.

Step 3: Create an egress gateway

You can use an egress gateway to control access traffic from services in a Service Mesh instance to an external website. After you configure an authorization policy for the egress gateway, you can also specify conditions to control whether to allow access to an external database.

  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 ASM Gateways > Egress Gateway.

  3. On the Egress Gateway page, click Create.

  4. On the Create page, set the Name parameter of the egress gateway to egressgateway, select a cluster from the Cluster drop-down list, set the Protocol parameter to TCP and the Service Port parameter to 13306 in the Port Mapping section, and then click Create.

    For descriptions of the configuration items, see Create an egress gateway.

Step 4: Configure a policy for accessing external services

By default, services in an ASM instance are allowed to access all external services. To control access to a specific external website, set the Outbound Traffic Policy parameter to REGISTRY_ONLY for an ASM instance in the ASM console. This way, external services that are not registered as service entries cannot be accessed by services in this Service Mesh instance.

  1. Configure a policy for accessing external services.

    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 Dataplane Component Management > Sidecar Proxy Setting.

    3. On the global tab, click Outbound Traffic Policy, set the Outbound Traffic Policy parameter to REGISTRY_ONLY, and then click Update Settings.

  2. Register the external database as a service entry.

    1. On the details page of the ASM instance, choose Cluster & Workload Management > External Service(ServiceEntry) in the left-side navigation pane. On the page that appears, click Create from YAML.

    2. On the Create page, select istio-system from the Namespace drop-down list and copy the following content to the YAML code editor. Then, click Create.

      apiVersion: networking.istio.io/v1beta1
      kind: ServiceEntry
      metadata:
        name: demo-server-rds
        namespace: demo-server
      spec:
        endpoints:
          - address: rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com   # The address of the external database. 
            ports:
              tcp: 3306  
        hosts:
          - rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
        location: MESH_EXTERNAL
        ports:
          - name: tcp
            number: 3306  # The port of the external database. 
            protocol: TCP  # The protocol used by the external database. 
        resolution: DNS
                                      

Step 5: Create a traffic policy

Create an Istio gateway, a destination rule, and a virtual service to route traffic from the demo-server namespace to port 13306 of the egress gateway and then to port 3306 of the external database.

  1. Create an Istio gateway.

    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 ASM Gateways > Gateway. On the page that appears, click Create from YAML.

    3. On the Create page, select istio-system from the Namespace drop-down list and copy the following content to the YAML code editor. Then, click Create.

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: istio-egressgateway
        namespace: istio-system
      spec:
        selector:
          istio: egressgateway
        servers:
          - hosts:
              - '*'
            port:
              name: http-0
              number: 13306
              protocol: TLS
            tls:
              mode: ISTIO_MUTUAL

      In the preceding code, the mode parameter is set to ISTIO_MUTUAL. This means that mutual Transport Layer Security (mTLS) authentication is enabled. In this case, services in an ASM instance must pass TLS authentication before they can access external websites.

  2. Create a destination rule.

    1. On the details page of the ASM instance, choose Traffic Management Center > DestinationRule in the left-side navigation pane. On the page that appears, click Create from YAML.

    2. On the Create page, select demo-server from the Namespace drop-down list and copy the following content to the YAML code editor. Then, click Create.

      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: demo-server-egress-gateway
        namespace: demo-server
      spec:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subsets:
          - name: mysql-gateway-mTLS
            trafficPolicy:
              loadBalancer:
                simple: ROUND_ROBIN
              portLevelSettings:
                - port:
                    number: 13306 # The port of the egress gateway. 
                  tls:
                    mode: ISTIO_MUTUAL
                    sni: rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com  # The host address of the external database.

      In the preceding code, the mode parameter is set to ISTIO_MUTUAL. This means that mTLS authentication is enabled. In this case, services in an ASM instance must pass TLS authentication before they can access external websites.

  3. Create a virtual service.

    1. 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.

    2. On the Create page, select demo-server from the Namespace drop-down list and copy the following content to the YAML code editor. Then, click Create.

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: demo-server-through-egress-gateway
        namespace: demo-server
      spec:
        exportTo:
          - istio-system
          - demo-server
        gateways:
          - mesh
          - istio-system/istio-egressgateway
        hosts:
          - rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
        tcp:
          - match:
              - gateways:
                  - mesh
                port: 3306
            route:
              - destination:
                  host: istio-egressgateway.istio-system.svc.cluster.local
                  port:
                    number: 13306
                  subset: mysql-gateway-mTLS
                weight: 100
          - match:
              - gateways:
                  - istio-system/istio-egressgateway
                port: 13306
            route:
              - destination:
                  host: rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com
                  port:
                    number: 3306
                weight: 100

      In the http section in the preceding code, two matching rules are configured. In the first matching rule, the gateways parameter is set to mesh. This indicates that the first matching rule applies to the sidecar proxy injected into the demo-server namespace and is used to route traffic from the demo-server namespace to port 13306 of the egress gateway. In the second matching rule, the gateways parameter is set to istio-system/istio-egressgateway. This indicates that the matching rule is used to route traffic from the egress gateway to port 3306 of the registered database.

Step 6: Verify that an authorization policy can be used to control access traffic from services in the demo-server namespace to an external database

You can create an authorization policy and modify the action parameter in the authorization policy to deny or allow access traffic from services in the demo-server namespace to an external database. This way, you can control access to the external database.

  1. Create an authorization policy to deny access traffic from the demo-server namespace to the external database.

    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. On the page that appears, click Create.

    3. On the Create page, configure the relevant parameters and click Create.

      Parameter

      Description

      Name

      The name of the authorization policy.

      Policy Type

      Set this parameter to DENY.

      Gateway Scope tab

      ASM Gateway

      Select egressgateway. After you select egressgateway, the Match Label parameter is set to istio:egressgateway by default.

      Request Matching Rules

      Turn on Namespaces and set it to demo-frontend.

      创建授权策略

  2. Access the external database.

    1. Log on to the ACK console. In the left-side navigation pane, click Clusters.

    2. On the Clusters page, click the name of the cluster that you want to manage and choose Workloads > Pods in the left-side navigation pane.

    3. On the Pods page, find the k8s-mysql container and click Terminal in the Actions column. Then, click Container: MySQL.

    4. Run the following command on the terminal of the k8s-mysql container to access the external database:

      mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com

      The ERROR 2013 error is returned, which indicates that services in the demo-server namespace fail to access the external database.

  3. Change the value of the action parameter in the authorization policy to ALLOW to allow access traffic from the demo-server namespace to the external database.

    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. On the AuthorizationPolicy page, find the policy that you want to manage and click YAML in the Actions column.

    4. In the Edit dialog box, change the value of the action parameter to ALLOW, and then click OK.

  4. Run the following command on the terminal of the k8s-mysql container to access the external database:

    mysql --user=root --password=$MYSQL_ROOT_PASSWORD --host rm-xxxxxxx.mysql.xxxx.rds.aliyuncs.com

    The Welcome to the MySQL monitor message is returned, which indicates that services in the demo-server namespace can access the external database.

    The test results indicate that an authorization policy can be used to control access traffic from services in a namespace to an external database.