前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >istio1.9中新的外部授权策略

istio1.9中新的外部授权策略

作者头像
有点技术
发布2021-03-08 15:37:14
1.5K0
发布2021-03-08 15:37:14
举报
文章被收录于专栏:有点技术有点技术有点技术

背景

istio 中的授权策略为网格内部的服务提供访问控制。授权策略是快速、强大及被广泛使用的功能,自istio 1.4首次发布以来,我们进行了持续改进,以使策略更加灵活,包含 DENY action, 排除语义, X-Forwarded-For 头支持, 嵌套 JWT claim 支持等,这些功能提高了授权策略的灵活性,但是此模型仍然不支持许多用例,例如:

•您拥有自己的内部授权系统,该系统无法轻松迁移到授权策略或无法轻松地被其替换。•您想与第三方解决方案(例如,opa 或oauth2代理)集成,该解决方案可能需要使用Istio中的底层Envoy配置API,或者根本无法使用。•对于您的用例,授权策略缺乏必要的语义。

解决方案

在istio 1.9中,引入了 CUSTOM action来实现对授权策略的可扩展性,该操作使您可以将访问控制决策委派给外部授权服务。

CUSTOM action使您可以将Istio与实现其自己的自定义授权逻辑的外部授权系统集成。下图显示了此集成的高级体系结构:

外部授权架构

在配置时,网格管理员使用一种CUSTOM action来配置授权策略,以在代理(网关或Sidecar)上启用外部授权。管理员应验证外部身份验证服务已启动并正在运行。

在运行时,

1.代理将拦截请求,代理将按照用户在授权策略中配置的方式将检查请求发送到外部身份验证服务。2.外部身份验证服务将决定是否允许它。3.如果允许,该请求将继续,并将由ALLOW/ DENYaction定义的任何本地授权强制执行。4.如果被拒绝,该请求将立即被拒绝。

让我们看一下带有该CUSTOM动作的示例授权策略:

apiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:  name: ext-authz  namespace: istio-systemspec:  # 选择器适用于istio-system 命名空间中的入口网关。  selector:    matchLabels:      app: istio-ingressgateway  # CUSTOM action将访问控制委派给外部授权者,这与在代理内部强制执行访问控制的ALLOW / DENY操作不同。  action: CUSTOM  # 提供程序指定在meshconfig中定义的外部授权者的名称,该名称指示在何处以及如何与外部身份验证服务进行通信。  provider:    name: "my-ext-authz-service"  # 该规则指定仅当请求路径具有前缀"/admin/"时才触发访问控制。这使您可以根据请求轻松启用或禁用外部授权,从而避免了不需要外部检查请求的情况。  rules:  - to:    - operation:        paths: ["/admin/*"]

引用了定义在mesh config中名为my-ext-authz-service 的提供者

extensionProviders:# 授权策略在其提供者字段中引用名称"my-ext-authz-service"。- name: "my-ext-authz-service"  # "envoyExtAuthzGrpc"字段指定由Envoy ext-authz过滤器gRPC API实现的外部授权服务的类型。另一个受支持的类型是Envoy ext-authz filter HTTP API。  envoyExtAuthzGrpc:    # 服务和端口指定外部身份验证服务的地址,"ext-authz.istio-system.svc.cluster.local"表示该服务已部署在网格中。也可以将其定义为网格之外,甚至可以将其定义为单独的容器。    service: "ext-authz.istio-system.svc.cluster.local"    port: 9000

CUSTOM action 授权策略使运行时启用外部授权,它可以被配置为根据使用您已经使用其他action同样的规则要求的外部授权进行触发。

外部授权服务当前在meshconfigAPI中定义,并通过其名称引用。它可以在有或没有代理的情况下部署在网格中。如果使用代理,则可以进一步用于PeerAuthentication在代理和外部授权服务之间启用mTLS。

该CUSTOM action目前处于实验阶段; API可能会根据用户反馈以非向后兼容的方式进行更改。该规则当前不支持与身份验证相关的字段(例如,source principal 或 JWT claim),并且给定工作负载仅允许一个提供程序,但是您仍可以在不同的工作负载上使用不同的提供程序。

OPA示例

在本节中,我们将演示如何将CUSTOM action与opa一起用作入口网关上的外部授权者。我们将有条件地在除/ip之外的所有路径上启用外部授权。

您也可以参考外部授权任务以获取使用示例ext-authz服务器的更基本的介绍

创建示例OPA 策略

运行以下命令,创建一个OPA策略,如果路径的前缀与JWT令牌中的声明"path"(base64编码)匹配,则允许该请求:

cat > policy.rego <<EOFpackage envoy.authzimport input.attributes.request.http as http_requestdefault allow = falsetoken = {"valid": valid, "payload": payload} {    [_, encoded] := split(http_request.headers.authorization, " ")    [valid, _, payload] := io.jwt.decode_verify(encoded, {"secret": "secret"})}allow {    is_token_valid    action_allowed}is_token_valid {  token.valid  now := time.now_ns() / 1000000000  token.payload.nbf <= now  now < token.payload.exp}action_allowed {  startswith(http_request.path, base64url.decode(token.payload.path))}EOFkubectl create secret generic opa-policy --from-file policy.rego

部署httpbin和OPA

启用sidecar注入

kubectl label ns default istio-injection=enabled

运行以下命令以部署示例应用程序httpbin和OPA。OPA可以作为单独的容器部署在httpbin容器中,也可以完全部署在单独的容器中:

kubectl apply -f - <<EOFapiVersion: v1kind: Servicemetadata:  name: opa  labels:    app: opaspec:  ports:  - name: grpc    port: 9191    targetPort: 9191  selector:    app: opa---kind: DeploymentapiVersion: apps/v1metadata:  name: opa  labels:    app: opaspec:  replicas: 1  selector:    matchLabels:      app: opa  template:    metadata:      labels:        app: opa    spec:      containers:        - name: opa          image: openpolicyagent/opa:latest-envoy          securityContext:            runAsUser: 1111          volumeMounts:          - readOnly: true            mountPath: /policy            name: opa-policy          args:          - "run"          - "--server"          - "--addr=localhost:8181"          - "--diagnostic-addr=0.0.0.0:8282"          - "--set=plugins.envoy_ext_authz_grpc.addr=:9191"          - "--set=plugins.envoy_ext_authz_grpc.query=data.envoy.authz.allow"          - "--set=decision_logs.console=true"          - "--ignore=.*"          - "/policy/policy.rego"          ports:          - containerPort: 9191          livenessProbe:            httpGet:              path: /health?plugins              scheme: HTTP              port: 8282            initialDelaySeconds: 5            periodSeconds: 5          readinessProbe:            httpGet:              path: /health?plugins              scheme: HTTP              port: 8282            initialDelaySeconds: 5            periodSeconds: 5      volumes:        - name: proxy-config          configMap:            name: proxy-config        - name: opa-policy          secret:            secretName: opa-policyEOF

还要部署httpbin:

kubectl apply -f samples/httpbin/httpbin.yaml

定义外部授权者

运行以下命令以编辑meshconfig:

kubectl edit configmap istio -n istio-system

将以下内容添加extensionProviders到中meshconfig:

apiVersion: v1data:  mesh: |-    # Add the following contents:    extensionProviders:    - name: "opa.default"      envoyExtAuthzGrpc:        service: "opa.default.svc.cluster.local"        port: "9191"

使用CUSTOM action创建AuthorizationPolicy

运行以下命令以创建授权策略,以在除/ip以下路径之外的所有路径上启用外部授权:

$ kubectl apply -f - <<EOFapiVersion: security.istio.io/v1beta1kind: AuthorizationPolicymetadata:  name: httpbin-opaspec:  selector:    matchLabels:      app: httpbin  action: CUSTOM  provider:    name: "opa.default"  rules:  - to:    - operation:        notPaths: ["/ip"]EOF

测试OPA政策

•创建一个客户端窗格来发送请求:

$ kubectl apply -f samples/sleep/sleep.yaml$ export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})

•使用由OPA签名的测试JWT令牌:

$ export TOKEN_PATH_HEADERS="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXRoIjoiTDJobFlXUmxjbk09IiwibmJmIjoxNTAwMDAwMDAwLCJleHAiOjE5MDAwMDAwMDB9.9yl8LcZdq-5UpNLm0Hn0nnoBHXXAnK4e8RSl9vn6l98"

•测试JWT令牌具有以下claims:

{  "path": "L2hlYWRlcnM=",  "nbf": 1500000000,  "exp": 1900000000}

path claim 要求有值L2hlYWRlcnM=,其是/headers的BASE64编码。

•将请求发送到/headers没有令牌的路径。应该使用403拒绝它,因为没有JWT令牌:

$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/headers -s -o /dev/null -w "%{http_code}\n"403

•/get使用有效令牌向路径发送请求。这应该用403拒绝,因为路径/get与令牌不匹配/headers:

$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/get -H "Authorization: Bearer $TOKEN_PATH_HEADERS" -s -o /dev/null -w "%{http_code}\n"403

•/headers使用有效令牌向路径发送请求。应该使用200,因为路径与令牌匹配:

$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/headers -H "Authorization: Bearer $TOKEN_PATH_HEADERS" -s -o /dev/null -w "%{http_code}\n"200

•将请求发送到/ip没有令牌的路径。应该允许使用200,因为该路径/ip已排除在授权范围之外:

$ kubectl exec ${SLEEP_POD} -c sleep  -- curl http://httpbin-with-opa:8000/ip -s -o /dev/null -w "%{http_code}\n"200

•检查代理和OPA日志以确认结果。

概括

在Istio 1.9中,CUSTOM授权策略中的action使您可以轻松地将Istio与任何外部授权系统集成,具有以下优点:

•授权策略API中的一流支持•易用性:只需使用URL定义外部授权者,并使用授权策略启用,再也不用担心EnvoyFilterAPI•条件触发,可提高性能•支持外部授权者的各种部署类型:•具有或不具有代理的普通服务和Pod•在工作负载窗格中作为单独的容器•外网

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有点技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 解决方案
  • OPA示例
    • 创建示例OPA 策略
      • 部署httpbin和OPA
        • 定义外部授权者
          • 使用CUSTOM action创建AuthorizationPolicy
            • 测试OPA政策
            • 概括
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档