ASM提供安全策略试运行模式来帮助解决网格中安全策略配置可能出现失误的情况。本文将通过示例为您介绍如何使用ASM安全策略试运行模式并展示试运行模式的效果。
前提条件
- 已创建ASM实例。具体操作,请参见创建ASM实例。
- 已创建Kubernetes托管版集群。具体操作,请参见创建Kubernetes托管版集群。
- 已创建名称为foo的示例命名空间并启用自动注入。具体操作,请参见管理全局命名空间。
- ASM实例的Istio版本需为v1.14或以上。如需升级,请参见升级ASM实例。
背景信息
ASM授权策略支持为网格中的工作负载提供命名空间和工作负载级别的访问权限控制。由于安全策略属于流量管控能力,对安全策略的配置失误可能引起非预期的访问被拒绝或放行,这对网格管理人员的工作带来了很大挑战。一旦安全策略配置失误,可能导致正常业务访问被拒绝或应当被阻止的访问被放行。为此,ASM提供了安全策略试运行模式来解决此类问题。对安全策略启用试运行选项可以使安全策略在应用后并不实际阻止或放行流量,而是仅对策略的执行输出日志。网格管理人员可以通过该日志来判断对应策略的执行结果是否符合预期,并可以参考日志将策略调整至完全符合预期后,再关闭试运行模式,使安全策略真正生效。
本文示例将部署sleep和httpbin两个测试应用,整体流程如下:在sleep应用中通过curl访问httpbin应用,验证连通性后,在ASM中配置一个拒绝特定请求的安全策略并开启试运行模式,然后发起可以匹配安全策略拒绝条件的请求。此时因为已启用试运行模式,所以该请求不会被拒绝,同时Sidecar会输出试运行的执行日志,供网格管理人员确认该安全策略的执行情况。确认无误后,关闭该安全策略的试运行模式,使安全策略生效。
步骤一:部署测试应用sleep和httpbin并测试连通性
- 使用以下内容创建sleep.yaml文件,并通过命令
kubectl apply -f sleep.yaml
部署sleep应用。apiVersion: v1 kind: ServiceAccount metadata: name: sleep namespace: foo --- apiVersion: v1 kind: Service metadata: name: sleep namespace: foo 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 ---
- 使用以下内容创建httpbin.yaml文件,部署httpbin应用。
apiVersion: v1 kind: ServiceAccount metadata: name: httpbin namespace: foo --- apiVersion: v1 kind: Service metadata: name: httpbin namespace: foo labels: app: httpbin service: httpbin spec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin namespace: foo spec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80
- 使用ACK集群kubeconfig执行以下命令。
$ for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/headers -s -o /dev/null -w "%{http_code}\n"; done
执行结果如下,可以看到从sleep应用所在的Pod中执行curl命令访问httpbin应用20次,返回值均为200。200 200 200 ...
步骤二:创建安全策略并启用试运行模式
- 登录ASM控制台。
- 在左侧导航栏选择 ,然后单击目标实例名称进入实例详情页。
- 在左侧导航栏选择创建。 ,然后单击
- 在当前页面,完成以下示例设置后,单击创建。
步骤三:观察示例安全策略效果
- 执行以下命令,再次从sleep应用中访问httpbin应用。
$ for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/headers -s -o /dev/null -w "%{http_code}\n"; done
执行结果如下,可以看到由于安全策略启用了试运行模式,所以请求仍然可以成功。200 200 200 ...
- 执行以下命令,将httpbin应用的Sidecar的RBAC日志级别调整为Debug。
$ kubectl exec "$(kubectl get pod -l app=httpbin -n foo -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo -- curl -X POST 127.0.0.1:15000/logging?rbac=debug
执行结果如下。% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0active loggers: ... rbac: debug ... 100 1028 0 1028 0 0 1003k 0 --:--:-- --:--:-- --:--:-- 1003k
- 执行以下命令,从httpbin应用的Sidecar中筛选安全策略输出的试运行日志。
$ kubectl logs "$(kubectl -n foo -l app=httpbin get pods -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo | grep "shadow denied"
可以看到输出的拦截日志如下。2021-11-19T20:20:48.733099Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0] 2021-11-19T20:21:45.502199Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0] 2021-11-19T20:22:33.065348Z debug envoy rbac shadow denied, matched policy ns[foo]-policy[deny-path-headers]-rule[0]
步骤四:关闭试运行模式
- 登录ASM控制台,在左侧导航栏,选择 。
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
- 在授权策略页面,找到步骤二创建的安全策略,在试运行模式列下关闭开关,然后在确认对话框,单击确认,关闭试运行模式。
- 使用以下命令再次发起请求测试。
for i in {1..20}; do kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/headers -s -o /dev/null -w "%{http_code}\n"; done
执行结果如下,可以看到因为安全策略已经生效,请求被拒绝,返回403代码。403 403 403 ...
- 测试完毕后,使用以下命令恢复Sidecar的日志级别为Warning。
$ kubectl exec "$(kubectl get pod -l app=httpbin -n foo -o jsonpath={.items..metadata.name})" -c istio-proxy -n foo -- curl -X POST 127.0.0.1:15000/logging?rbac=warning
执行结果如下。% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0active loggers: ... rbac: warning ... 100 1028 0 1028 0 0 1003k 0 --:--:-- --:--:-- --:--:-- 1003k