一文了解Istio外部授权

本文介绍了Istio的授权机制,包括本地授权的EnvoyRBAC和外部授权服务,如OpenPolicyAgent。Istio的AuthorizationPolicy提供声明式API,允许精细的访问控制。此外,文章还展示了如何集成OPA实现更复杂的策略控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击上方“程序猿技术大咖”,关注并选择“设为星标”

回复“加群”获取入群讨论资格!

初识Istio Authorization

我们都知道认证(Authentication、Authn)与授权(Authorization、Authz)一同构建了起网络应用安全的基本屏障。通常,授权对认证有一定的依赖。比如我们熟悉的OAuth或者基于JWT Token的授权。

Istio授权充分利用了Envoy的授权插件,基本覆盖业界主流的访问控制策略。Istio Authz功能提供了服务网格、命名空间以及工作负载范围的访问控制,多种粒度的访问控制具有以下好处:

1. 工作负载到工作负载以及最终用户到工作负载授权

2. 简单的API:Istio利用声明式的AuthorizationPolicy,对用户来说简单易用。

3. 灵活的语法:用户可以基于Istio的访问属性(身份,命名控制等)自定义控制策略(ALLOW, DENY,CUSTOM)

4. 高性能:Istio本地授权在envoy进程内部执行

5. 灵活扩展性:外部授权支持更加复杂的访问控制,外部授权支持HTTP、gRPC协议,后面重点讲解。

Istio Authorization架构及原理

7f54ccf34bdd880bffa754083a8c8f3b.png

授权架构

授权策略强制对服务器端 Envoy 代理中Inboud流量进行访问控制。每个 Envoy 代理运行一个授权引擎,在运行时授权请求。当请求到达代理时,授权引擎根据当前授权策略评估请求上下文,并返回授权结果,允许或拒绝。用户可以通过AuthorizationPolicy指定访问控制策略。

本地授权基于Envoy RBAC(Role Based Access Control)过滤器实现。RBAC Filter可以用来对识别到的下游客户(Principals)进行授权。这对于显式管理应用程序的调用者并保护应用程序很有用。RBAC本地授权支持使用连接属性(IP,端口,SSL subject)以及HTTP头配置ALLOW或DENY列表。

External Authorization

988dbc3ab7d7568e89e9e93decf8d374.png

External Authorization

Envoy (v1.7.0+) 支持外部授权过滤器,它调用授权服务来检查传入请求是否被授权。External Authz可以将授权决策委托给外部服务,并将请求上下文传递给授权服务。请求上下文包含诸如网络请求的来源、网络请求的目的地、网络请求(例如http请求)等信息。外部服务可以使用所有这些信息来对 Envoy 收到的传入请求的命运做出明智的决定。

Envoy外部授权过滤器有两种:一种是TCP的网络过滤器,另一种是HTTP过滤器。理论上可以配置任意的外部过滤器,当请求被TCP的外部授权拒绝时,网络连接自动断开,当网络请求被HTTP外部授权过滤器拒绝时,则会返回403 HTTP响应码。

目前有一些成熟的开源外部授权服务器实现,比如Open Policy Agent, oauth2-proxy。当然也可以实现自己的授权服务器,参考Istio例子:https://github.com/istio/istio/blob/master/samples/extauthz/src/main.go

外部授权接口支持gRPC和HTTP两种协议。Envoy通过CheckRequest定义了传递给授权服务的请求上下文属性,供其进行决策。请求上下文主要分为:

●  Source :源地址,身份principal(Istio从x509证书SAN中提取)

●  Destination:目的地址,身份principal(Istio从x509证书SAN中提取)

●  Request:网络请求,HTTP头,方法,请求参数,协议等信息

授权API External AuthorizationPolicy

AuthorizationPolicy与Istio其他的API一样也是通过CRD定义的,声明式的API。其优点是简单易用。首先简单了解一下AuthorizationPolicy:

type AuthorizationPolicy struct {   

// Optional. The selector decides where to apply the authorization policy. The selector will match with workloads   

// in the same namespace as the authorization policy. If the authorization policy is in the root namespace, the selector  

// will additionally match with workloads in all namespaces.   

//   

// If not set, the selector will match all workloads.   

Selector *v1beta1.WorkloadSelector

     // Optional. A list of rules to match the request. A match occurs when at least one rule matches the request.  

//   

// If not set, the match will never occur. This is equivalent to setting a default of deny for the target workloads if   

// the action is ALLOW.   

Rules[]*Rule   

// Optional. The action to take if the request is matched with the rules. Default is ALLOW if not specified.   

Action AuthorizationPolicy_Action    // Types that are valid to be assigned to ActionDetail:  

// *AuthorizationPolicy_Provider   

ActionDetail         isAuthorizationPolicy_ActionDetail

Selector: 决定此授权策略应用到哪个工作负载。

cc20ee5383085e34be00c6051ed05010.png

授权策略语义分析

Rules:一组匹配策略,当任意策略匹配上的时候,执行下面的Action。Rule支持三种匹配,

1. From,即匹配请求源

2. To,匹配请求的操作,比如访问路径,方法

3. When,指定执行这条规则的条件,例如当request.auth.claims[iss]

Action:决策结果:ALLOW、DENY、CUSTOM,CUSTOM则是指定外部授权方式,同时必须指定下面的ActionDetail

ActionDetail:授权服务provider  

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 action: ALLOW
 rules:
 - from:
   - source:
       principals: ["cluster.local/ns/default/sa/sleep"]
   - source:
       namespaces: ["default"]
   to:
   - operation:
       methods: ["GET"]
   when:
   - key: request.auth.claims[iss]
     values: ["https://accounts.google.com"]

上面的例子表示Istio使用本地授权,当网络请求使用JWT认证,签发者是google时,允许服务账户为“cluster.local/ns/default/sa/sleep”,来自default命名空间的服务,访问httbin-v1服务的GET接口。否则,决绝访问httpbin-v1。

Istio允许用户为同一个服务指定多个授权策略,为了避免不同的AuthorizationPolicy相互冲突,Istio定义了一定的优先级策略,如下所示:

1. 首先执行CUSTOM的外部授权,如果外部授权结果为ALLOW,则继续执行本地授权当结果为DENY时,则直接返回DENY决策,退出授权链。

2. 执行DENY的本地授权规则,当请求匹配DENY条件时,返回DENY决策,退出授权链。否则继续执行ALLOW的本地授权规则

3. 执行ALLOW的本地授权策略,当请求匹配ALLOW Rule时,返回ALLOW,否则不能匹配ALLOW Rule,直接返回DENY。

2a25defd0a04ad32554fbec6fda28ace.png

授权策略优先级

参考链接:

https://www.openpolicyagent.org/docs/latest/envoy-introduction/ 

Open Policy Agent介绍

OPA是为云原生环境设计的策略引擎,目前已经是CNCF的毕业项目。OPA的愿景打造云原生乃至整个业界策略控制的事实标准。

“停止为您使用的每种产品和服务使用不同的策略语言、策略模型和策略 API。将 OPA 用于云原生堆栈的统一工具集和策略框架。

无论是针对一项服务还是针对您的所有服务,都可以使用 OPA 将策略与服务代码分离,这样您就可以在不牺牲可用性或性能的情况下发布、分析和审查策略(安全和合规团队喜欢的策略)。”

OPA是一种声明式的策略引擎,使用rego表示策略。OPA-Envoy Plugin扩展了OPA,实现了Envoy的外部授权gRPC服务。因此Istio外部授权可以直接使用OPA-Envoy插件。

6a32c705faa6c195797f0baf8d272020.png

 Istio与OPA集成

将OPA-Envoy以Sidecar的形式部署在应用旁是一种更为推荐的方式,这样远程调用的时延最小。然而这也不是必须的,OPA也可以中心式部署。

Istio外部授权-集成OPA

OPA官网https://www.openpolicyagent.org/docs/latest/envoy-tutorial-istio/提供了如何利用Istio Envoyfilter配置由OPA-Envoy执行授权访问控制。由于OPA-Envoy以边车的形式部署,所以没有使用AuthorizationPolicy,而是直接通过EnvoyFilter,控制外部授权服务的地址。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: ext-authz
  namespace: istio-system
spec:
  configPatches:
    - applyTo: HTTP_FILTER
      match:
        context: SIDECAR_INBOUND
        listener:
          filterChain:
            filter:
              name: "envoy.filters.network.http_connection_manager"
              subFilter:
                name: "envoy.filters.http.router"
      patch:
        operation: INSERT_BEFORE
        value:
          name: envoy.ext_authz
          typed_config:
            '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
            transport_api_version: V3
            status_on_error:
              code: ServiceUnavailable
            with_request_body:
              max_request_bytes: 8192
              allow_partial_message: true
            grpc_service:
              # NOTE(tsandall): when this was tested with the envoy_grpc client the gRPC
              # server was receiving check requests over HTTP 1.1. The gRPC server in
              # OPA-Istio would immediately close the connection and log that a bogus
              # preamble was sent by the client (it expected HTTP 2). Switching to the
              # google_grpc client resolved this issue.
              google_grpc:
                target_uri: 127.0.0.1:9191
                stat_prefix: "ext_authz"

上述Envoyfilter样例向Envoy中插入一个HTTP外部授权过滤器,控制所有的请求都向127.0.0.1:9191这个服务发起授权请求。实际上这正是OPA-Envoy边车监听的地址。

OPA-Envoy的策略声明如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: opa-policy
data:
  policy.rego: |
    package istio.authz
    import input.attributes.request.http as http_request
    import input.parsed_path
    default allow = false
    allow {
        parsed_path[0] == "health"
        http_request.method == "GET"
    }
    allow {
        roles_for_user[r]
        required_roles[r]
    }
    roles_for_user[r] {
        r := user_roles[user_name][_]
    }
    required_roles[r] {
        perm := role_perms[r][_]
        perm.method = http_request.method
        perm.path = http_request.path
    }
    user_name = parsed {
        [_, encoded] := split(http_request.headers.authorization, " ")
        [parsed, _] := split(base64url.decode(encoded), ":")
    }
    user_roles = {
        "alice": ["guest"],
        "bob": ["admin"]
    }
    role_perms = {
        "guest": [
            {"method": "GET",  "path": "/productpage"},
        ],
        "admin": [
            {"method": "GET",  "path": "/productpage"},
            {"method": "GET",  "path": "/api/v1/products"},
        ],
    }

●  用户alice被授予guest角色,具有发起GET请求/productpage的权限。

● 用户bob被授予admin角色,具有发起GET请求/productpage和/api/v1/products的权限。

在典型的部署中,策略要么内置到 OPA 容器映像中,要么通过 Bundle API 动态获取。在这里是通过Configmap挂载到容器中。

参考链接

1.https://istio.io/latest/docs/tasks/security/authorization/authz-custom/ 

2. https://istio.io/latest/docs/concepts/security/#authoriz

ation 

3.https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/ext_authz_filter.html

4. https://www.openpolicyagent.org/docs/latest/envoy-tutorial-istio/   


感谢您的阅读,也欢迎您发表关于这篇文章的任何建议,关注我,技术不迷茫!

35c417d28d245d1659507165b61f6f77.gif

0431af2497e365ee63a57d2a048a723d.gif

喜欢就点个"在看"呗,留言、转发朋友圈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值