Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

Pod安全上下文

安全上下文(Security Context):K8s对Pod和容器提供的安全机制,可以设置Pod特权和访问控制。

安全上下文限制维度:
• 自主访问控制(Discretionary Access Control):基于用户ID(UID)和组ID(GID),来判定对对象(例文件)的访问权限。
• 安全性增强的 Linux(SELinux): 为对象赋予安全性标签。
• 以特权模式或者非特权模式运行。
• Linux Capabilities: 为进程赋予 root 用户的部分特权而非全部特权。
• AppArmor:定义Pod使用AppArmor限制容器对资源访问限制
• Seccomp:定义Pod使用Seccomp限制容器进程的系统调用
• AllowPrivilegeEscalation: 禁止容器中进程(通过 SetUID 或 SetGID 文件模式)获得特权提升。当容器以权模式运行或者具有CAP_SYS_ADMIN能力时,AllowPrivilegeEscalation总为True。
• readOnlyRootFilesystem:以只读方式加载容器的根文件系统。

案例1:设置容器以普通用户运行

背景:容器中的应用程序默认以root账号运行的,这个root与宿主机root账号是相同的,拥有大部分对Linux内核的系统调用权限,这样是不安全的,所以我们应该将容器以普通用户运行,减少应用程序对权限的使用。

可以通过两种方法设置普通用户:

• Dockerfile里使用USER指定运行用户
• K8s里指定spec.securityContext.runAsUser,指定容器默认用户UID

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

Dockerfile方式:

flask-demo目录下:

Dockerfile

FROM python
RUN useradd python
RUN mkdir /data/www -p
COPY . /data/www
RUN chown -R python /data
RUN pip install flask -i https://mirrors.aliyun.com/pypi/simple/ && \
    pip install prometheus_client -i https://mirrors.aliyun.com/pypi/simple/
WORKDIR /data/www
USER python
CMD python main.py

main.py

from flask import Flask,render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template("index.html")

if __name__ == "__main__":
    app.run(host="0.0.0.0",port=8080)

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>

<h1>Hello Python!</h1>

</body>
</html>

docker build -t flask-demo:v1 .

docker run -d --name=demo-v1 -p 8080:8080 flask-demo:v1

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

docker exec -it demo-v1 bash

id查看当前执行的账号

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

K8s里指定spec.securityContext.runAsUser方式

操作在node01上执行:

demo2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: demo2
  name: demo2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo2
  template:
    metadata:
      labels:
        app: demo2
    spec:
      nodeName: node01
      securityContext:
        runAsUser: 1000
      containers:
      - image: registry.cn-beijing.aliyuncs.com/howell-practice/kubernetes:v1
        name: flask-demo
        imagePullPolicy: IfNotPresent
        securityContext:
          allowPrivilegeEscalation: false
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

案例2:避免使用特权容器

背景:容器中有些应用程序可能需要访问宿主机设备、修改内核等需求,在默认情况下,容器没这个有这个能力,因此这时会考虑给容器设置特权模式。

containers:
  - image: registry.cn-beijing.aliyuncs.com/howell-practice/kubernetes:v1
    name: web
    securityContext:
      privileged: true

启用特权模式就意味着,你要为容器提供了访问Linux内核的所有能力,这是很危险的,为了减少系统调用的供给,可以使用Capabilities为容器赋予仅所需的能力。

实验:

pod-privileged.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-privileged
spec:
  containers:
  - image: busybox
    name: test
    command:
    - sleep
    - 24h
    #securityContext:
      #privileged: true

kubectl exec -it pod-privileged -- sh

测试挂载能力
mount -t tmpfs / /tmp

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

解除注释,新创建一个pod

pod02-privileged.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod02-privileged
spec:
  containers:
  - image: busybox
    name: test
    command:
    - sleep
    - 24h
    securityContext:
      privileged: true

进入容器,测试挂载能力

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

Linux Capabilities

Linux Capabilities:Capabilities 是一个内核级别的权限,它允许对内核调用权限进行更细粒度的控制,而不是简单地以 root 身份能力授权。Capabilities 包括更改文件权限、控制网络子系统和执行系统管理等功能。在securityContext 中,可以添加或删除 Capabilities,做到容器精细化权限控制。

查看node01当前的能力

capsh --print

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

查看容器中的能力
docker run -d centos sleep 24h

capsh --print
进入容器,执行capsh --print

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

示例1:容器默认没有挂载文件系统能力,添加SYS_ADMIN增加这个能力

cap-pod01.yaml

apiVersion: v1
kind: Pod
metadata:
  name: cap-pod01
spec:
  containers:
  - image: busybox
    name: test
    command:
    - sleep
    - 24h
    securityContext:
      capabilities:
        add: ["SYS_ADMIN"]
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

kubectl exec -it cap-pod01 -- sh
mount -t tmpfs / /tmp

案例2:只读挂载容器文件系统,防止恶意二进制文件创建

cap-pod02.yaml

apiVersion: v1
kind: Pod
metadata:
  name: cap-pod02
spec:
  containers:
  - image: busybox
    name: test
    command:
    - sleep
    - 24h
    securityContext:
      readOnlyRootFilesystem: true
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

OPA Gatekeeper

OPA(Open Policy Agent):是一个开源的、通用策略引擎,可以将策略编写为代码。提供一个种高级声明性语言-Rego来编写策略,并把决策这一步骤从复杂的业务逻辑中解耦出来。
OPA可以用来做什么?
• 拒绝不符合条件的YAML部署
• 允许使用哪些仓库中的镜像
• 允许在哪个时间段访问系统

Gatekeeper 是基于OPA的一个Kubernetes 策略解决方案,可替代PSP或者部分RBAC功能。当在集群中部署了Gatekeeper组件,APIServer所有的创建、更新或者删除操作都会触发Gatekeeper来处理,如果不满足策略则拒绝。

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

部署Gatekeeper:

官网:
https://open-policy-agent.github.io/gatekeeper/website/docs/
安装文档:
https://open-policy-agent.github.io/gatekeeper/website/docs/install/

根据安装文档安装:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

如果安装不了可以在网页下载

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

Gatekeeper的策略由两个资源对象组成:
Template:策略逻辑实现的地方,使用rego语言
Contsraint:负责Kubernetes资源对象的过滤或者为Template提供输入参数

案例1:禁止容器启用特权

模板:

通过匹配容器特权是否为true,判断是否拒绝

privileged_tpl.yaml

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: privileged
spec:
  crd:
    spec:
      names:
        kind: privileged
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package admission
        violation[{"msg": msg}] { # 如果violation为true(表达式通过)说明违反约束
          containers = input.review.object.spec.template.spec.containers
          c_name := containers[0].name
          containers[0].securityContext.privileged # 如果返回true,说明违反约束
          msg := sprintf("提示:'%v'容器禁止启用特权!",[c_name])
        }

# 查看资源
kubectl get ConstraintTemplate

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

约束:

制定约束的资源类型,为templete提供输入参数

privileged_constraint.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: privileged
metadata:
  name: privileged
spec:
  match: # 匹配的资源
    kinds:
      - apiGroups: ["apps"]
        kinds:
        - "Deployment"
        - "DaemonSet"
        - "StatefulSet"

# 查看资源
kubectl get constraints

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

启用特权的测试容器

nginx_privileged.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-deploy
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-deploy
    spec:
      containers:
      - image: nginx
        name: nginx
        securityContext:
          privileged: true

kubectl apply -f nginx_privileged.yaml

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

案例2:只允许使用特定的镜像仓库

模板:

image_tpl.yaml

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: image-check
spec:
  crd:
    spec:
      names:
        kind: image-check
      validation:
        openAPIV3Schema:
          properties: # 需要满足条件的参数
            prefix:
              type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package image
        violation[{"msg": msg}] {
          containers = input.review.object.spec.template.spec.containers
          image := containers[0].image
          not startswith(image, input.parameters.prefix) # 镜像地址开头不匹配并取反则为true,说明违反约束
          msg := sprintf("提示:'%v'镜像地址不在可信任仓库!", [image])
        }

约束:

image_constraint.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: image-check
metadata:
  name: image-check
spec:
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds:
        - "Deployment"
        - "DaemonSet"
        - "StatefulSet"
  parameters: # 传递给opa的参数
    prefix: "registry.cn-beijing.aliyuncs.com/"

测试:

kubectl create deployment nginx-deployment --image=nginx

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

Secret存储敏感数据

Secret是一个用于存储敏感数据的资源,所有的数据要经过base64编码,数据实际会存储在K8s中Etcd,然后通过创建Pod时引用该数据。

Pod使用secret数据有两种方式:
变量注入
数据卷挂载

kubectl create secret 支持三种数据类型:
• docker-registry:存储镜像仓库认证信息
• generic:从文件、目录或者字符串创建,例如存储用户名密码
• tls:存储证书,例如HTTPS证书

示例:将Mysql用户密码保存到Secret中存储

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mysql
type: Opaque
data:
  mysql-root-password: "MTIzNDU2"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: db
        image: mysql:5.7.30
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql
              key: mysql-root-password

验证下:

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

使用123456作为密码登入

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

安全沙箱运行容器

gVisor介绍

所知,容器的应用程序可以直接访问Linux内核的系统调用,容器在安全隔离上还是比较弱,虽然内核在不断地增强自身的安全特性,但由于内核自身代码极端复杂,CVE 漏洞层出不穷。所以要想减少这方面安全风险,就是做好安全隔离,阻断容器内程序对物理机内核的依赖。Google开源的一种gVisor容器沙箱技术就是采用这种思路,gVisor隔离容器内应用和内核之间访问,提供了大部分Linux内核的系统调用,巧妙的将容器内进程的系统调用转化为对gVisor的访问。

gVisor兼容OCI,与Docker和K8s无缝集成,很方便使用。

项目地址:https://github.com/google/gvisor

容器中应用程序直接与Linux内核交互

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

容器中应用程序需要通过gVisor才能使用资源

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

gVisor 由 3 个组件构成:

• Runsc 是一种 Runtime 引擎,负责容器的创建与销毁。
• Sentry 负责容器内程序的系统调用处理。
• Gofer 负责文件系统的操作代理,IO 请求都会由它转接到 Host 上。

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

gVisor与Docker集成

gVisor内核要求:Linux 3.17+
如果用的是CentOS7则需要升级内核,Ubuntu不需要。

CentOS7内核升级步骤:

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install kernel-ml-devel kernel-ml –y
grub2-set-default 0
reboot
uname -r

1、准备gVisor二进制文件
gvisor.zip

unzip gvisor.zip

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

sha512sum -c runsc.sha512

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

rm -f *.sha512
chmod a+x runsc
mv runsc /usr/local/bin

2、Docker配置使用gVisor

runsc install # 查看加的配置/etc/docker/daemon.json

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

systemctl restart docker

docker info | grep Runtime

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

使用runsc运行容器:
docker run -d --runtime=runsc nginx
进入容器查看可知,已经被gvisor内核接管

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

容器默认是使用宿主机的内核

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

使用dmesg验证:
docker run --runtime=runsc -it nginx dmesg

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

gVisor与Containerd集成

切换Containerd容器引擎

1、准备配置

cat > /etc/sysctl.d/99-kubernetes-cri.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sysctl -system

2、安装

cd /etc/yum.repos.d
wget http://mirrors.aliyun.com/dockerce/linux/centos/docker-ce.repo
yum install -y containerd.io

3、修改配置文件

pause镜像地址
• Cgroup驱动改为systemd
• 增加runsc容器运行时
• 配置docker镜像加速器

mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

修改容器镜像:
vi /etc/containerd/config.toml

[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.2"

修改驱动为systemd

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true

增加runsc容器运行时

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
  runtime_type = "io.containerd.runsc.v1"
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

配置docker镜像加速器

[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
  endpoint = ["https://b9pmyelo.mirror.aliyuncs.com"]

systemctl restart containerd

4、配置kubelet使用containerd

vi /etc/sysconfig/kubelet

KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtimeendpoint=unix:///run/containerd/containerd.sock --cgroup-driver=systemd

systemctl restart kubelet

5、验证

kubectl get node -o wide
containerd也有 ctr 管理工具,但功能比较简单,一般使用crictl工具检查和调试容器。
项目地址:https://github.com/kubernetes-sigs/cri-tools/

准备crictl连接containerd配置文件:

cat > /etc/crictl.yaml << EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
EOF
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

下面是docker与crictl命令对照表:

Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

K8s使用gVisor运行容器

RuntimeClass 是一个用于选择容器运行时配置的特性,容器运行时配置用于运行 Pod 中的容器。

创建RuntimeClass

RuntimeClass.yaml

apiVersion: node.k8s.io/v1 # RuntimeClass 定义于 node.k8s.io API 组
kind: RuntimeClass
metadata:
  name: gvisor # 用来引用 RuntimeClass 的名字
handler: runsc # 对应的 CRI 配置的名称
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

创建Pod测试gVisor:

nginx-gvisor.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-gvisor
spec:
  nodeName: node01
  runtimeClassName: gvisor
  containers:
  - name: nginx
    image: nginx
Kubernetes安全篇4:最小化微服务漏洞(安全上下文、OPA Gatekeeper、Secret、安全沙箱)

发布者:LJH,转发请注明出处:https://www.ljh.cool/34009.html

(0)
上一篇 2023年4月2日 下午2:19
下一篇 2023年4月2日 下午4:36

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注