文章首发于:
火线Zone社区(https://zone.huoxian.cn/)
Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。
学习k8s安全可以从搭建、理解组件关系、工作流程、安全机制开始,本文记录从0基础搭建k8s环境和k8s安全基础的笔记。
K8s安装有三种方式:
// Minikube
一个k8s集群模拟器,只有一个节点的集群,master和worker都在一起。
// 云平台K8s
可视化搭建,几步就可以创一个集群,优点是安装简单,生态齐全。
// 裸机安装
至少需要两台机器,主节点和工作节点各一台,需要自己安装Kubernetes组件,配置稍麻烦,缺少生态支持,比如负载均衡器和云存储。
minikube安装
0.minikube 介绍
https://minikube.sigs.k8s.io/
minikube 是启动一个最小的 local 的 Kubernetes 的一个环境。
minikube为什么说是最小是因为启动后会创建一个minikube vm,然后在minikube vm中创建一个单节点的k8s集群,就是说创建了一个只有一个节点的集群,也可以在启动minikube的指定
--vm-driver=none参数,使minikube直接在当前系统里安装单节点的k8s集群而不再创建minikube vm。
minikube可以在本机也可以在虚拟机中安装,Win/Linux都可,如果是虚拟机安装的话VT-x/AMD-v 虚拟化必须在 BIOS 中开启。并且如果在Windows下安装,如果开启了Hyper-V,不支持VirtualBox方式。
安装minikube过程为三步,分别是:安装docker、安装kubectl、安装minikube。
-
docker是容器引擎
-
kubectl是一个kubernetes的命令管理工具,一个kubernetes的一个命令行客户端。类似于mysql命令和mysqld数据库服务器的管理,mysql是mysqld的一个命令管理工具,mysqld是数据库引擎。
-
minikube是缩小版的kubernetes。
初始操作
这里拿一台干净的CentOS7.9来安装,进行一些初始命令:
systemctl stop firewalld && systemctl disable firewalld #关闭自带防火墙
yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save #安装iptables并清空规则
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config #关闭SELinux
swapoff -a && sed -i '/ swap / s/^(.*)$/#1/g' /etc/fsta #关闭SWap
1.安装 docker
yum update
yum -y install docker
#启动和设置开机自启
systemctl start docker
systemctl enable docker
#非root用户 建立docker组并添加自身用户
sudo groupadd docker
sudo usermod -aG docker ${USER}
sudo systemctl restart docker
su root //需要切换下用户,生效配置
su ${USER}
国内源:
cat <<EOF > /etc/docker/daemon.json { "registry-mirrors": ["http://hub-mirror.c.163.com"] } EOF
grep -E --color 'vmx|svm' /proc/cpuinfo #检查虚拟化
2.安装 kubectl
https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/
#下载最新kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
#sha256校验
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
#校验
echo "$(<kubectl.sha256) kubectl"="" |="" sha256sum="" --check<="" p="">
下载最新kubectl后再校验完整性,显示OK即可开始安装
安装kubectl后运行
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client
3.安装minikube
https://github.com/kubernetes/minikube/releases/tag/
#下载安装
curl -Lo minikube https://github.com/kubernetes/minikube/releases/download/v1.25.2/minikube-linux-amd64
chmod +x minikube && sudo mv minikube /usr/local/bin/
minikube start --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --vm-driver=none
#使用阿里的镜像。--vm-driver=none,添加这个参数之后,minikube就不会创建minikubevm了,而会直接在当前系统里安装单节点的k8s集群。
如果遇到如下报错
X Exiting due to GUEST_MISSING_CONNTRACK: Sorry, Kubernetes 1.23.3 requires conntrack to be installed in root's path
安装conntrack即可解决:
yum install -y conntrack
安装后查看
Minikube启动的时间较长,需要等待,如果有 timed out waiting for the condition错误可以minikube delete,minikube start 再重试。
到这minikube就安装好了,贴一下minikube启动的时的常用参数,在启动时的根据自己的需求加上即可:
--driver=*** 从1.5.0版本开始,Minikube缺省使用系统优选的驱动来创建Kubernetes本地环境,比如您已经安装过Docker环境,minikube 将使用 docker 驱动
--cpus=2: 为minikube虚拟机分配CPU核数
--memory=2048mb: 为minikube虚拟机分配内存数
--registry-mirror=*** 为了提升拉取Docker Hub镜像的稳定性,可以为 Docker daemon 配置镜像加速,参考阿里云镜像服务
--kubernetes-version=***: minikube 虚拟机将使用的 kubernetes 版本
更多帮助参数查看minikube help start命令或者查看官方docs。
minikube控制台
minikube dashboard
Minikube启动Dashboard后返回的地址只是容器代理出来的地址只能本机内网访问,默认只能localhost访问,如果需要开放外部访问需要使用kubectl添加一层代理
代理监听,默认8001端口
kubectl proxy --port=8002--address=0.0.0.0 --accept-hosts='^.*' &
设置好后即可非本地的ip访问dashboard 的UI 界面了:
minikube 使用
用户使用Minikube CLI管理虚拟机上的Kubernetes环境,比如:启动,停止,删除,获取状态等。一旦Minikube虚拟机启动,用户就可以使用熟悉的Kubectl CLI在Kubernetes集群上执行操作。
Minikube 也提供了丰富的 Addon 组件
通过 minikube 命令行,可以轻松开启 Addon 组件,所有组件镜像也会正确解析到阿里云的镜像仓库URL。
如图,k8s集群由主控节点(Master node,以下简称master)和工作节点(Worker Node,以下简称node)组成:
-
master节点负责资源调度,调度应用,维护状态和应用扩容等。
-
node节点上跑着应用服务,每个Node节点有一个kubelet,负责node与master之间的通信。
Master node组件
1.APIserver
集群统一入口,以restful方式,交给etcd存储。用户端一般通过kubectl命令行工具与kube-apiserver进行交互。
2.Controller-manager
处理集群中常规后台任务,通常一个资源对应一个控制器。
3.Scheduler
节点调度,选择node节点应用部署,负责决定将Pod放在哪个Node上。会对各个节点的负载、性能、数据考虑最优的node。
4.Etcd
存储系统,用于保存集群中相关的数据。
Worker node组件
1.Kubelet
Master派到node节点的agent,管理本机容器的各种操作。
2.Kube-proxy
提供网络代理,用来实现负载均衡等操作。
3.Pod
是k8s中的最小部署单元,一组容器的集合,一个pod中的容器是共享网络的。主要是基于docker技术来搭建的。
用户端命令下发通常流程如下:
-
kubectl向apiserver发送部署请求(例如使用 kubectl create -f deployment.yml)
-
apiserver将 Deployment 持久化到etcd;etcd与apiserver进行一次http通信。
-
controller manager通过watch api监听 apiserver ,deployment controller看到了一个新创建的deplayment对象更后,将其从队列中拉出,根据deployment的描述创建一个ReplicaSet并将 ReplicaSet 对象返回apiserver并持久化回etcd。
-
接着scheduler调度器看到未调度的pod对象,根据调度规则选择一个可调度的节点,加载到pod描述中nodeName字段,并将pod对象返回apiserver并写入etcd。
-
kubelet在看到有pod对象中nodeName字段属于本节点,将其从队列中拉出,通过容器运行时创建pod中描述的容器。
请求的发起的两个部分:
-
人机交互,使用kubectl 对 apiserver 的一个请求。
-
Pod 中的业务逻辑与apiserver 之间的交互。
Api Server收到请求后,会经过三个步骤的访问控制流程:
-
认证:判断请求用户是否为能够访问集群的合法用户。如果用户是个非法用户,那 apiserver 会返回一个 401 的状态码,并终止该请求;
-
授权:判断用户是否有权限进行请求中的操作。如果无权进行操作,apiserver 会返回 403 的状态码,并同样终止该请求;
-
准入控制:判断请求是否是一个安全合规的请求。如果最终验证通过的话,访问控制流程才会结束。
1.认证阶段
https://kubernetes.io/zh/docs/reference/access-authn-authz/authentication/
在主流的认证模块中会包括客户端证书、密码、plain tokens、bootstrap tokens以及JWT tokens(用于service account),客户端证书的使用是默认的并且是最常见的方案。
认证模块时管理员在集群创建过程中配置的,一个集群可能有多个认证模块配置,每个模块会依次尝试认证, 直到其中一个认证成功。
// K8s中的用户
k8s中的客户端访问有两类用户:
-
普通用户(Human User)(K8s不会对其管理):User独立在 K8S 之外,也就是说User是可以作用于全局的,跨 namespace,并且需要在全局唯一,一般是集群外访问,如 kubectl 使用的证书。k8s不会对普通user 进行管理,并且不会存储user的信息,不能通过调用k8s api来增删查这个 user。
-
Service Account (K8s会对其管理) :ServiceAccount是K8S的一种资源,是存在于某个namespace之中的,在不同namespace中可以同名,代表了不同的资源。k8s 会对serviceaccount 进行管理,Service account的作用就是给集群内运行的 pod 提供一种认证的方式。
总结就是,k8s 只做认证不做管理。
对应上面说的两种K8s用户,常用的两种认证方式分别是证书认证和Service Account Tokens认证。
// X509 client certs
X509 client certs 认证方式对用外部用户访问 apiserver 以及集群组件之间访问时使用,比如 kubectl 请求 apiserver 时。
kubernetes 的一些部署工具 kubeadm、minkube 等都是基于证书的认证方式。客户端证书认证叫作 TLS 双向认证,也就是服务器客户端互相验证证书的正确性,在都正确的情况下协调通信加密方案。
目前最常用的 X509 证书制作工具有 openssl、cfssl 等。
而所需认证的信息都放在kubeconfig 文件中:
// Service Account Tokens
serviceaccounts 是用在 pod 中访问 apiserver 时进行认证的,比如使用自定义 controller 时。
在 pod 内部访问 apiserver获取集群资源( pod、service、deployment)的情况下,kubernetes 提供了这种特殊的认证方式,serviceaccounts 是面向 namespace 的,每个 namespace 创建的时候,kubernetes 会自动在这个 namespace 下面创建一个默认的 serviceaccounts;并且这个 serviceaccounts 只能访问该 namespace 的资源。
每个 serviceaccounts 中都对应一个 secrets,namespace、token 和 ca 信息都是保存在 secrets 中且都通过 base64 编码的。一般是保存在/var/run/secrets/kubernetes.io/serviceaccount/目录下,所以渗透时候格外关注这个位置:
serviceaccounts 主要包含了三个内容:namespace、token 和 ca,每个 serviceaccounts 中都对应一个 secrets,namespace、token 和 ca 信息都是保存在 secrets 中且都通过 base64 编码的。
namespace 指定了 pod 所在的 namespace,ca 用于验证 apiserver 的证书,token 用作身份验证,它们都通过 mount 的方式保存在 pod 的文件系统中:
2.授权阶段
请求经过认证之后,就会执行用户授权流程,对于授权一个请求,Kubernetes主要关注三个方面:
-
请求者的用户名
从嵌入 token 的头部中提取 -
请求动作
GET、POST、PUT、DELETE -
动作影响的对象
有效的 Kubernetes 资源对象
K8s 目前支持如下四种授权机制:
-
Node
-
ABAC
-
RBAC
-
Webhook
// RBAC授权方式
重点关注最常用的授权方式RBAC(基于角色的访问控制),通过自定义角色并将角色和特定的 user,group,serviceaccounts 关联起来已达到权限控制的目的。
RBAC三个重要部分:
-
Role: 角色
-
Subject: 用户
-
RoleBinding: 绑定
简单来说就是Role角色代表权限的集合,例如K8s中的admin、cluster-admin都是角色。Subject:就是普通的外部用户,RoleBinding是将用户以及操作权限进行绑定。
比如你域渗透中的domain admin组,将一个普通域用户被拉进domain admin组就有了域管权限,而K8s中给用户赋予权限是通过RoleBinding,绑定关系,也就是把用户和角色绑定到一起,这样用户就有了这个角色所拥有的权限。
// 创建role和rolebinding
创建一个属于test名称空间的Role
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: test
name: pods-reader
rules:
- apiGroups: [""]
resources: ["pods","services","pods/log"]
verbs: ["get","watch","list"]
为test用户增加test名称空间的访问权限:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: podreader
namespace: test
subjects:
- kind: ServiceAccount
name: test
namespace: default
roleRef:
kind: Role
name: pods-reader
apiGroup: rbac.authorization.k8s.io
查看关系,kubectl describe rolebinding -n test:
3.准入控制阶段
最后一步是准入控制,准入控制有许多内置的模块来用于对请求的资源对象执行自定义操作。
简单来说可以把它看作是拦截(已认证)API 请求的拦截器,它可以更改请求对象,甚至完全拒绝请求。
准入控制也是获取请求的 body,操作 API resource。
准入控制是在 apiserver 中进行配置启用的:
准入控制有两个重要的阶段:
-
Mutating
可以对请求内容进行修改。 -
Validating
不允许修改请求内容,但可以根据请求的内容判断是继续执行该请求还是拒绝该请求。
准入控制器即可以被用作变更和验证,也可以两者结合起来使用,所以总结就是准入控制器是指在请求通过认证和授权之后,可用于对其进行变更操作或验证操作的一些代码或功能。
k8s内置已有一些Admission Controller ,可以自己进行启动和停止,比较重要的是MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook准入控制器,他们是为k8s提供了一种可以拓展的方式来使用自构建的服务,以webhook的形式调用。
准入控制这部分后面再可以分文章再细说与漏洞利用之间的关系。
【火线Zone云安全社区群】
进群可以与技术大佬互相交流
进群有机会免费领取节假日礼品
进群可以免费观看技术分享直播
识别二维码回复【社区群】进群
【火线Zone社区周激励】
2022.5.9~ 2022.5.15公告
【相关精选文章】
火线Zone是[火线安全平台]运营的云安全社区,内容涵盖云计算、云安全、漏洞分析、攻防等热门主题,研究讨论云安全相关技术,助力所有云上用户实现全面的安全防护。欢迎具备分享和探索精神的云上用户加入火线Zone社区,共建一个云安全优质社区!
如需转载火线Zone公众号内的文章请联系火线小助手:hxanquan(微信)
// 火线Zone //
微信号 : huoxian_zone
点击阅读原文,加入社区,共建一个有技术氛围的优质社区!
原文始发于微信公众号(火线Zone):从0基础搭建K8s环境及K8s安全基础笔记
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论