前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用OPA实现Envoy外部授权

使用OPA实现Envoy外部授权

作者头像
CNCF
发布2019-12-04 11:16:17
2.1K0
发布2019-12-04 11:16:17
举报
文章被收录于专栏:CNCFCNCF

作者:Ash Narkar

微服务通过将应用程序分解为更小的、独立的部分来提高单个开发团队的生产力。然而,仅使用微服务并不能解决诸如服务发现、身份验证和授权等古老的分布式系统问题。事实上,由于微服务环境的异构性和短暂性,这些问题往往更为严重。

随着越来越多的组织采用微服务体系结构,对分离的身份验证和授权的需求变得越来越明显。本文将深入探讨如何利用EnvoySPIFFE/SPIREOpen Policy Agent(OPA)在微服务环境中执行重要的安全政策。

背景

Envoy是为大型现代面向服务架构设计的L7代理和通信总线。Envoy(v1.7.0+)支持外部授权过滤器(External Authorization filter),它调用授权服务来检查传入的请求是否被授权。该特性使将授权决策委托给外部服务成为可能,并使请求上下文对服务可用。请求上下文包含诸如网络活动的源、网络活动的目标、网络请求(例如http请求)。所有这些信息都可以被外部事务处用来对Envoy收到的传入请求的命运作出知情的决定。

SPIFFE(Secure Production Identity Framework for Everyone)是一组开放源码标准,用于在动态和异构环境中安全地标识软件系统。采用SPIFFE的系统无论在何处运行,都可以轻松可靠地进行相互身份验证。SPIRE(SPIFFE Runtime Environment,SPIFFE运行时环境)是一个工具链,用于在各种平台上的工作负载之间建立信任。

OPA(Open Policy Agent,开放政策代理)是一个开放源码的通用政策引擎,支持跨整个堆栈的统一的、上下文感知的政策执行。OPA的高级声明性语言Rego允许创建细粒度的安全政策,用于对结构化文档中表示的信息进行推理。

OPA作为外部授权服务

我们将演练一个使用Envoy的外部授权过滤器和OPA作为授权服务的示例。

Envoy-OPA外部授权

该示例由三个服务(web、后端和db)组成,它们与正在运行的Envoy服务进行协作。每个服务使用外部授权过滤器调用各自的OPA实例,检查是否允许传入请求。

web服务接收来自部署在不同子网中的api-server-1和api-server-2的所有入站请求。请求被转发到后端服务,后端服务随后调用db服务。

web、后端和db服务之间的安全通信,通过在每个容器中配置Envoy代理来建立彼此之间的mTLS连接来实现的。Envoy从实现Envoy SDS的SPIRE代理,获得用于mTLS通信的客户机和服务器TLS证书和可信CA根。代理依次从SPIRE服务器获取此信息,并将其提供给已标识的工作负载。在下面的示例中,SPIRE以嵌入到TLS证书中的SPIFFE ID的形式,为每个工作负载提供一个身份,以方便mTLS通信。然后,OPA可以使用每个工作负载的SPIFFE ID来构建授权政策。更多关于塔尖的信息可以在这里找到。

https://spiffe.io/spire/overview/

  • Envoy监听每个容器8001端口的进入情况。
  • api-server-1和api-server-2是分别运行在端口5000和5001上的flask应用程序,它们将请求转发给web服务。
  • api-server-1在172.28.0.0/16子网中有一个静态IP,而api-server-2在192.28.0.0/16子网中有一个静态IP。
  • OPA通过GRPC服务器进行扩展,实现了Envoy外部授权API。
  • data.envoy.authz.allow是决定是否允许请求的默认OPA政策。
  • 查询的GRPC服务器端口和默认OPA政策都是可配置的。

运行这个例子

第一步:安装Docker

确保安装了docker和docker-compose的最新版本。

第二步:克隆repo并启动容器

克隆OPA-Envoy-SPIRE repo:

git clone git@github.com:ashutosh-narkar/opa-envoy-spire-ext-authz.git

$ cd opa-envoy-spire-ext-authz
$ docker-compose up --build -d
$ docker-compose ps

下列容器应正常运作:

                  Name                                 Command               State                 Ports
----------------------------------------------------------------------------------------------------------------------
opa-envoy-spiffe-ext-authz_api-server-1_1   flask run --host=0.0.0.0         Up      0.0.0.0:5000->5000/tcp
opa-envoy-spiffe-ext-authz_api-server-2_1   flask run --host=0.0.0.0         Up      0.0.0.0:5001->5000/tcp, 5001/tcp
opa-envoy-spiffe-ext-authz_backend_1        /bin/sh -c /usr/local/bin/ ...   Up      10000/tcp
opa-envoy-spiffe-ext-authz_db_1             /bin/sh -c /usr/local/bin/ ...   Up      10000/tcp
opa-envoy-spiffe-ext-authz_opa_be_1         ./opa_istio_linux_amd64 -- ...   Up      0.0.0.0:9192->9192/tcp
opa-envoy-spiffe-ext-authz_opa_db_1         ./opa_istio_linux_amd64 -- ...   Up      0.0.0.0:9193->9193/tcp
opa-envoy-spiffe-ext-authz_opa_web_1        ./opa_istio_linux_amd64 -- ...   Up      0.0.0.0:9191->9191/tcp
opa-envoy-spiffe-ext-authz_spire-server_1   /usr/bin/dumb-init /opt/sp ...   Up
opa-envoy-spiffe-ext-authz_web_1            /bin/sh -c /usr/local/bin/ ...   Up      10000/tcp, 0.0.0.0:8001->8001/tcp

第三步:启动SPIRE基础设施

启动SPIRE代理并在SPIRE服务器上注册web、后端和db服务器。更多关于注册过程的信息可以在这里找到。

$ ./configure-spire.sh

第四步:实行进入政策

进入政策声明web服务只能从子网172.28.0.0/16访问。

检查api-server-1是否可以访问web服务。

$ curl -i localhost:5000/hello
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 29
Server: Werkzeug/0.15.2 Python/2.7.15
Date: Thu, 02 May 2019 21:21:48 GMT

Hello from the web service !

检查api-server-2不能访问web服务。

$ curl -i localhost:5001/hello
HTTP/1.0 403 FORBIDDEN
Content-Type: text/html; charset=utf-8
Content-Length: 40
Server: Werkzeug/0.15.2 Python/2.7.15
Date: Thu, 02 May 2019 21:22:12 GMT

Access to the Web service is forbidden.

第五步:实施服务对服务政策

服务到服务政策声明请求可以从web流到后端到db服务。

检查这个流是否被接受。

$ curl -i localhost:5000/the/good/path
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 35
Server: Werkzeug/0.15.2 Python/2.7.15
Date: Thu, 02 May 2019 21:22:50 GMT

Allowed path: WEB -> BACKEND -> DB

检查web服务是否不允许直接调用db服务。

$ curl -i localhost:5000/the/bad/path
HTTP/1.0 403 FORBIDDEN
Content-Type: text/html; charset=utf-8
Content-Length: 26
Server: Werkzeug/0.15.2 Python/2.7.15
Date: Thu, 02 May 2019 21:23:22 GMT

Forbidden path: WEB -> DB

OPA政策例子

每个服务为一个决策调用其各自的OPA实例,并将其所需的政策加载到OPA中。要查看服务加载的OPA政策,请查看repo中的docker目录。

政策-1示例

上面示例中使用的以下OPA政策被加载到web服务调用的OPA中。

  • web服务只能从子网172.28.0.0/16访问
import input.attributes.request.http as http_request
import input.attributes.source.address as source_address

default allow = false

allowed_paths = {"/hello", "/the/good/path", "/the/bad/path"}

# allow access to the Web service from the subnet 172.28.0.0/16 for the allowed paths
allow {
    allowed_paths[http_request.path]
    http_request.method == "GET"
    net.cidr_contains("172.28.0.0/16", source_address.Address.SocketAddress.address)
}

OPA-Envoy进入政策

Rego游乐场尝试OPA-Envoy进入政策!

政策-2示例

本例中使用的另一项政策规定:

  • 请求可以从web流到后端到db服务

下面是一个政策片段,它被加载到db服务调用的OPA中。该政策只允许从后端服务请求db服务。

package envoy.authz

import input.attributes.request.http as http_request
import input.attributes.source.address as source_address

default allow = false

# allow Backend service to access DB service
allow {
    http_request.path == "/good/db"
    http_request.method == "GET"
    svc_spiffe_id == "spiffe://domain.test/backend-server"
}

svc_spiffe_id = client_id {
    [_, _, uri_type_san] := split(http_request.headers["x-forwarded-client-cert"], ";")
    [_, client_id] := split(uri_type_san, "=")
}

OPA-Envoy服务政策

Rego游乐场尝试OPA-Envoy服务对服务政策!

X-Forward-Client-Cert头由发起服务的Envoy代理注入,并由目标服务的Envoy代理验证。将Envoy配置为转发客户机证书中的URI字段。为了标识发出请求的服务,该政策使用X-Forward-Client-Cert头的URI字段,在本例中,该头是后端服务器的SPIFFE ID。

X-Forward-Client-Cert(XFCC)是一个代理标头,它指示请求在从客户机到服务器的过程中流经的部分,或全部客户机或代理的证书信息。有关标题及其支持的键的更多信息可以在这里找到。

https://www.envoyproxy.io/docs/envoy/latest/configuration/http_conn_man/headers#x-forwarded-client-cert

Envoy配置例子

下面是一个Envoy代理的示例配置,该代理侦听端口80上的HTTP客户机连接,然后调用OPA的gRPC服务器,该服务器实现了Envoy外部授权API。

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

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 80
    use_original_dst: true
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
            - name: envoy.file_access_log
              config:
                path: "/dev/stdout"
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              - match:
                  prefix: "/hello"
                route:
                  cluster: web-service
              - match:
                  prefix: "/the/good/path"
                route:
                  cluster: web-service
              - match:
                  prefix: "/the/bad/path"
                route:
                  cluster: web-service
          http_filters:
          - name: envoy.ext_authz
            config:
              failure_mode_allow: false
              grpc_service:
                google_grpc:
                  target_uri: opa:9191
                  stat_prefix: ext_authz
                timeout: 0.5s
          - name: envoy.router
            config: {}
  clusters:
  - name: web-service
    connect_timeout: 0.25s
    type: strict_dns
    lb_policy: round_robin
    http2_protocol_options: {}
    load_assignment:
      cluster_name: web-service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: web-service
                port_value: 80
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8001

这就是了!

这就是如何使用OPA作为外部授权服务,使用Envoy的外部授权过滤器强制执行进入和服务到服务的安全政策。OPA利用SPIFFE/SPIRE提供的身份验证框架,通过将Envoy配置为转发客户端证书细节,OPA能够基于客户端X.509证书的URI SAN中包含的SPIFFE ID做出授权决策。

源代码

示例代码可以在这里找到:https://github.com/ashutosh-narkar/opa-envoy-spi-ext-authz。

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

本文分享自 CNCF 微信公众号,前往查看

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

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

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