OpenShift Security (19) - 用红帽官方镜像加固云原生应用安全

发布于:2023-01-04 ⋅ 阅读:(405) ⋅ 点赞:(0)

OpenShift 4.x HOL教程汇总
本文在 OpenShift 4.11+ACS 3.71.0 环境中进行验证。

在进行以下操作前请安装 RHACS 环境。

基于镜像部署应用

  1. 执行命令下载文件,确认 nginx/Dockerfile 是基于 docker.io/nginx:1.20 镜像构建的。然后根据 Dockerfile 创建定制 nginx 镜像。
$ git clone https://github.com/liuxiaoyu-git/sample-blog-for-rhacs-tutorial.git && cd sample-blog-for-rhacs-tutorial
$ more ./default/docker/nginx/Dockerfile
FROM docker.io/nginx:1.20
 
COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf
 
USER 1001
EXPOSE 8080
 
CMD nginx -g "daemon off;" 
 
$ oc new-project sample-blog
$ oc new-build --name=nginx --strategy=docker --binary
$ oc start-build nginx --from-dir=./default/docker/nginx/ --follow
  1. 确认 django/Dockerfile 是基于 docker.io/python:3.9 镜像构建的。然后根据 Dockerfile 创建定制 django 镜像。
$ more ./default/docker/django/Dockerfile
FROM docker.io/python:3.9
 
ADD ./app .
RUN pip install -r requirements.txt
 
ENTRYPOINT /bin/bash docker-entrypoint.sh
 
$ oc new-build --name=django --strategy=docker --binary
$ oc start-build django --from-dir=./default/docker/django/ --follow
  1. 查看生成的 ImageStream 和 Image,其中 Image 是保存在 OpenShift 内部 ImageRegistry 中的镜像,此时还没有部署运行在 OpenShift 中。
$ oc get is
NAME     IMAGE REPOSITORY                                                      TAGS     UPDATED
django   image-registry.openshift-image-registry.svc:5000/sample-blog/django   latest   2 minutes ago
nginx    image-registry.openshift-image-registry.svc:5000/sample-blog/nginx    latest   20 minutes ago
$ oc get image | grep sample-blog
sha256:11253e2ba01c6fc2a6857e19119df0aed272b3825d5ef6e7e4679ed166cf508b   image-registry.openshift-image-registry.svc:5000/sample-blog/nginx@sha256:11253e2ba01c6fc2a6857e19119df0aed272b3825d5ef6e7e4679ed166cf508b
sha256:29a4d64a8e64b1c136ee834743ff0ada9a0ff80c12eca1d1ed6a5d8cdc2c9271   image-registry.openshift-image-registry.svc:5000/sample-blog/django@sha256:29a4d64a8e64b1c136ee834743ff0ada9a0ff80c12eca1d1ed6a5d8cdc2c9271
  1. 确认此时 RHACS 中的 IMAGES 中查不到和 sample-blog 相关的 Image,这说明在 OpenShift 内部 ImageRegistry 中的镜像是不会被 RHACS 扫描的,直到它被部署运行起来。
    在这里插入图片描述
  2. 运行以下命令,分别使用 docker.io/mysql:8.0.26、docker.io/redis:6.0.8、image-registry.openshift-image-registry.svc:5000/sample-blog/django:latest 和 image-registry.openshift-image-registry.svc:5000/sample-blog/nginx:latest 镜像部署应用资源。
$ more ./default/k8s/base/mysql-statefulset.yaml
$ more ./default/k8s/base/redis-statefulset.yaml
$ more ./default/k8s/base/nginx-deployment.yaml
$ more ./default/k8s/base/django-deployment.yaml
  1. 执行命令创建 service、route 等资源。
$ BASE_DOMAIN=$(oc get ingresses.config/cluster -o jsonpath={.spec.domain})
$ envsubst < ./default/k8s/base/nginx-route-template.yaml > ./default/k8s/base/nginx-route.yaml
$ oc apply -k ./default/k8s/base/
  1. 在完成后可在 “拓扑” 中确认部署到的应用资源。
    在这里插入图片描述

使用 RHACS 分析安全风险

  1. 在 RHACS 的 Dashborad 中可以看到以下两部分:风险最高的 Image 和 Deployment。
    在这里插入图片描述
  2. 点击进入 Images at the most risk 的 View all,可以看到在下面 IMAGES 页面中前 4 个是上面用到的 Image。镜像包含了数量不等的 CVE 和 Fixable CVE。
    在这里插入图片描述
  3. 进入 RHACS 的 Violations 菜单,按照 Severity 排序,可以看到前 4 个 High 级别的违规都和刚刚部署的应用资源相关。
    在这里插入图片描述
  4. 依次查看上图中 4 个违规涉及到的 Policy,主要有以下 2 类:1)镜像包含 CVE 漏洞,2)部署包含 PASSWORD 敏感信息。
    在这里插入图片描述
    在这里插入图片描述
  5. 在 Violation 说明的 Deployment 栏中可查看涉及到的相关镜像。例如以下 docker.io/mysql:8.0.26 镜像包含 4 个 Fixable 的 Critical 级别 CVE。
    在这里插入图片描述
  6. 另外,在违规中还有违反 No resource requests or limits specified、Pod Service Account Token Automatically Mounted 等 Policy 的项目。

修复安全风险

  1. 查看以下 4 个文件,确认上面用到的 docker.io 镜像都换成了 Red Hat 的镜像。
$ more ./improved/k8s/base/mysql-statefulset.yaml
$ more ./improved/k8s/base/redis-statefulset.yaml
$ more ./improved/docker/nginx/Dockerfile
$ more ./improved/docker/django/Dockerfile
  1. 重新根据 Dockerfile 构建镜像。
oc new-build --name=nginx-2 --strategy=docker --binary --to=nginx:v0.1
oc start-build nginx-2 --from-dir=./improved/docker/nginx --follow
oc new-build --name=django-2 --strategy=docker --binary --to=django:v0.1
oc start-build django-2 --from-dir=./improved/docker/django --follow
  1. 查看构建的 Image 和生成的 ImageStream,已经有新的镜像了。
$ oc get is
NAME     IMAGE REPOSITORY                                                      TAGS          UPDATED
django   image-registry.openshift-image-registry.svc:5000/sample-blog/django   v0.1,latest   51 seconds ago
nginx    image-registry.openshift-image-registry.svc:5000/sample-blog/nginx    v0.1,latest   About a minute ago
[lab-user@bastion sample-blog-for-rhacs-tutorial]$ oc get image | grep sample-blog
sha256:11253e2ba01c6fc2a6857e19119df0aed272b3825d5ef6e7e4679ed166cf508b   image-registry.openshift-image-registry.svc:5000/sample-blog/nginx@sha256:11253e2ba01c6fc2a6857e19119df0aed272b3825d5ef6e7e4679ed166cf508b
sha256:9ad852a977eb8ec4ccb3b2ae1501ad9c45320194476e49c9a4f401ee7f9397c5   image-registry.openshift-image-registry.svc:5000/sample-blog/nginx@sha256:9ad852a977eb8ec4ccb3b2ae1501ad9c45320194476e49c9a4f401ee7f9397c5
sha256:29a4d64a8e64b1c136ee834743ff0ada9a0ff80c12eca1d1ed6a5d8cdc2c9271   image-registry.openshift-image-registry.svc:5000/sample-blog/django@sha256:29a4d64a8e64b1c136ee834743ff0ada9a0ff80c12eca1d1ed6a5d8cdc2c9271
sha256:332f648bc477789f86ac611d5d54d09daa394902f8b54659717b695b223452be   image-registry.openshift-image-registry.svc:5000/sample-blog/django@sha256:332f648bc477789f86ac611d5d54d09daa394902f8b54659717b695b223452be
  1. 执行命令,根据新的配置更新应用资源。其中部署中用到的 “用户名” 和 “密码” 都是使用 comfigmap + secret 方式间接提供的。
$ oc apply -f ./improved/k8s/base/sample-blog-sa.yaml
 
$ oc apply -f ./improved/k8s/base/mysql-configmap.yaml
$ oc apply -f ./improved/k8s/base/mysql-secret.yaml
$ oc apply -f ./improved/k8s/base/mysql-statefulset.yaml
 
$ oc apply -f ./improved/k8s/base/redis-configmap.yaml
$ oc apply -f ./improved/k8s/base/redis-statefulset.yaml
 
$ oc apply -f ./improved/k8s/base/django-configmap.yaml
$ oc apply -f ./improved/k8s/base/django-secret.yaml
$ oc apply -f ./improved/k8s/base/django-deployment.yaml
 
$ oc apply -f ./improved/k8s/base/nginx-deployment.yaml

安全风险修复结果

  1. 在 IMAGES 中确认更新的 4 个镜像每个都只有 3 个 Fixable 的 CVE。
    在这里插入图片描述
  2. 点击上图中 registry.redhat.io/rhel8/mysql-80:latest 镜像后的 3 Fixable 链接,可以在右滑出的页面看到 3 个 Fixable CVE 的说明。通过查看上图中 4 个镜像的 Fixable CVE,确认他们都是相同的。
    在这里插入图片描述
  3. 进入 docker.io/mysql:8.0.26 镜像,确认此时已经没有 Critical 级别的 CVE 了,而 Fixable 的 CVE 只有 3 个了。
    在这里插入图片描述
  4. 在 Violations 中可以看到 4 个 High 级别违规 Policy 分别是 Fixable Severity at least Important 和 Kubernetes Actions: Exec into Pod。而前面出现的 Environment Variable Contains Secret 类型的 Violation 以及 Medium 级别的 Violation 都已近被修复。
    在这里插入图片描述
  5. 进入 Kubernetes Actions: Exec into Pod 的违规 Policy,可以看到是在 Pod 中运行 “sh” 命令。
    在这里插入图片描述
  6. 如果确认上述违规确认没有风险,可以将项目标记为 resolved 或同时将进程名加到基线中。
    在这里插入图片描述

参考

https://qiita.com/shin7446/items/e0aeb58625b4586274f7