ASM提供安全策略试运行模式来帮助解决网格中安全策略配置可能出现失误的情况。本文将通过示例为您介绍如何使用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控制台。
- 在左侧导航栏选择,然后单击目标实例名称进入实例详情页。
- 在左侧导航栏选择,然后单击创建。
- 在当前页面,完成以下示例设置后,单击创建。

配置项 |
说明 |
命名空间 |
选择已创建的示例空间foo。
|
名称 |
填写自定义的授权策略名称。 |
启用试运行模式 |
选中此选项。 |
策略 |
选择RULES。
|
动作 |
选择DENY。
|
工作负载标签选择 |
打开此开关,单击新增匹配标签,输入标签名称为app,值为httpbin。
|
请求操作 |
打开此开关,单击增加请求操作到列表中后再单击增加请求操作,输入请求操作域为paths,值为/headers。
|
步骤三:观察示例安全策略效果
- 执行以下命令,再次从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控制台的页面,找到步骤二创建的安全策略,在其操作列,单击查看YAML。
- 在YAML文件中,将
istio.io/dry-run
的annotation由true
改为false
,然后单击确定。
- 使用以下命令再次发起请求测试。
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