Ambient模式中,由于4层和7层的分离架构,导致认证和授权的配置模型与原Sidecar模式不同。以ASM 1.18版本为例,本文介绍如何使用7层授权策略。
前提条件
已部署ASM网关和应用,且成功验证基本功能。具体操作,请参见入门示例的前提条件和步骤一。
使用限制
授权策略在Waypoint代理中的使用限制如下:
action
字段不支持CUSTOM
,即Waypoint代理不支持自定义授权服务。source
字段中不支持ipBlocks
。
存在Waypoint代理时,Ztunnel代理会允许所有来自Waypoint代理的请求通过。此时,授权策略需要绑定给指定的Waypoint代理。
准备工作
执行以下命令,为productpage部署Waypoint。
istioctl x waypoint apply --service-account bookinfo-productpage
执行以下命令,查看对应的Waypoint Pod。
kubectl get pod --show-labels | grep waypoint
预期输出:
bookinfo-productpage-istio-waypoint-6c579dd48d-l**** 1/1 Running 0 91s gateway.istio.io/managed=istio.io-mesh-controller,istio.io/gateway-name=bookinfo-productpage,pod-template-hash=6c579dd48d,service.istio.io/canonical-name=bookinfo-productpage-istio-waypoint,service.istio.io/canonical-revision=latest,sidecar.istio.io/inject=false
示例一:存在Waypoint时,Ztunnel上的授权策略失效
存在Waypoint时,Ztunnel将会允许所有来自当前服务Waypoint的流量通过,此时再将授权策略应用到Ztunnel上(授权策略的selector
选中了业务Pod)时,该授权策略不会生效。
使用以下内容,创建productpage-viewer.yaml。
以下授权策略作用于Ztunnel,禁止访问productpage的9080端口。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: productpage-viewer namespace: default spec: selector: matchLabels: app: productpage action: DENY rules: - to: - operation: ports: - "9080"
在ASM实例对应的KubeConfig环境下,执行以下命令,创建授权策略。
kubectl apply -f productpage-viewer.yaml
验证授权策略是否生效。
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
预期输出:
<title>Simple Bookstore App</title>
执行以下命令,进行访问测试。
kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage" | grep -o "<title>.*</title>"
预期输出:
<title>Simple Bookstore App</title>
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://productpage:9080/| grep -o "<title>.*</title>"
预期输出:
command terminated with exit code 56
执行以下命令,进行访问测试。
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
预期输出:
<title>Simple Bookstore App</title>
本测试和不存在Waypoint的示例二:禁止访问productpage的9080端口使用了同样的授权策略,但本测试所有访问均成功。
以上结果说明当配置Waypoint后,之前Ztunnel上的所有策略都会失效。您需要更改
selector
为productpage对应的Waypoint。将授权策略productpage-viewer.yaml修改为如下内容,然后执行
kubectl apply -f productpage-viewer.yaml
命令进行部署。以下YAML修改了
selector
字段。apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: productpage-viewer namespace: default spec: selector: matchLabels: istio.io/gateway-name: bookinfo-productpage action: DENY rules: - to: - operation: ports: - "9080"
验证授权策略是否生效。
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage"
预期输出:
RBAC: access denied%
执行以下命令,进行访问测试。
kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage"
预期输出:
RBAC: access denied%
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://productpage:9080/
预期输出:
RBAC: access denied%
执行以下命令,进行访问测试。
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
预期输出:
RBAC: access denied%
此处返回的报错信息
RBAC: access denied%
和L4鉴权的示例二:禁止访问productpage的9080端口不同。这个错误实际由productpage的Waypoint返回。Waypoint发现9080端口不允许访问,于是返回一个HTTP RBAC错误,实际的状态码应为403。
执行以下命令,清除授权策略。
kubectl delete authorizationpolicy productpage-viewer
示例二:禁止sleep Pod的IP直接或通过网关间接访问productpage
目前配置在Waypoint上的授权策略不支持ipBlocks
字段,只支持remoteIpBlocks
。请求经过网关只能配置remoteIpBlocks
字段进行匹配。
使用以下内容,创建productpage-viewer.yaml,禁止sleep Pod通过网关访问productpage。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: productpage-viewer namespace: default spec: selector: matchLabels: istio.io/gateway-name: bookinfo-productpage action: DENY rules: - from: - source: remoteIpBlocks: - "${sleep Pod IP}"
在ASM实例对应的KubeConfig环境下,执行以下命令,创建授权策略。
kubectl apply -f productpage-viewer.yaml
验证授权策略是否生效。
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage"
预期输出:
RBAC: access denied%
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ -I
预期输出:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Fri, 19 Jul 2024 08:17:08 GMT server: istio-envoy
预期输出表明sleep Pod不可以直接访问productpage,也不可以通过网关访问。
执行以下命令,清除授权策略。
kubectl delete authorizationpolicy productpage-viewer
示例三:productpage禁止被istio-system命名空间下的Pod访问
使用以下内容,创建productpage-viewer.yaml,禁止istio-system命名空间的Pod访问productpage。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: productpage-viewer namespace: default spec: selector: matchLabels: istio.io/gateway-name: bookinfo-productpage action: DENY rules: - from: - source: namespaces: - istio-system
在ASM实例对应的KubeConfig环境下,执行以下命令,创建授权策略。
kubectl apply -f productpage-viewer.yaml
验证授权策略是否生效。
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage"
预期输出:
RBAC: access denied%
执行以下命令,进行访问测试。
kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage"
预期输出:
RBAC: access denied%
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
预期输出:
<title>Simple Bookstore App</title>
执行以下命令,进行访问测试。
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
预期输出:
<title>Simple Bookstore App</title>
预期输出表明sleep和notsleep均无法通过网关访问productpage,但是可以直接访问productpage,因为网关在istio-system命名空间。
执行以下命令,清除授权策略。
kubectl delete authorizationpolicy productpage-viewer
示例四:限制host为test.com的请求,不能访问9080端口
productpage应用暴露的端口为9080。本示例配置host
为test.com
的请求不能访问9080,但其它请求可以。
使用以下内容,创建productpage-viewer.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: productpage-viewer namespace: default spec: selector: matchLabels: istio.io/gateway-name: bookinfo-productpage action: DENY rules: - to: - operation: hosts: ["test.com"] ports: ["9080"]
在ASM实例对应的KubeConfig环境下,执行以下命令,创建授权策略。
kubectl apply -f productpage-viewer.yaml
验证授权策略是否生效。
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -H "Host: test.com"
预期输出:
RBAC: access denied%
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -H "Host: test1.com" -I
预期输出:
HTTP/1.1 200 OK content-type: text/html; charset=utf-8 content-length: 5290 server: istio-envoy date: Tue, 15 Aug 2023 03:39:29 GMT x-envoy-upstream-service-time: 18
执行以下命令,清除授权策略。
kubectl delete authorizationpolicy productpage-viewer
示例五:限制不允许使用HEAD方法访问/productpage路径
使用以下内容,创建productpage-viewer.yaml。
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: productpage-viewer namespace: default spec: selector: matchLabels: istio.io/gateway-name: bookinfo-productpage action: DENY rules: - to: - operation: methods: ["HEAD"] paths: ["/productpage"]
在ASM实例对应的KubeConfig环境下,执行以下命令,创建授权策略。
kubectl apply -f productpage-viewer.yaml
验证授权策略是否生效。
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -I
预期输出:
HTTP/1.1 403 Forbidden content-length: 19 content-type: text/plain date: Tue, 15 Aug 2023 03:59:37 GMT server: istio-envoy x-envoy-upstream-service-time: 0
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/productpage -XGET -I
预期输出:
HTTP/1.1 200 OK content-type: text/html; charset=utf-8 content-length: 5290 server: istio-envoy date: Tue, 15 Aug 2023 03:39:29 GMT x-envoy-upstream-service-time: 18
执行以下命令,进行访问测试。
kubectl exec deploy/sleep -- curl -s http://$GATEWAY_HOST/api/v1/products -I
预期输出:
HTTP/1.1 200 OK content-type: text/html; charset=utf-8 content-length: 5290 server: istio-envoy date: Tue, 15 Aug 2023 03:39:29 GMT x-envoy-upstream-service-time: 18
执行以下命令,清除授权策略。
kubectl delete authorizationpolicy productpage-viewer