侧边栏壁纸
博主头像
cloudnative-blog博主等级

I can break through the limitations !

  • 累计撰写 23 篇文章
  • 累计创建 12 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

四.供应链安全

周锐豪
2024-02-03 / 0 评论 / 0 点赞 / 27 阅读 / 9209 字 / 正在检测是否收录...

一.供应链

1.简介

可信任软件供应链:指在建设基础架构过程中,涉及的软件都是可信任的
在K8s领域可信软件供应链主要是指镜像,因为一些软件交付物都是镜像,部署的最小载体

image-20231206140623968

2.Dockerfile优化

减少镜像层:一次RUN指令形成新的一层,尽量Shell命令都写在一行,减少镜像层。
• 清理无用文件:清理对应的残留数据,例如yum缓存。
• 清理无用的软件包:基础镜像默认会带一些debug工具,可以删除掉,仅保留应用程序所需软件,防止黑客利用。
• 选择最小的基础镜像:例如alpine
• 使用非root用户运行:USER指令指定普通用户

二.trivy

1.简介

Trivy:是一种用于容器镜像、文件系统、Git仓库的漏洞扫描工具。发现目标软件存在的漏洞。
Trivy易于使用,只需安装二进制文件即可进行扫描,方便集成CI系统。
项目地址: https://github.com/aquasecurity/trivy
下载地址: https://github.com/aquasecurity/trivy/releases

2.安装trivy

tar xf trivy_0.47.0_Linux-64bit.tar.gz

3.使用trivy

# 容器镜像扫描
./trivy image nginx
./trivy image -i nginx.tar
# 打印指定(高危、严重)漏洞信息
./trivy image -s HIGH nginx
./trivy image -s HIGH, CRITICAL nginx
# JSON格式输出并保存到文件
./trivy image nginx -f json -o /root/output.json

三.kubesec

1.简介

kubesec:是一个针对K8s资源清单文件进行安全配置评估的工具,根据安全配置
最佳实践来验证并给出建议。
官网:https://kubesec.io
项目地址:https://github.com/controlplaneio/kubesec

2.安装

tar xf kubesec_linux_amd64.tar.gz

3.使用

./kubesec scan nginx.yaml
或者使用容器环境执行检查
docker run -i kubesec/kubesec scan /dev/stdin < nginx.yaml

4.远程调用kubesec

kubesec内置一个HTTP服务器,可以直接启用,远程调用。
• 二进制
kubesec http 8080 &
• Docker容器
docker run -d -p 8080:8080 kubesec/kubesec http 8080

示例:
curl -sSX POST --data-binary @deployment.yaml http://192.168.31.71:8080/scan

五.准入控制器

1.简介

Admission Webhook:准入控制器Webhook是准入控制插件的一种,用于拦截所有向APISERVER发送的请求,并且可以修改请求或拒绝请求。
Admission webhook为开发者提供了非常灵活的插件模式,在kubernetes资源持久化之前,管理员通过程序可以对指定资源做校验、修改等操作。例如为资源自动打标签、pod设置默认SA,自动注入sidecar容器等。

相关Webhook准入控制器:
• MutatingAdmissionWebhook:修改资源,理论上可以监听并修改任何经过ApiServer处理的请求
• ValidatingAdmissionWebhook:验证资源
• ImagePolicyWebhook:镜像策略,主要验证镜像字段是否满足条件

2.imagepolicywehook

签发证书。镜像策略服务器是以https启用,需要给它自签证书,访问它时也要携带根证书或者客户端证书。
准备imgaepolicywebhook配置文件,指定镜像策略服务器配置文件存放目录。
准备镜像策略服务器配置文件,指定连接服务器IP地址、端口、API、根证书、客户端证书。
启用准入控制插件。

image-20231206152358526

3.配置

3.1定义镜像策略控制器配置文件

root@master01:mkdir -p /etc/kubernetes/image-policy/
root@master01:/etc/kubernetes/image-policy# cat admission_configuration.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
  configuration:
    imagePolicy:
      kubeConfigFile: /etc/kubernetes/image-policy/connect_webhook.yaml  # 指定镜像策略服务器配置文件。
      allowTTL: 50       # 控制批准请求的缓存时间,单位秒
      denyTTL: 50        # 控制批准请求的缓存时间,单位秒
      retryBackoff: 500    # 控制重试间隔,单位毫秒
      defaultAllow: true    # 确定webhook后端失效的行为

3.2定义镜像策略服务器连接配置文件

root@master01:/etc/kubernetes/image-policy# cat connect_webhook.yaml
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority: /etc/kubernetes/image-policy/webhook.pem # 数字证书,用于验证远程服务
    server: https://192.168.3.135:8080/image_policy # 镜像策略服务器地址,必须是https
  name: webhook
contexts:
- context:
    cluster: webhook
    user: apiserver
  name: webhook
current-context: webhook
preferences: {}
users:
- name: apiserver
  user:
    client-certificate: /etc/kubernetes/image-policy/apiserver-client.pem # webhook准入控制器使用的证书
    client-key: /etc/kubernetes/image-policy/apiserver-client-key.pem # 对应私钥证书

3.3签发证书

chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64

mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
##k8s根证书。
cat > ca-config.json <<EOF 
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

cat > ca-csr.json <<EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

##镜像策略服务器根证书。
cat > webhook-csr.json <<EOF
{
  "CN": "webhook",
  "hosts": [
   "192.168.3.135"
   ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
    }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes webhook-csr.json | cfssljson -bare webhook

##连接镜像策略服务器的客户端证书。
cat > apiserver-client-csr.json <<EOF  
{
  "CN": "apiserver",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
    }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-client-csr.json | cfssljson -bare apiserver-client

3.4开启ImagePolicyWebhook插件

root@master01:~# vim /etc/kubernetes/manifests/kube-apiserver.yaml
    - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
    - --admission-control-config-file=/etc/kubernetes/image-policy/admission_configuration.yaml

    volumeMounts:
    - mountPath: /etc/kubernetes/image-policy/
      name: image-policy-webhook

  volumes:
  - hostPath:
      path: /etc/kubernetes/image-policy/
      type: DirectoryOrCreate
    name: image-policy-webhook

3.5部署webhook服务

3.5.1 自己用python开发一个简单的webhook端点服务器,作用是拒绝部署的镜像乜有指定标签(即latest)

from flask import Flask,request
import json

app = Flask(__name__)

@app.route('/image_policy',methods=["POST"])
def image_policy():
    post_data = request.get_data().decode()
    #print("POST数据: %s" %post_data)
    data = json.loads(post_data)
    for c in data['spec']['containers']:
        if ":" not in c['image'] or ":latest" in c['image']:  # 如果镜像里不带冒号或者带:latest说明是镜像使用latest标签
            allowed, reason = False, "检查镜像失败!镜像标签不允许使用latest!"
            break
        else:
            allowed, reason = True, "检查镜像通过."
    print("检查结果: %s" %reason)
    result = {"apiVersion": "imagepolicy.k8s.io/v1alpha1","kind": "ImageReview",
              "status": {"allowed": allowed,"reason": reason}}

    return json.dumps(result,ensure_ascii=False)

if __name__ == "__main__":
    app.run(host="0.0.0.0",port=8080,ssl_context=('/data/www/webhook.pem','/data/www/webhook-key.pem'))

3.5.2构建镜像

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/
WORKDIR /data/www
USER python
CMD python main.py

docker build -t image-policy-webhook:test .

3.5.3拷贝webhook证书并启动容器

docker run -d -u root --name=image-policy-webhook \
-v /image-policy/webhook.pem:/data/www/webhook.pem \
-v /image-policy/webhook-key.pem:/data/www/webhook-key.pem \
-e PYTHONUNBUFFERED=1 -p 8080:8080 \
image-policy-webhook:test

3.6创建pod容器测试

root@master01:~# kubectl create deploy nginx1 --image=nginx:1.21
deployment.apps/nginx1 created
root@master01:~# kubectl create deploy nginx2 --image=nginx:latest
deployment.apps/nginx2 created
192.168.3.181 - - [07/Dec/2023 02:16:04] "POST /image_policy?timeout=30s HTTP/1.1" 200 -
检查结果: 检查镜像失败!镜像标签不允许使用latest!
192.168.3.181 - - [07/Dec/2023 02:16:18] "POST /image_policy?timeout=30s HTTP/1.1" 200 -
0

评论区