Kubernetes安全框架

Kubernetes安全框架

  • K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都 支持插件方式,通过API Server配置来启用插件。

    1. Authentication(鉴权):身份鉴别,只有正确的账号才能够通过认证
    2. Authorization(授权):判断用户是否有权限对访问的资源执行特定的动作
    3. Admission Control(准入控制):用于补充授权机制以实现更加精细的访问控制功能。
  • 客户端要想访问K8s集群API Server,一般需要证书、Token或 者用户名+密码;如果Pod访问,需要ServiceAccount

Authentication(鉴权)

三种客户端身份认证:

  • HTTP Base认证:通过用户名+密码的方式认证

这种认证方式是把“用户名:密码"用BASE64算法进行编码后的字符串放在HTTP请求中的Header Authorization域里发送给服务端。服务端收到后进行解码,获取用户名及密码,然后进行用户身份认证的过程。

  • HTTP Token认证:通过一个Token来识别合法用户

这种认证方式是用一个很长的难以被模仿的字符串–Token来表明客户身份的一种方式。每个Token对应一个用户名,当客户端发起API调用请求时,需要在HTTP Header里放入Token, API Server 接到Token后会跟服务器中保存的token进行比对,然后进行用户身份认证的过程。

  • HTTPS证书认证:基于CA根证书签名的双向数字证书认证方式

    这种认证方式是安全性最高的一种方式,但是同时也是操作起来最麻烦的一种方式。

HTTPS认证大体分为3个过程:

  1. 证书申请和下发

    HTTPS通信双方的服务器向CA机构申请证书,CA机构下发根证书、服务端证书及私钥给申请者。

  2. 客户端和服务端的双向认证

    • 客户端向服务器端发起请求,服务端下发自己的证书给客户端,客户端接收到证书后,通过私钥解密证书,在证书中获得服务端的公钥,客户端利用服务器端的公钥认证证书中的信息,如果一致,则认可这个服务器。

    • 客户端发送自己的证书给服务器端,服务端接收到证书后,通过私钥解密证书, 在证书中获得客户端的公钥,并用该公钥认证证书信息,确认客户端是否合法。

  3. 服务器端和客户端进行通信

    服务器端和客户端协商好加密方案后,客户端会产生-一个随机的秘钥并加密,然后发送到服务器端服务器端接收这个秘钥后,双方接下来通信的所有内容都通过该随机秘钥加密。

Authorization(授权)

授权发生在认证成功之后,通过认证就可以知道请求用户是谁,然后Kubernetes会根据事先定义的授权策略来决定用户是否有权限访问,这个过程就称为授权。

RBAC(Role-Based Access Control) 基于角色的访问控制,主要是在描述一件事情:给哪些对象授予了哪些权限

RBAC根据API请求属性,决定允许还是拒绝。

比较常见的授权的几个概念:

  • 对象:User(用户名)、Groups(用户分组)、 ServiceAccount(服务账号)
  • 角色:代表着一组定义在资源上的可操作动作(权限)的集合
  • 绑定:将定义好的角色跟用户绑定在一起

角色

  • Role:授权特定命名空间的访问权限
  • ClusterRole:授权所有命名空间的访问权限

一个角色就是一组权限的集合,这里的权限都是许可形式的(白名单)。

# Role只能对命名空间内的资源进行授权,需要指定nameapce
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: authorization-role
  namespace: test 
rules:
- apiGroups: [""] 	# 支持的API组列表,"”空字符串,表示核心API群
  resources: ["pods"] 	# 支持的资源对象列表
  verbs: ["get", "watch", "list"] 	# 允许的对资源对象的操作方法列表
# 该 authorization-role 角色,对指定test命名空间,核心api组的pod资源具有get watch list 权限

# ClusterRole可以对集群范围内资源、跨namespaces的范围资源、非资源类型进行授权
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: authorization-clusterrole
rules:
- apiGroups: [""] 
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

rules中的参数说明:

  • apiGroups:支持的API组列表
"","apps","autoscaling", "batch", "networking"
  • resources:支持的资源对象列表
"services","endpoints","pods","secrets","configmaps","crontabs" ,"deployments","jobs",
"nodes" , "rolebindings","clusterroles", " daemonsets" ,"replicasets" ,"statefulsets",
"horizontalpodautoscalers" ,"replicationcontrollers" , "cronjobs"
  • verbs:对资源对象的操作方法列表
"get","list", "watch", "create", "update", "patch", "delete", "exec"

角色绑定

  • RoleBinding:将角色绑定到主体(即subject)
  • ClusterRoleBinding:将集群角色绑定到主体

角色绑定用来把一个角色绑定到一个目标对象上,绑定目标可以是User、Group或者ServiceAccount

# RoleBinding可以将同一namespace中的subject绑定到某个Role下,则此subject即具有该Role定义的权限
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: authorization-role-binding
  namespace: test
subjects:	# 目标对象信息
- kind: User    # 用户类型
  name: zhangsan    # 存在的用户名
  apiGroup: rbac.authorization.k8s.io
roleRef:	# 角色信息
  kind: Role   # Role类型
  name: authorization-role    # 存在的role
  apiGroup: rbac.authorization.k8s.io
# 将 authorization-role 角色绑定到 zhangsan 目标用户上(此时,zhangsan用户即用户authorization-role角色下所定义的权限)

# ClusterRoleBinding在整个集群级别和所有namespaces将特定的subject与ClusterRole绑定,授予权限
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: authorization-clusterrole-binding
subjects:	# 目标对象信息
- kind: User	# 用户类型
  name: zhangsan
  apiGroup: rbac.authorization.k8s.io
roleRef:	# 角色信息
  kind: ClusterRole
  name: authorization-clusterrole
  apiGroup: rbac.authorization.k8s.io

RoleBinding引用ClusterRole进行授权

RoleBinding可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。

一种很常用的做法就是,集群管理员为集群范围预定义好一组角色(ClusterRole),然后在多个命名空间中重复使用这些ClusterRole。这样可以大幅提高授权管理工作效率,也使得各个命名空间下的基础性授权规则与使用体验保持一致。

#虽然authorization-clusterrole是一个集群角色,但是因为使用了RoleBinding ,所以zhangsan只能读取test命名空间中的资源
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: authorization-role-binding-ns
  namespace: test
subjects:
- kind: User
  name: zhangsan
  apiGroup: rbac.authorization.k8s.io
roleRef :
  kind: ClusterRole
  name: authorization-clusterrole
  apiGroup: rbac.authorization.k8s.io

Admission Control(准入控制)

Adminssion Control实际上是一个准入控制器插件列表,发送到API Server 的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过, 则拒绝请求。

案例:为指定用户授权访问不同命名空间权限

Eg: 为xin用户授权default命令空间Pod读取权限
  1. 用K8S CA签发客户端证书
  2. 生成kubeconfig授权文件
  3. 创建RBAC权限策略

签发证书

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF

cat > xin-csr.json <<EOF
{
  "CN": "xin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF

cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes xin-csr.json | cfssljson -bare xin
bash cert.sh
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \	# 指定根证书的名称路径
  --embed-certs=true \	# 将根证书内容写入配置文件中
  --server=https://192.168.200.29:6443 \		# 指定连接k8s集群的IP地址
  --kubeconfig=xin.kubeconfig	# 生成的文件名

# 设置客户端认证
kubectl config set-credentials xin \
  --client-key=xin-key.pem \	 
  --client-certificate=xin.pem \
  --embed-certs=true \
  --kubeconfig=xin.kubeconfig

# 设置默认上下文
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=xin \
  --kubeconfig=xin.kubeconfig

# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=xin.kubeconfig
# 执行文件
bash kubeconfig.sh
# 将文件传到node节点
scp xin.kubeconfig node1:/root/
# 测试		发现xin证书没有授权
$ kubectl get pods --kubeconfig=/root/.kube/config 
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-79899cbcb-nl52v   1/1     Running   1          2d

$ kubectl get pods --kubeconfig=xin.kubeconfig 
Error from server (Forbidden): pods is forbidden: User "xin" cannot list resource "pods" in API group "" in the namespace "default"

$ cfssl-certinfo --cert xin.pem 	# 查看证书信息
# 授权操作
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]       #API组,空表示在核心组
  resources: ["pods"]   #资源
  verbs: ["get", "watch", "list"]  # 操作方法:查看,始时查看,列表

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User    #主体
  name: xin     #用户名
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role    #角色
  name: pod-reader      #绑定的角色名称
  apiGroup: rbac.authorization.k8s.io
# 执行
$ kubectl apply -f rbac.yaml 
role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/read-pods created
$ kubectl get role	#创建成功
NAME                                    CREATED AT
leader-locking-nfs-client-provisioner   2023-07-07T18:06:03Z
pod-reader                              2023-07-09T19:06:55Z
$ kubectl get pods --kubeconfig=xin.kubeconfig 	# 可以访问了
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-79899cbcb-nl52v   1/1     Running   1          2d1h 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值