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.
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
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.
Create a MySQL client in the demo-server namespace.
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
Run the following command to create the MySQL client:
kubectl apply -f k8s-mysql.yaml -n demo-server
Verify that a sidecar proxy is injected into the MySQL client.
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, click the name of the cluster that you want to manage and choose in the left-side navigation pane.
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.
Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
On the Egress Gateway page, click Create.
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.
Configure a policy for accessing external services.
Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
On the global tab, click Outbound Traffic Policy, set the Outbound Traffic Policy parameter to REGISTRY_ONLY, and then click Update Settings.
Register the external database as a service entry.
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
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.
Create an Istio gateway.
Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose . On the page that appears, click Create from YAML.
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.
Create a destination rule.
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
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.
Create a virtual service.
On the details page of the ASM instance, choose in the left-side navigation pane. On the page that appears, click Create from YAML.
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.
Create an authorization policy to deny access traffic from the demo-server namespace to the external database.
Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose . On the page that appears, click Create.
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.
Access the external database.
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, click the name of the cluster that you want to manage and choose in the left-side navigation pane.
On the Pods page, find the k8s-mysql container and click Terminal in the Actions column. Then, click Container: MySQL.
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.
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.
Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
On the AuthorizationPolicy page, find the policy that you want to manage and click YAML in the Actions column.
In the Edit dialog box, change the value of the action parameter to ALLOW, and then click OK.
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.