k8s双向证书认证实战-创建基于rbac认证的角色并绑定用户
转载
一、认证管理
kubernetes集群安全的关键点在于如何识别并认证客户端身份,它提供了3种客户端身份认证方式:
1. HTTP Base认证
通过用户名+密码的方式进行认证。
这种方式是把“用户名:密码”用BASE64算法进行编码后的字符串放在HTTP请求中的Header的Authorization域里面发送给服务端。服务端收到后进行解码,获取用户名和密码,然后进行用户身份认证的过程。
2. HTTP Token认证
通过一个Token来识别合法用户。
这种认证方式是用一个很长的难以被模仿的字符串–Token来表明客户端身份的一种方式。每个Token对应一个用户名,当客户端发起API调用请求的时候,需要在HTTP的Header中放入Token,API Server接受到Token后会和服务器中保存的Token进行比对,然后进行用户身份认证的过程。
3. HTTPS证书认证
基于CA根证书签名的双向数字证书认证方式。
这种认证方式是安全性最高的一种方式,但是同时也是操作起来最麻烦的一种方式。
HTTPS认证大体分为3个过程:
- 证书申请和下发
HTTPS通信双方的服务器向CA机构申请证书,CA机构下发根证书、服务端证书及私钥给申请者
- 客户端和服务端的双向认证
- 客户端向服务器端发起请求,服务端下发自己的证书给客户端,客户端接收到证书后,通过私钥解密证书,在证书中获得服务端的公钥,客户端利用服务器端的公钥认证证书中的信息,如果一致,则认可这个服务器。
- 客户端发送自己的证书给服务器端,服务端接收到证书后,通过私钥解密证书,在证书中获得客户端的公钥,并用该公钥认证证书信息,确认客户端是否合法
- 服务器端和客户端进行通信
服务器端和客户端协商好加密方案后,客户端会产生一个随机的秘钥并加密,然后发送到服务器端。服务器端接收这个秘钥后,双方接下来通信的所有内容都通过该随机秘钥加密。
二、创建用户证书
1. 生成客户端私钥
# 进入 k8s 存放证书的目录
cd /etc/kubernetes/pki/
# 生成私钥
umask 077;openssl genrsa -out devman.key 2048
2. 生成证书请求
openssl req -new -key devman.key -out devman.csr -subj "/CN=devman/O=devgroup"
申请的用户是devman,组是devgroup。
3. 签属证书
openssl x509 -req -in devman.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out devman.crt -days 3650
三、配置集群上下文
# 1. 设置集群(这一步不需要,使用默认的集群即可)
# kubectl config set-cluster kubernetes --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.18.100:6443
# 2. 创建一个用户 devman,并指定他的证书和私钥的位置。
kubectl config set-credentials devman --embed-certs=true --client-certificate=/etc/kubernetes/pki/devman.crt --client-key=/etc/kubernetes/pki/devman.key
# 3. 设置上下文(创建特定集群和用户的绑定关系,切换上下文相当于切换了用户和集群)
kubectl config set-context devman@kubernetes --cluster=kubernetes --user=devman
# 4. 创建 namespace
kubectl create ns dev
# 5. 切换到 devman 用户
kubectl config use-context devman@kubernetes
此时如果执行 kubectl get pods -n dev
会提示没有权限,这个是因为还没授权,接下来通过创建角色和角色绑定用户 devman 进行授权。
四、创建角色和角色绑定
1. 切换到admin账户
kubectl config use-context kubernetes-admin@kubernetes
2. 创建角色和角色绑定
# 创建请求文件
cat > dev-role.yaml<<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: dev-role
namespace: dev
rules:
- apiGroups: [""] # 支持的API组列表,""空字符串,表示核心API群
resources: ["pods"] # 支持的资源对象列表
verbs: ["create","get","watch","list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: authorization-role-binding
namespace: dev
subjects:
- kind: User
name: devman
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-role
apiGroup: rbac.authorization.k8s.io
EOF
# 生成角色
kubectl apply -f dev-role.yaml
五、测试
1. 切换到devman账户
kubectl config use-context devman@kubernetes
2. 创建并获取 pod
# 创建nginx
kubectl run nginx-pod --image="nginx" -n dev
# 获取pod列表
kubectl get pod -n dev
# 获取default名称空间列表 -> 没有权限
kubectl get pod
#Error from server (Forbidden): pods is forbidden: User "devman" cannot list resource "pods" in API group "" in the namespace "default"