一、OPA概述

OPA (Open Policy Agent)背后的主要动机是在整个环境中实现统一的策略实施。通常,组织需要在运行其应用程序的环境中应用各种策略。可能需要这些策略来满足合规性要求、实现更高程度的安全性、实现跨多个环境的标准化等。这就需要一种自动化/声明式的方式来定义和执行这些策略。像 OPA 这样的策略引擎帮助我们实现了这样的目标。

OPA 是一个开源的通用策略引擎,可用于在各种类型的软件系统上执行策略,如微服务、CI/CD pipline、网关、Kubernetes等。 OPA 由 Styra 开发,目前是其中的一部分CNCF 的(https://www.openpolicyagent.org/)。

OPA 为我们提供了 REST API,我们的系统可以调用这些 API 来检查请求负载是否满足策略。它还为我们提供了一种高级声明性语言 Rego,它允许我们将要执行的策略指定为代码。这为我们在定义政策时提供了很大的灵活性。

上图显示了 OPA 的架构。它公开 API,任何需要做出授权或策略决策的服务都可以调用(策略查询),然后 OPA 可以根据策略的 Rego 代码做出决策,并将决策返回给相应地进一步处理请求的服务. 执行由实际服务本身完成,OPA 只负责做出决定。这就是 OPA 成为通用策略引擎并支持大量服务的方式。

二、在Docker中使用OPA

使用K8s集群外一台单独的安装了Docker的设备来执行OPA。

1.创建OPA空规则

首先我们需要创建一个存放OPA规则的目录(固定):

mkdir -p /etc/docker/policies

然后在目录下创建一个允许所有请求的空策略文件authz.rego,内容如下:

package docker.authzallow = true

2.在Docker中安装opa插件:

docker plugin install openpolicyagent/opa-docker-authz-v2:0.8 opa-args="-policy-file /opa/policies/authz.rego"

安装插件并制定策略的位置。容器内的/opa/policies/authz.rego就等于宿主机的/etc/docker/policies/authz.rego,因为opa插件做了卷挂载。接着我们配置 Docker 守护程序以使用插件进行授权:

cat > /etc/docker/daemon.json <<EOF
{"authorization-plugins": ["openpolicyagent/opa-docker-authz-v2:0.8"]
}
EOF

通知 Docker 守护进程重新加载配置文件:

kill -HUP $(pidof dockerd)

查看opa插件是否安装成功:可以看到,已经成功,并且已经启用。

[root@localhost ~]#  docker plugin list
ID             NAME                                      DESCRIPTION                                     ENABLED
8c9fc9b3e798   openpolicyagent/opa-docker-authz-v2:0.8   A policy-enabled authorization plugin for Do…   true

3.编写OPA规则
修改authz.rego文件,内容如下:

package docker.authzdefault allow = falseallow {not deny
}deny {seccomp_unconfined
}seccomp_unconfined {# This expression asserts that the string on the right-hand side is equal# to an element in the array SecurityOpt referenced on the left-hand side.input.Body.HostConfig.SecurityOpt[_] == "seccomp:unconfined"
}

其中default allow表示默认是拒绝所有;deny {xxx} 表示拒绝xxx规则所定义的操作;allow {not deny}则表示除了deny {xxx} 拒绝的,其他都允许。上面的authz.rego的含义就是,拒绝创建具有不受限制的seccomp配置文件容器的请求,由 input.Body.HostConfig.SecurityOpt[_] == "seccomp:unconfined"定义。其中input.Body是固定的,后面的是docker inspect 查看到的。

如何编写OPA规则请查看:https://www.openpolicyagent.org/docs/latest/docker-authorization/

4.验证规则是否生效
运行带有seccomp:unconfined SecurityOpt的容器,可以看到,无法正常创建。报错内容是无法通过OPA 如下规则的检测:input.Body.HostConfig.SecurityOpt[_] == “seccomp:unconfined”。

[root@localhost policies]# docker run -d --restart=always --name=web1 --security-opt seccomp:unconfined nginx
docker: Error response from daemon: plugin openpolicyagent/opa-docker-authz-v2:0.8 failed with error: AuthZPlugin.AuthZReq: 1 error occurred: 1 error occurred: /opa/policies/authz.rego:17: rego_parse_error: unexpected eof tokeninput.Body.HostConfig.SecurityOpt[_] == "seccomp:unconfined"^.
See 'docker run --help'.

三、在K8s集群中使用OPA

Gatekeeper 项目是 OPA 的 Kubernetes 特定实现。Gatekeeper 允许我们以 Kubernetes 原生方式使用 OPA 来执行所需的策略。

在 Kubernetes 集群上,Gatekeeper 作为ValidatingAdmissionWebhook安装。在请求通过 K8s API 服务器的身份验证和授权之后,但在它们持久化到数据库中之前,准入控制器可以拦截请求。如果任何准入控制器拒绝请求,则拒绝整个请求。准入控制器的局限性在于它们需要编译到 kube-apiserver 中,并且只有在 apiserver 启动时才能启用。

1.实验环境

底层系统为ubuntu18.04,然后在每个node上安装k8s,并构建集群。Master node的IP地址为192.168.26.71/24,两个Worker node的IP地址为192.168.26.72/24、192.168.26.73/24。

2.在集群环境中部署Gatekeeper
在master node上,使用如下命令部署Gatekeepe:

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.7/deploy/gatekeeper.yaml

可以看到,已经部署完成:

root@vms71:~/gatekeeper# kubectl get pods -n gatekeeper-system
NAME                                             READY   STATUS    RESTARTS   AGE
gatekeeper-audit-59d4b6fd4c-ckl7q                1/1     Running   0          5m
gatekeeper-controller-manager-66f474f785-6wt7p   1/1     Running   0          5m
gatekeeper-controller-manager-66f474f785-8pvgq   1/1     Running   0          5m
gatekeeper-controller-manager-66f474f785-k4b9l   1/1     Running   0          5m

3.创建OPA规则
在K8s中,当我们安装完Gatekeeper后,同样也需要编写OPA规则。创建OPA规则的yaml文件如下。

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:name: blacklistimages
spec:crd:spec:names:kind: BlacklistImagestargets:- rego: |package k8strustedimagesimages {image := input.review.object.spec.containers[_].imagenot startswith(image, "xx.163.com/")not startswith(image, "yy.163.com/")}violation[{"msg": msg}] {not imagesmsg := "not trusted image!"}target: admission.k8s.gatekeeper.sh

此模板yaml文件通过CRD自定义了一个资源类型BlacklistImages。我们在其中定义了OPA规则。首先在images中匹配了以xx.163.com或者yy.163.com开头的镜像。violation中则定义了如果我们匹配到了images中所定义的镜像,则无法部署,并且报错:“not trusted image!”。

使用此yaml文件创建后。我们可以利用创建的BlacklistImages资源类型创建一个具体的黑名单实例。将规则应用到具体的资源上,例如(pod、deploy)。所使用的yaml文件如下,我们准备将OPA规则应用到pod资源中:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: BlacklistImages
metadata:generation: 1managedFields:name: pod-trusted-imagesresourceVersion: "14449"
spec:match:kinds:- apiGroups:- ""kinds:- Pod

最后使用yaml文件创建实例:

root@vms71:~/gatekeeper# kubectl apply -f gatekeeper-blacklist.yaml
blacklistimages.constraints.gatekeeper.sh/pod-trusted-images created
root@vms71:~/gatekeeper# kubectl get BlacklistImages
NAME                 AGE
pod-trusted-images   30s

4.验证OPA规则是否生效
首先,分别在两个Worker Node上将要使用的nginx镜像(已经下载)重命名:

docker tag nginx:latest xx.163.com/library/nginx
docker tag nginx:latest yy.163.com/library/nginx
docker tag nginx:latest zz.163.com/library/nginx

查看是否成功:

root@vms72:~# docker images
REPOSITORY                                           TAG       IMAGE ID       CREATED         SIZE
xx.163.com/library/nginx                             latest    ea335eea17ab   4 weeks ago     141MB
yy.163.com/library/nginx                             latest    ea335eea17ab   4 weeks ago     141MB
zz.163.com/library/nginx                             latest    ea335eea17ab   4 weeks ago     141MB

然后我们在master node上分别通过这三个镜像创建pod,查看是否能够成功。

root@vms71:~/gatekeeper# kubectl run web1 --image=xx.163.com/library/nginx --image-pull-policy=IfNotPresent
Error from server ([pod-trusted-images] not trusted image!): admission webhook "validation.gatekeeper.sh" denied the request: [pod-trusted-images] not trusted image!
root@vms71:~/gatekeeper# kubectl run web1 --image=yy.163.com/library/nginx --image-pull-policy=IfNotPresent
Error from server ([pod-trusted-images] not trusted image!): admission webhook "validation.gatekeeper.sh" denied the request: [pod-trusted-images] not trusted image!

可以看到,当我们使用xx.163.com/library/nginx和yy.163.com/library/nginx 镜像创建pod时,都会出现OPA规则报错: [pod-trusted-images] not trusted image!。当我们使用zz.163.com/library/nginx时,则可以正常创建pod:

root@vms71:~/gatekeeper# kubectl run web1 --image=zz.163.com/library/nginx --image-pull-policy=IfNotPresent
pod/web1 created
root@vms71:~/gatekeeper# kubectl get pod web1
NAME   READY   STATUS    RESTARTS   AGE
web1   1/1     Running   0          10s

说明OPA规则已经生效。

整理资料来源:
《老段CKS课程》
Kubernetes OPA:https://www.velotio.com/engineering-blog/deploy-opa-on-kubernetes
Gatekeeper install:https://open-policy-agent.github.io/gatekeeper/website/docs/install/
Docker OPA:https://www.openpolicyagent.org/docs/latest/docker-authorization/

二十八、K8s最小服务漏洞2-OPA相关推荐

  1. 二十九、K8s最小服务漏洞3-gVisor沙箱

    一.为什么需要使用沙箱运行容器 首先,我们来看看整个K8s调用容器的架构: 1.架构概述 架构分为3个部分,分别时High-level container management.High-level ...

  2. ballerina 学习二十八 快速grpc 服务开发

    ballerina 的grpc 开发模型,对于开发者来说简单了好多,不是schema first 的方式,而是我们 只要编写简单的ballerina service 就可以了,proto 文件是自动帮 ...

  3. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21 我要评论 这篇文章主要介绍了Android项 ...

  4. SAP UI5 初学者教程之二十八 - SAP UI5 应用的集成测试工具 OPA 介绍试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 初学者教程之一:Hello World SAP UI5 初学者教程之二:SAP UI5 ...

  5. WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]

    WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过Ser ...

  6. 关闭数字健康 android 魅族,数字体验 篇二十八:精雕细刻,只为给魅友更好的选择,魅族16s Pro体验分享...

    数字体验 篇二十八:精雕细刻,只为给魅友更好的选择,魅族16s Pro体验分享 2019-09-06 17:31:22 14点赞 10收藏 15评论 当我还一直在称赞魅族16s所拥有的舒适手感表现时, ...

  7. 深度学习之图像分类(二十八)-- Sparse-MLP(MoE)网络详解

    深度学习之图像分类(二十八)Sparse-MLP(MoE)网络详解 目录 深度学习之图像分类(二十八)Sparse-MLP(MoE)网络详解 1. 前言 2. Mixture of Experts 2 ...

  8. kafka maven 依赖_SpringBoot入门建站全系列(二十八)整合Kafka做日志监控

    SpringBoot入门建站全系列(二十八)整合Kafka做日志监控 一.概述 Apache Kafka是一个分布式发布 - 订阅消息系统和一个强大的队列,可以处理大量的数据,并使您能够将消息从一个端 ...

  9. SpringBoot入门建站全系列(二十八)整合Kafka做日志监控

    SpringBoot入门建站全系列(二十八)整合Kafka做日志监控 一.概述 Apache Kafka是一个分布式发布 - 订阅消息系统和一个强大的队列,可以处理大量的数据,并使您能够将消息从一个端 ...

最新文章

  1. 英文VS2010安装中文版MSDN文档方法
  2. 途牛自营门市超500家 单笔订单交易额最高近300万元
  3. C++描述的位运算总结
  4. Reinforcement Learning
  5. 囊括计算机 电子信息仿真技术,什么是虚拟现实?
  6. Spring Boot – spring.config.name –案例研究
  7. 高德地图定位精度多少米_中美俄卫星定位精度分别是多少?美0.1米,俄10米,中国呢?...
  8. 数据结构-链表4-企业链表
  9. ASP.NET操作DataTable各种方法总结(给Datatable添加行列、DataTable选择排序等)
  10. 把uliweb项目变成可安装的python包
  11. AndroidStudio_开发工具的设置_界面设置_字体设置_使用习惯设置_按钮设置等一些设置的介绍---Android原生开发工作笔记71
  12. 上市公司回购股票是利好还是利空?
  13. 为什么程序员都不愿意升级 Java 8?
  14. MIT课程全面解读2019深度学习最前沿 | 附视频+PPT
  15. 为什么要学习 Spring Boot?
  16. 机器学习笔记(三):NumPy、Matplotlib、kNN算法 | 凌云时刻
  17. [Sturts2]继承ActionSupport类
  18. 用join实现交集,并集,差集,补集的效果
  19. 通过requests获取网络上图片的大小
  20. 2021 CCPC 哈尔滨 E. Power and Modulo (思维题)

热门文章

  1. 封杀太愚蠢,马斯克喊话解封特朗普推特账号!
  2. python换发型_神经网络P图神器:摘墨镜,戴美瞳,加首饰,换发型【TensorFlow实现】...
  3. http get请求参数放在url中和放在 header中有什么区别
  4. 全球及中国氢燃料电池汽车行业销售规模与运营前景展望报告2022版
  5. C++ 炼气期之算术运算符
  6. 拖放(DragDrop)
  7. 贾志刚_OpenCV视频课程资源
  8. 周志华机器学习:决策树
  9. 100道Java并发和多线程面试题
  10. APP制作:APP设计的过程与方法