基于组和列表声明的授权
本教程将向您介绍在 Istio 中配置基于组的授权和列表类型声明的授权的示例。
开始之前
阅读授权概念并阅读有关如何配置 Istio 授权的指南。
创建一个安装了 Istio 并启用了双向 TLS 的 Kubernetes 集群。要满足此先决条件,您可以按照 Kubernetes 安装说明进行操作。
设置所需的命名空间和服务
本教程在一个名为 rbac-groups-test-ns
的新命名空间中运行,该命名空间有两个服务,httpbin
和 sleep
,两者都各自附带一个 Envoy sidecar 代理。使用以下命令来设置环境变量以存储命名空间的名称,创建命名空间,并启动这两个服务。在运行以下命令之前,您需要输入包含 Istio 安装文件的目录。
- 将
NS
环境变量的值设置为rbac-listclaim-test-ns
:
$ export NS=authz-groups-test-ns
- 确保
NS
环境变量指向一个完全用于测试的命名空间。运行以下命令删除NS
环境变量指向的命名空间中的所有资源。
$ kubectl delete namespace $NS
- 为本教程创建命名空间:
$ kubectl create ns $NS
- 创建
httpbin
和sleep
服务和部署:
$ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n $NS
$ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n $NS
- 要验证
httpbin
和sleep
服务是否正在运行并且sleep
能够访问httpbin
,请运行以下 curl 命令:
$ kubectl exec $(kubectl get pod -l app=sleep -n $NS -o jsonpath={.items..metadata.name}) -c sleep -n $NS -- curl http://httpbin.$NS:8000/ip -s -o /dev/null -w "%{http_code}\n"
当命令成功时,它返回 HTTP 状态码为 200。
使用双向 TLS 配置 JSON Web 令牌(JWT)认证
您接下来应用的认证策略会强制要求访问 httpbin
服务需要具备有效的 JWT。策略中定义的 JSON Web 密钥集( JWKS )端点必须对 JWT 进行签名。本教程使用 Istio 代码库中的 JWKS 端点 并使用此示例 JWT。示例 JWT 包含一个标识为 groups
的声明键和一个 ["group1"
,"group2"
] 字符串列表的声明值。JWT 声明值可以是字符串或字符串列表;两种类型都支持。
- 应用认证策略同时需要双向 TLS 和
httpbin
服务的 JWT 认证。
$ cat <<EOF | kubectl apply -n $NS -f -
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "require-mtls-jwt"
spec:
targets:
- name: httpbin
peers:
- mtls: {}
origins:
- jwt:
issuer: "testing@secure.istio.io"
jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.5/security/tools/jwt/samples/jwks.json"
principalBinding: USE_ORIGIN
EOF
- 在
sleep
中应用DestinationRule
策略以使用双向 TLS 与httpbin
通信。
$ cat <<EOF | kubectl apply -n $NS -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: use-mtls-on-sleep
spec:
host: httpbin.$NS.svc.cluster.local
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
EOF
- 设置
TOKEN
环境变量以包含有效的示例 JWT。
$ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.5/security/tools/jwt/samples/groups-scope.jwt -s)
- 连接到
httpbin
服务:
$ kubectl exec $(kubectl get pod -l app=sleep -n $NS -o jsonpath={.items..metadata.name}) -c sleep -n $NS -- curl http://httpbin.$NS:8000/ip -s -o /dev/null -w "%{http_code}\n" --header "Authorization: Bearer $TOKEN"
当附加的 JWT 有效时,它返回 HTTP 状态码为 200。
- 当没有附加 JWT 时,验证与
httpbin
服务的连接是否失败:
$ kubectl exec $(kubectl get pod -l app=sleep -n $NS -o jsonpath={.items..metadata.name}) -c sleep -n $NS -- curl http://httpbin.$NS:8000/ip -s -o /dev/null -w "%{http_code}\n"
当没有附加有效的 JWT 时,它返回 HTTP 状态码为 401。
配置基于组的授权
本节创建一个策略授权来自特定组的请求访问 httpbin
服务。由于缓存和其他传播开销可能会有一些延迟,因此请等待新定义的 RBAC 策略生效。
- 为命名空间启用 Istio RBAC:
$ cat <<EOF | kubectl apply -n $NS -f -
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
{}
EOF
- 一旦 RBAC 策略生效,验证 Istio 是否拒绝了与
httpbin
服务的 curl 连接:
$ kubectl exec $(kubectl get pod -l app=sleep -n $NS -o jsonpath={.items..metadata.name}) -c sleep -n $NS -- curl http://httpbin.$NS:8000/ip -s -o /dev/null -w "%{http_code}\n" --header "Authorization: Bearer $TOKEN"
一旦 RBAC 策略生效,该命令返回 HTTP 状态码为 403。
- 要提供对
httpbin
服务的读访问权,请创建httpbin-viewer
服务角色:
$ cat <<EOF | kubectl apply -n $NS -f -
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "httpbin-viewer"
spec:
selector:
matchLabels:
app: httpbin
rules:
- to:
- operation:
methods: ["GET"]
when:
- key: request.auth.claims[groups]
values: ["group1"]
EOF
- 要将
httpbin-viewer
角色分配给group1
中的用户,请创建bind-httpbin-viewer
服务角色绑定。
$ cat <<EOF | kubectl apply -n $NS -f -
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: bind-httpbin-viewer
namespace: rbac-groups-test-ns
spec:
subjects:
- properties:
request.auth.claims[groups]: "group1"
roleRef:
kind: ServiceRole
name: "httpbin-viewer"
EOF
或者,您可以在 subject
下指定 group
属性。指定组的两种方式都是等效的。目前,Istio 仅支持与在 JWT 中的 request.auth.claims
属性和 subject
下的 group
属性进行字符串列表匹配。
指定 subject
下的 group
属性,请使用以下命令:
$ cat <<EOF | kubectl apply -n $NS -f -
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: bind-httpbin-viewer
namespace: rbac-groups-test-ns
spec:
subjects:
- group: "group1"
roleRef:
kind: ServiceRole
name: "httpbin-viewer"
EOF
等待新定义的 RBAC 策略生效。
- RBAC 策略生效后,验证与
httpbin
服务的连接是否成功:
$ kubectl exec $(kubectl get pod -l app=sleep -n $NS -o jsonpath={.items..metadata.name}) -c sleep -n $NS -- curl http://httpbin.$NS:8000/ip -s -o /dev/null -w "%{http_code}\n" --header "Authorization: Bearer $TOKEN"
HTTP Header 包含一个有效的 JWT,其 groups
声明值为["group1"
,"group2"
],因为它包含 group1
,所以返回 HTTP 状态码为 200。
配置列表类型声明的授权
Istio RBAC 支持配置列表类型声明的授权。示例中的 JWT 包含一个带有标识为 scope
的声明键和一个 ["scope1"
,"scope2"
] 字符串列表作为其声明值。您可以使用 gen-jwt
python 脚本生成带有其他列表类型声明的 JWT 进行测试。按照 gen-jwt
脚本中的说明使用 gen-jwt.py
文件。
- 要将
httpbin-viewer
角色分配给一个附加 JWT 其中包含值为scope1
的列表类型scope
声明的请求,请创建名为bind-httpbin-viewer
的服务角色进行绑定:
$ cat <<EOF | kubectl apply -n $NS -f -
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "httpbin-viewer"
spec:
selector:
matchLabels:
app: httpbin
rules:
- to:
- operation:
methods: ["GET"]
when:
- key: request.auth.claims[scope]
values: ["scope1"]
EOF
等待新定义的 RBAC 策略生效。
- RBAC 策略生效后,验证与
httpbin
服务的连接是否成功:
$ kubectl exec $(kubectl get pod -l app=sleep -n $NS -o jsonpath={.items..metadata.name}) -c sleep -n $NS -- curl http://httpbin.$NS:8000/ip -s -o /dev/null -w "%{http_code}\n" --header "Authorization: Bearer $TOKEN"
HTTP Header 包含一个有效的 JWT,scope
的声明值为["scope1"
,"scope2"
],因为它包含 scope1
, 所以返回 HTTP 状态码为 200。
清理
完成本教程后,运行以下命令删除在命名空间中创建的所有资源。
$ kubectl delete namespace $NS
相关内容
Istio v1beta1 授权策略的设计原则、基本概述及迁移操作。
基于 Istio 授权的 Micro-Segmentation
描述 Istio 的授权功能以及如何在各种用例中使用它。
展示如何设置基于角色的 HTTP 流量访问控制。
展示如何设置 TCP 流量的访问控制。
描述 Istio 的授权与鉴权功能。
阐述如何在不更改授权策略的前提下从一个信任域迁移到另一个。