供应链安全
供应链安全
目录
[toc]
本节实战
实战名称 |
---|
💘 实战:安装Trivy-2023.6.4(测试成功) |
💘 实战:安装kubesec-2023.6.4(测试成功) |
💘 实战:准入控制器: ImagePolicyWebhook-2023.6.6(测试成功) |
可信任软件供应链概述
**可信任软件供应链:**指在建设基础架构过程中,涉及的软件都是可信任的。
在K8s领域可信软件供应链主要是指镜像,因为一些软件交付物都是镜像,部署的最小载体。
构建镜像Dockerfile文件优化
- 减少镜像层:一次RUN指令形成新的一层,尽量Shell命令都写在一行,减少镜像层。
- **清理无用文件:**清理对应的残留数据,例如yum缓存。
- **清理无用的软件包:**基础镜像默认会带一些debug工具,可以删除掉,仅保留应用程序所需软件,防止黑客利用。
- 选择最小的基础镜像:例如alpine
- **使用非root用户运行:**USER指令指定普通用户
- 注意:
一次RUN指令形成新的一层,尽量Shell命令都写在一行,减少镜像层。
- 删除掉这个缓存目录就行
- alpine镜像大小:5MB
镜像漏洞扫描工具:Trivy
**Trivy:**是一种用于容器镜像、文件系统、Git仓库的漏洞扫描工具。发现目标软件存在的漏洞。
Trivy易于使用,只需安装二进制文件即可进行扫描,方便集成CI系统。
项目地址:https:centos7
- 实验软件
链接:https:提取码:08202023.6.4-trivy-code
- 安装步骤
1、下载软件[root@k8s-master1 ~]#ll -h trivy_0.18.3_Linux-64bit.tar.gz #自己去官网下载,这里直接用提供的安装包-rw-r--r--1rootroot11MJun407:39trivy_0.18.3_Linux-64bit.tar.gz2、移动二进制文件到/usr/bin目录[root@k8s-master1 ~]#mkdir trivy[root@k8s-master1 ~]#mv trivy_0.18.3_Linux-64bit.tar.gz trivy[root@k8s-master1 ~]#cd trivy/[root@k8s-master1 trivy]#tar xf trivy_0.18.3_Linux-64bit.tar.gz [root@k8s-master1 trivy]#lscontribLICENSEREADME.mdtrivytrivy_0.18.3_Linux-64bit.tar.gz[root@k8s-master1 trivy]#mv trivy /usr/bin/3、测试[root@k8s-master1 ~]#trivy --helpNAME:trivy-AsimpleandcomprehensivevulnerabilityscannerforcontainersUSAGE:trivy[global options]command[command options]targetVERSION:0.18.3COMMANDS:image,iscananimagefilesystem,fsscanlocalfilesystemrepository,reposcanremoterepositoryclient,cclientmodeserver,sservermodeplugin,pmanagepluginshelp,hShowsalistofcommandsorhelpforonecommandGLOBALOPTIONS:--quiet,-qsuppressprogressbarandlogoutput(default:false) [$TRIVY_QUIET]--debug,-ddebugmode(default:false) [$TRIVY_DEBUG]--cache-dirvaluecachedirectory(default:"/root/.cache/trivy") [$TRIVY_CACHE_DIR]--help,-hshowhelp(default:false)--version,-vprinttheversion(default:false)
安装结束。😘
示例:
# 容器镜像扫描trivyimagenginxtrivyimage-inginx.tar# 打印指定(高危、严重)漏洞信息trivyimage-sHIGHnginxtrivyimage-sHIGH,CRITICALnginx# JSON格式输出并保存到文件trivyimage-fjson-ooutput.jsonnginx
漏洞数据库:
检查YAML文件安全配置:kubesec
**kubesec:**是一个针对K8s资源清单文件进行安全配置评估的工具,根据安全配置最佳实践来验证并给出建议。
- 实验软件
链接:https:提取码:08202023.6.4-kubesec-code
- 安装步骤
1、下载软件root@k8s-master1~]#ll-hkubesec_linux_amd64.tar.gz-rw-r--r--1rootroot3.9MJun407:39kubesec_linux_amd64.tar.gz2、解压[root@k8s-master1 ~]#tar xf kubesec_linux_amd64.tar.gz [root@k8s-master1 ~]#mv kubesec /usr/bin/3、验证[root@k8s-master1 ~]#kubesec --helpValidateKubernetesresourcesecuritypoliciesUsage:kubesec[command]AvailableCommands:helpHelpaboutanycommandhttpStartskubesecHTTPserveronthespecifiedportscanScansKubernetesresourceYAMLorJSONversionPrintskubesecversionFlags:-h,--helphelpforkubesecUse"kubesec [command] --help"formoreinformationaboutacommand.
安装结束。😘
示例:
kubesecscandeployment.yaml或者使用容器环境执行检查dockerrun-ikubesec/kubesecscan/dev/stdin<deployment.yaml
kubesec内置一个HTTP服务器,可以直接启用,远程调用。
- 二进制
kubesechttp8080&
- Docker容器
dockerrun-d-p8080:8080kubesec/kubesechttp8080示例:curl-sSXPOST--data-binary@deployment.yamlhttp:[root@k8s-master1 ~]#kubesec scan deployment.yaml
[root@k8s-master1 ~]#docker run -d -p 8085:8080 kubesec/kubesec http 8080 #宿主机端口:容器端口[root@k8s-master1 ~]#curl -sSX POST --data-binary @deployment.yaml http:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.20.0docker:提取码:08202023.6.6-ImagePolicyWebhook-code
- 课件步骤
1、准备配置文件
(在k8s-master1
上操作)
- 创建
admission_configuration.yaml
文件
#创建/etc/kubernetes/image-policy目录及/etc/kubernetes/image-policy/admission_configuration.yaml文件[root@k8s-master1 ~]#mkdir /etc/kubernetes/image-policy/[root@k8s-master1 ~]#vim /etc/kubernetes/image-policy/admission_configuration.yamlapiVersion:apiserver.config.k8s.io/v1kind:AdmissionConfigurationplugins:- name:ImagePolicyWebhookconfiguration:imagePolicy:kubeConfigFile:/etc/kubernetes/image-policy/connect_webhook.yaml# 连接镜像策略服务器配置文件allowTTL:50# 控制批准请求的缓存时间,单位秒denyTTL:50# 控制拒绝请求的缓存时间,单位秒retryBackoff:500# 控制重试间隔,单位毫秒defaultAllow:true# 确定webhook后端失效的行为
- 创建
connect_webhook.yaml
文件
[root@k8s-master1 ~]#vim /etc/kubernetes/image-policy/connect_webhook.yamlapiVersion:v1kind:Configclusters:- cluster:certificate-authority:/etc/kubernetes/image-policy/webhook.pem# 数字证书,用于验证远程服务server:https:name:webhookcontexts:- context:cluster:webhookuser:apiservername:webhookcurrent-context:webhookpreferences:{}users:- name:apiserveruser:client-certificate:/etc/kubernetes/image-policy/apiserver-client.pem# webhook准入控制器使用的证书client-key:/etc/kubernetes/image-policy/apiserver-client-key.pem# 对应私钥证书
注:涉及的证书文件,下一步将生成,然后会拷贝到相应路径。
2、部署镜像服务器
(在k8s-node1
上操作。)
自己用python开发一个简单的webhook端点服务器,作用是拒绝部署的镜像乜有指定标签(即latest)。
(1) 自签HTTPS证书
来到k8s-node1
节点:
- 将压缩包
image-policy-webhook.zip
拷贝到k8s-node1
节点并解压:
[root@k8s-node1 ~]#lltotal4-rw-r--r--1rootroot2910Jun507:09image-policy-webhook.zip[root@k8s-node1 ~]#unzip image-policy-webhook.zip Archive:image-policy-webhook.zipcreating:image-policy-webhook/inflating:image-policy-webhook/Dockerfileinflating:image-policy-webhook/main.pyinflating:admission_configuration.yamlinflating:connect_webhook.yamlinflating:image-policy-certs.sh[root@k8s-node1 ~]#lsadmission_configuration.yamlconnect_webhook.yamlimage-policy-certs.shimage-policy-webhookimage-policy-webhook.zip
- 查看当前
image-policy-certs.sh
自签脚本文件:
[root@k8s-node1 ~]#cat image-policy-certs.sh [root@k8s-node1 ~]#cat image-policy-certs.sh cat>ca-config.json<<EOF{"signing":{"default":{"expiry":"87600h"},"profiles":{"kubernetes":{"expiry":"87600h","usages":["signing","key encipherment","server auth","client auth"]}}}}EOFcat>ca-csr.json<<EOF{"CN":"kubernetes","key":{"algo":"rsa","size":2048},"names":[{"C":"CN","L":"Beijing","ST":"Beijing"}]}EOFcfsslgencert-initcaca-csr.json|cfssljson-bareca-cat>webhook-csr.json<<EOF{"CN":"webhook","hosts":["172.29.9.32"],"key":{"algo":"rsa","size":2048},"names":[{"C":"CN","L":"BeiJing","ST":"BeiJing"}]}EOFcfsslgencert-ca=ca.pem-ca-key=ca-key.pem-config=ca-config.json-profile=kuberneteswebhook-csr.json|cfssljson-barewebhookcat>apiserver-client-csr.json<<EOF{"CN":"apiserver","hosts":[],"key":{"algo":"rsa","size":2048},"names":[{"C":"CN","L":"BeiJing","ST":"BeiJing"}]}EOFcfsslgencert-ca=ca.pem-ca-key=ca-key.pem-config=ca-config.json-profile=kubernetesapiserver-client-csr.json|cfssljson-bareapiserver-client
- 执行脚本:
[root@k8s-node1 ~]#sh image-policy-certs.sh [root@k8s-node1 ~]#lltotal5784-rw-r--r--1rootroot508Oct212021admission_configuration.yaml-rw-r--r--1rootroot956Jun507:15apiserver-client.csr-rw-r--r--1rootroot182Jun507:15apiserver-client-csr.json-rw-------1rootroot1679Jun507:15apiserver-client-key.pem-rw-r--r--1rootroot1306Jun507:15apiserver-client.pem-rw-r--r--1rootroot294Jun507:15ca-config.json-rw-r--r--1rootroot960Jun507:15ca.csr-rw-r--r--1rootroot212Jun507:15ca-csr.json-rw-------1rootroot1679Jun507:15ca-key.pem-rw-r--r--1rootroot1273Jun507:15ca.pem-rw-r--r--1rootroot5850685Jun507:15cfssl.tar.gz-rw-r--r--1rootroot632Oct212021connect_webhook.yaml-rw-r--r--1rootroot1365Jun507:13image-policy-certs.shdrwxr-xr-x2rootroot39Jul92021image-policy-webhook-rw-r--r--1rootroot2910Jun507:09image-policy-webhook.zip-rw-r--r--1rootroot1001Jun507:15webhook.csr-rw-r--r--1rootroot202Jun507:15webhook-csr.json-rw-------1rootroot1679Jun507:15webhook-key.pem-rw-r--r--1rootroot1330Jun507:15webhook.pem
- 拷贝证书文件到
k8s-master1
对应目录:
[root@k8s-node1 ~]#scp webhook.pem apiserver-client-key.pem apiserver-client.pem root@172.29.9.31:/etc/kubernetes/image-policy/Theauthenticityofhost'172.29.9.31 (172.29.9.31)'can't be established.ECDSA key fingerprint is SHA256:XfMhwZeoqC6kPHaF1uPzLdY9t2ZgNoNvyEd0kJd24eY.ECDSA key fingerprint is MD5:ec:5e:37:9d:fc:e7:af:e1:9e:3a:ac:21:81:92:b5:91.Are you sure you want to continue connecting (yes/no)?yesWarning:Permanently added '172.29.9.31'(ECDSA) to the list of known hosts.root@172.29.9.31'spassword:webhook.pem100%13301.3MB/s00:00apiserver-client-key.pem100%1679858.4KB/s00:00apiserver-client.pem100%1306330.6KB/s00:00[root@k8s-master1 ~]#cd /etc/kubernetes/image-policy/[root@k8s-master1 image-policy]#lltotal20-rw-r--r--1rootroot509Jun507:01admission_configuration.yaml-rw-------1rootroot1679Jun507:27apiserver-client-key.pem-rw-r--r--1rootroot1306Jun507:27apiserver-client.pem-rw-r--r--1rootroot633Jun507:04connect_webhook.yaml-rw-r--r--1rootroot1330Jun507:27webhook.pem
(2) Docker容器启动镜像策略服务
- 构建镜像:
[root@k8s-node1 ~]#pwd/root[root@k8s-node1 ~]#lsadmission_configuration.yamlapiserver-client-key.pemca.csrca.pemimage-policy-certs.shwebhook.csrwebhook.pemapiserver-client.csrapiserver-client.pemca-csr.jsoncfssl.tar.gzimage-policy-webhookwebhook-csr.jsonapiserver-client-csr.jsonca-config.jsonca-key.pemconnect_webhook.yamlimage-policy-webhook.zipwebhook-key.pem[root@k8s-node1 ~]#cd image-policy-webhook[root@k8s-node1 image-policy-webhook]#lsDockerfilemain.py[root@k8s-node1 image-policy-webhook]#cat Dockerfile FROMpythonRUNuseraddpythonRUNmkdir/data/www-pCOPY./data/wwwRUNchown-Rpython/dataRUNpipinstallflask-ihttps:WORKDIR/data/wwwUSERpythonCMDpythonmain.py[root@k8s-node1 image-policy-webhook]#docker build -t image-policy-webhook .[root@k8s-node1 image-policy-webhook]#docker images|grepimage-policy-webhookimage-policy-webhooklatest331d1c0b42d818secondsago936MB
- 启动容器:
dockerrun-d-uroot--name=image-policy-webhook\-v $PWD/webhook.pem:/data/www/webhook.pem\-v $PWD/webhook-key.pem:/data/www/webhook-key.pem\-e PYTHONUNBUFFERED=1-p8081:8080\image-policy-webhook#注意:这里的证书文件是放置在/root下的;#注意:课件里宿主机端口用的是8080,但自己宿主机8080端口被nodeCache占用了,因此这里使用8081.[root@k8s-node1 ~]#docker ps -lCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES7145eb5dfa6dimage-policy-webhook"/bin/sh -c 'python …"5secondsagoUp4seconds0.0.0.0:8081->8080/tcp,:::8081->8080/tcpimage-policy-webhook[root@k8s-node1 ~]#docker logs 7145eb5dfa6d*ServingFlaskapp'main'*Debugmode:offWARNING:Thisisadevelopmentserver.Donotuseitinaproductiondeployment.UseaproductionWSGIserverinstead.*Runningonalladdresses(0.0.0.0)*Runningonhttps:*Runningonhttps:PressCTRL+Ctoquit[root@k8s-node1 ~]#
3、启用准入控制插件
[root@k8s-master1 ~]#vim /etc/kubernetes/manifests/kube-apiserver.yaml- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook- --admission-control-config-file=/etc/kubernetes/image-policy/admission_configuration.yaml……- mountPath:/etc/kubernetes/image-policyname:image-policyreadOnly:true……- hostPath:path:/etc/kubernetes/image-policytype:DirectoryOrCreatename:image-policy
报错退出,此时可以看到静态pod kube-apiserver-k8s-master1
发生重启了。
4、测试
- 在
k8s-node1
上持续查看容器image-policy
的日志
[root@k8s-node1 ~]#docker logs -f image-policy-webhook
- 创建不带tag的deployment资源测试
[root@k8s-master1 image-policy]#kubectl create deployment web-no-tag --image=nginxdeployment.apps/web-no-tagcreated[root@k8s-master1 image-policy]#kubectl get deployment NAMEREADYUP-TO-DATEAVAILABLEAGEweb-no-tag0/10010s[root@k8s-master1 image-policy]#kubectl describe replicaset web-no-tag-78bd59988f
- 创建tag的deployment资源测试
[root@k8s-master1 image-policy]#kubectl create deployment web-with-tag --image=nginx:1.16deployment.apps/web-with-tagcreated[root@k8s-master1 image-policy]#kubectl get deploymentNAMEREADYUP-TO-DATEAVAILABLEAGEweb-no-tag0/1002m45sweb-with-tag1/1116s
带有tag的镜像会被成功创建,不带tag的镜像会被ImagePolicyWebhook
拒绝,符合预期。
测试结束。😘
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码 x2675263825 (舍得), qq:2675263825。
🍀 微信公众号 《云原生架构师实战》
🍀 语雀