基于组和列表声明的授权

    • 阅读授权概念并阅读有关如何的指南。

    • 阅读 Istio 认证策略和相关的概念。

    • 创建一个安装了 Istio 并启用了双向 TLS 的 Kubernetes 集群。要满足此先决条件,您可以按照 Kubernetes 安装说明进行操作。

    设置所需的命名空间和服务

    本教程在一个名为 的新命名空间中运行,该命名空间有两个服务,httpbinsleep,两者都各自附带一个 Envoy sidecar 代理。使用以下命令来设置环境变量以存储命名空间的名称,创建命名空间,并启动这两个服务。在运行以下命令之前,您需要输入包含 Istio 安装文件的目录。

    • NS 环境变量的值设置为 rbac-listclaim-test-ns
    • 确保 NS 环境变量指向一个完全用于测试的命名空间。运行以下命令删除 NS 环境变量指向的命名空间中的所有资源。
    1. $ kubectl delete namespace $NS
    • 为本教程创建命名空间:
    1. $ kubectl create ns $NS
    • 创建 httpbinsleep 服务和部署:

    Zip

    1. $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n $NS
    2. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@) -n $NS
    • 要验证 httpbinsleep 服务是否正在运行并且 sleep 能够访问 httpbin,请运行以下 curl 命令:
    1. $ 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。

    您接下来应用的认证策略会强制要求访问 httpbin 服务需要具备有效的 JWT。策略中定义的 JSON Web 密钥集( JWKS )端点必须对 JWT 进行签名。本教程使用 Istio 代码库中的 JWKS 端点 并使用。示例 JWT 包含一个标识为 groups 的声明键和一个 ["group1""group2"] 字符串列表的声明值。JWT 声明值可以是字符串或字符串列表;两种类型都支持。

    • 应用认证策略同时需要双向 TLS 和 httpbin 服务的 JWT 认证。
    1. $ cat <<EOF | kubectl apply -n $NS -f -
    2. apiVersion: "authentication.istio.io/v1alpha1"
    3. kind: "Policy"
    4. metadata:
    5. name: "require-mtls-jwt"
    6. spec:
    7. targets:
    8. - name: httpbin
    9. peers:
    10. - mtls: {}
    11. origins:
    12. - jwt:
    13. issuer: "testing@secure.istio.io"
    14. principalBinding: USE_ORIGIN
    15. EOF
    • sleep 中应用 DestinationRule 策略以使用双向 TLS 与 httpbin 通信。
    • 设置 TOKEN 环境变量以包含有效的示例 JWT。
    1. $ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.5/security/tools/jwt/samples/groups-scope.jwt -s)
    • 连接到 httpbin 服务:

    当附加的 JWT 有效时,它返回 HTTP 状态码为 200。

    • 当没有附加 JWT 时,验证与 httpbin 服务的连接是否失败:
    1. $ 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。

    配置基于组的授权

    • 为命名空间启用 Istio RBAC:
    1. $ cat <<EOF | kubectl apply -n $NS -f -
    2. apiVersion: security.istio.io/v1beta1
    3. kind: AuthorizationPolicy
    4. metadata:
    5. name: deny-all
    6. spec:
    7. {}
    8. EOF
    • 一旦 RBAC 策略生效,验证 Istio 是否拒绝了与 httpbin 服务的 curl 连接:
    1. $ 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 服务角色:
    • 要将 httpbin-viewer 角色分配给 group1 中的用户,请创建 bind-httpbin-viewer 服务角色绑定。
    1. $ cat <<EOF | kubectl apply -n $NS -f -
    2. apiVersion: "rbac.istio.io/v1alpha1"
    3. kind: ServiceRoleBinding
    4. metadata:
    5. name: bind-httpbin-viewer
    6. namespace: rbac-groups-test-ns
    7. spec:
    8. subjects:
    9. - properties:
    10. request.auth.claims[groups]: "group1"
    11. roleRef:
    12. kind: ServiceRole
    13. EOF

    或者,您可以在 subject 下指定 group 属性。指定组的两种方式都是等效的。目前,Istio 仅支持与在 JWT 中的 request.auth.claims 属性和 subject 下的 group 属性进行字符串列表匹配。

    指定 subject 下的 group 属性,请使用以下命令:

    1. $ cat <<EOF | kubectl apply -n $NS -f -
    2. apiVersion: "rbac.istio.io/v1alpha1"
    3. kind: ServiceRoleBinding
    4. metadata:
    5. name: bind-httpbin-viewer
    6. spec:
    7. subjects:
    8. - group: "group1"
    9. roleRef:
    10. kind: ServiceRole
    11. name: "httpbin-viewer"
    12. EOF

    等待新定义的 RBAC 策略生效。

    • RBAC 策略生效后,验证与 httpbin 服务的连接是否成功:
    1. $ 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 生成带有其他列表类型声明的 JWT 进行测试。按照 gen-jwt 脚本中的说明使用 gen-jwt.py 文件。

    • 要将 httpbin-viewer 角色分配给一个附加 JWT 其中包含值为 scope1 的列表类型 scope 声明的请求,请创建名为 bind-httpbin-viewer 的服务角色进行绑定:
    1. $ cat <<EOF | kubectl apply -n $NS -f -
    2. apiVersion: "security.istio.io/v1beta1"
    3. kind: "AuthorizationPolicy"
    4. metadata:
    5. name: "httpbin-viewer"
    6. spec:
    7. selector:
    8. matchLabels:
    9. app: httpbin
    10. rules:
    11. - to:
    12. - operation:
    13. methods: ["GET"]
    14. when:
    15. - key: request.auth.claims[scope]
    16. values: ["scope1"]
    17. EOF

    等待新定义的 RBAC 策略生效。

    1. $ 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",],因为它包含 scope1, 所以返回 HTTP 状态码为 200。

    清理

    完成本教程后,运行以下命令删除在命名空间中创建的所有资源。

    Istio v1beta1 授权策略的设计原则、基本概述及迁移操作。

    描述 Istio 的授权功能以及如何在各种用例中使用它。

    HTTP 流量授权

    展示如何设置基于角色的 HTTP 流量访问控制。

    展示如何设置 TCP 流量的访问控制。

    安全

    描述 Istio 的授权与鉴权功能。

    阐述如何在不更改授权策略的前提下从一个信任域迁移到另一个。