走马观花云原生技术(12):规则管理Open Policy Agent

2022-11-18 14:54:12 浏览数 (1)

继续我们的云原生技术走马观花的旅途,这一次我聊一下规则管理Open Policy Agent。相比较来说,这个概念及使用可能并不广范,大多数情况下并无必要使用这个东西,因为它增加了架构与部署的复杂度。

不过凡事都有但是,对于安全非常在意思的一些组织或企业来说,它是一个很有价值的工具。

这篇文章,我将试图在概念上给大家理清楚:

  • • 什么是Policy及Policy Engine
  • • 什么是Open Policy Agent
  • • 如何在K8S中使用OPA

Policy及Policy Engine

什么是Policy

Policy这个英文单词是政策,策略或规则的意思,我在这把它翻译成了规则。那什么是规则,应该还是比较好理解的,Policy某种程度上可以说是允许,约束限制,它与安全密切相关联的。

那在编程的世界中,哪些属于Policy呢,举例说明:

  • • 限制内网IP才允许SSH远程登录到服务器,其它则禁止
  • • 允许超级管理员任意修改用户的密码,其它禁止
  • • 只允许从公司镜像仓储拉取镜像,其它则禁止

上面的这些都是Policy,所以Policy大多是一些允许,约束或限制,它是为了强化架构或业务上的安全。

Policy其实有非常多种,比如上述中的超级管理员的Policy,是属于业务级别,而镜像拉取Policy则属于部署及运维层面。对于业务级别的Policy,当然我们只能用代码来实现,比如RBAC权限模型或领域中的约束与限制等。

什么是Policy Engine

理解了Policy之后,那下一个我们需要关心的问题就是:怎么来定义及存储Policy,又如何来验证Policy。而实现了定义存储Policy,又支持验证Policy的,我们就称之为Policy Engine。

以大家所熟知的RBAC模型及实现为例,我们会通过代码级,支持在UI上定义角色及资源等,将这些定义存储在类似MySQL的数据库中,再在代码中进行验证,不符合权限的抛出异常。这是一个Policy Engine。

理解了Policy Engine之后,那就可以开始正式讲到今天的主角了,OPA

什么是Open Policy Agent (OPA)

OPA就是一个Policy Engine实现,而且是一个独立的,不耦合特定平台与服务的Policy Engine,可应用于系统Linux或K8S,甚至是SQL等非常多的场景,支持Policy的定义与管理,验证与约束等。

OPA的优势是:

  1. 1. 架构上的独立与耦合,不与特定的技术或场景耦合,适合K8S及其它场景下的Policy的实现与管理
  2. 2. 在K8S这种分布式部署中,可以统一的管理整个部署中的Policy,简单方便
  3. 3. 可拔插的定义与管理,灵活性强,可随时修改规则

比如,使用OPA,你可以轻松的做到:

  • • 所有部署的镜像必须来源于公司内网指定镜像,禁止从外网拉取镜像进行部署
  • • 所有Pod必须指定资源限制(包括CPU,内存等),不指定资源限制的不允许部署

所以,在一些对安全比较在意的企业或部署管理中,OPA还是非常有价值的。

OPA的简介

OPA架构

OPA是一个独立的服务,可嵌入许多平台或框架中,做到Policy的Query以及Decision,总体来说,OPA主要是由Input,Policy以及Query等几个部分来组成。

Input

Input可理解为OPA的原始数据源,你可以理解为对现状的描述。它的格式是JSON。根据OPA应用的实际不同,Input产生的方式也并不一样。

举例说明,你部署了一个webdb服务,web服务支持http,https,而db则是tcp

我们可以用如下的Input来表达这个描述

代码语言:javascript复制
{
  "servers": [
    {
      "id": "db",
      "protocols": ["tcp"]
    },
    {
      "id": "web",
      "protocols": ["http","https"]
    }
  ]
}

这就是一个Input,我们用JSON定义了一个Input源,Input是描述。

Policy

Policy是策略,在OPA中,使用的是一个声明式语言Rego,通过Rego来定义Policy

我们定义如下的Policy:

  • • 任意一个服务,如果开放了http协议,则认为不安全,禁止

使用Rego来编写这个Policy

代码语言:javascript复制
package example
import future.keywords.every

# 如果violation的结果是0,则allow为true
allow := true {
    count(violation) == 0 
}
# 这个Policy表达了:如果任何protocols包括了http,则是violation的
violation[server.id] {
    some server in input.servers
    "http" in server.protocols
}

这就是一个Policy文件定义,它使用的是Rego语言来定义,意味着如果你想写好OPA,学习Rego是必不可少的

使用OPA来执行与运行这个Policy与Input

代码语言:javascript复制
./opa eval -i input.json -d example.rego

得到的结果是

代码语言:javascript复制
{
    "violation": [
        "web"
    ]
}

这是OPA运行后得出的结果,然后可以根据这个结果来进行决策,是允许还是禁止。

总结

所以,现在你理解OPA是一个什么样的Policy Engine了吧,它非常灵活,与特定的技术或平台并不耦合。定义Policy使用的是声明式的Rego

OPA与K8S

OPA并非只能用到K8S中,它的适用面非常广,比如你可以在Linux上配置并使用OPA,对SSH进行Policy控制;甚至可以对SQL运行配置OPA使用,限制不同的人能访问不同的表等,它非常灵活。

当然,做为CNCF中的一个项目,它肯定是支持K8S的。

OPA集成到K8S中主要有两种方式:

  • • OPA kube-mgmt的模式
  • • Gatekeeper

这两种方式都是OPA官方提供的方式,只不过前面一种比较原始,而Gatekeeper则是基于OPA之上,提供了更多的一些附加能力而已。

但是,不管是哪种方式,都是基于K8S提供的Admission Controllers(控制准入)基础能力之上实现的。

Admission Controllers

K8S所有的部署命令,无论是通过API方式,或是通过API封装提供的kubectl,在执行任何一个部署命令时,都会触发 Admission Controllers,也就是控制准入的流程。

K8S本身包括很多控制准入的内置的一些能力,但这里要讲的主要是MutatingAdmissionWebhookValidatingAdmissionWebhook

  • • MutatingAdmissionWebhook:这个Webhook会对命令的数据进行修改,添加其它信息等
  • • ValidatingAdmissionWebhook: 这个Webhook会对命令进行验证,如果不符合一些条件(比如超出限额配置),执行会被禁止。

而OPA集成到K8S,靠的就是ValidatingAdmissionWebhook。集成到K8S时,扩展了ValidatingAdmissionWebhook的能力,然后每次执行命令,会调用OPA进行验证。

至于OPA究竟如何集成到K8S中,这个就是后续需要深入进一步学习需要做的事了。

结论

OPA的应用可能并不普通,大多数情况下,可能并不会在自己的架构上再加一层OPA,这增加了复杂度,而且需要学习一个Rego的声明式语法,也需要付出成本。

但对于部署有较高的要求,比如有许多人能执行部署,在安全性的要求下,考虑使用OPA是一个不错的方案。它可以在技术层面避免一些错误及不允许的操作。

但凡能依赖技术的,就不要依赖人手动来做,这是技术世界不变的法则。

比如你的企业希望限制部署的镜像来源,与其通过文件规定或不停的向开发运维人员传达规定或事后检查等,还不如定义一个OPA来的更直接,简单及持续有效,并且没有人能违反规定。

是不是挺有价值的?

0 人点赞