基于组和列表声明的授权
本教程将向您介绍在 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/master/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/master/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 的授权与鉴权功能。
阐述如何在不更改授权策略的前提下从一个信任域迁移到另一个。