Minikube 인증서를 통한 사용자 추가 및 인증/인가
By Bys on July 14, 2022
Minikube
1.Minikube 인증서를 이용한 사용자 인증
이번에는 인증서를 통한 신규 사용자 생성 및 권한에 대해 확인 해 본다.
- Normal user
A few steps are required in order to get a normal user to be able to authenticate and invoke an API. First, this user must have a certificate issued by the Kubernetes cluster, and then present that certificate to the Kubernetes API.
자세한 내용은 아래 공식홈페이지를 참고한다.
Certificate Signing Requests
사용자는 클러스터에 의해 발급된 인증서를 가지고 인증을 진행하면 허가가 가능하다. 따라서 개인 키파일을 만들어 서명요청서를 만들고 클러스터의 키파일로 서명을 요청한다. 클러스터의 관리자가 서명요청을 승인하면 클러스터에 의해 서명된 인증서가 발급되게 되고 사용자는 발급된 인증서를 통해 config파일을 구성하고 인증을 진행하게 된다.
아래의 과정을 따라가며 진행해본다.
1.1 Create private key
openssl 커맨드를 통해 개인 키파일을 하나 생성한다.
openssl genrsa -out devuser.key 2048
openssl 커맨드를 통해 생성된 키파일을 이용하여 csr(Certificate Signing Request)파일을 생성한다.
CN 은 반드시 생성할 유저이름으로 지정한다.
openssl req -new -key devuser.key -out devuser.csr
csr파일의 내용을 base64로 인코딩하여 출력한다.
cat devuser.csr | base64 | tr -d "\n"
1.2 Create CertificateSigningRequest
Certificate 서명 요청을 위해 아래와 같이 수행한다.
Request는 위에서 csr파일의 base64인코딩으로 출력된 값을 입력한다.
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: devuser
spec:
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ3RqQ0NBWjRDQVFBd1ZURUxNQWtHQTFVRUJoTUNTMUl4RlRBVEJnTlZCQWNNREVSbFptRjFiSFFnUTJsMAplVEVjTUJvR0ExVUVDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRFUk1BOEdBMVVFQXd3SWRHVnpkSFZ6ClpYSXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFESjhwZThWN3pTYnpBN0thZHkKMkQzeDM4QVhtTUZ0WTAwZDIyUWZBVUxxcmNXMG1XVldBUno0U3p0TTk5WUNuME94WmZtbUJqRGYxVSsyVUhocgpDSkxJck9GWGZZTUw2ZVZaUEhRaVRXM3ZPSk1ReHF4UGhVZGRnTG5ZSkViWjdwcW92dzgxSzYwQVJhaHF6Z2x3Ci8yR3BqNUozNTZoUjBkdGx6R0Yyc2I0TGpxM0VQR3RTVTVrdUVqQnh0RkIyM2piNXorOHJzcENXdFF3VGMvYlcKYmY0NUQvbGdEdk1ycGk0dEx1S0cwN1FCV0R1d3I3ZitwUWg1LytXVTZwMU9XbGZPQVlhc1c4Ri9xVGFqNks1MwpvYU1ZTzEzQVA1RFJzcEFzTmVPdFNkYkI2QmFCZ2k0bG1PVDV4NUhzdkR4L0VGNEVPN0ozK1IxbU8wQVZ4RE1ECm1ueU5BZ01CQUFHZ0hEQWFCZ2txaGtpRzl3MEJDUWN4RFF3TGNYVmtkRzVuYjJkdk1TRXdEUVlKS29aSWh2Y04KQVFFTEJRQURnZ0VCQUFQM09QMUJBZlBrdkR0V1BtVWRUNElkZ1ltOFNjcXVOZ1J2OEZ2azRWaXdEZW5hWHovRgpETjRHOVdMK0F6aW9WSEVRU3R2NFU1TzYybU1EbHB2aWVuWGIvWHE3cEs2c2FQZmNhV3ZGenN0Z0lqVWw4NDdqCkRyaS8xNFArKyttRFplTGNNTWlHcnNYOHp6UXRTbTBRS1JCaXg3SEVGSnhaTmEycTZGNVNvRHU5N2RYbUxjNVkKdVFlTXZmYTNsNDRxb20yblRNVmFvdWV2WUFablZkNndIcDltbGJCK2E3TVRDazhIVTRDMUZFcXU3RnMvRmk3bAp0VGJtc1hEemZ6WFNOTUgyVlNYOVZ5TU1nbGZtcVRKWUR4TVFPb3hUOVBQOVg3eEdaZDRGK0pYbXU0Vll2a0lYCjl6ZHM0U2hRdHB6WnczbVQ3NHI3Z1VrbXB4MGdJOWFyU1pBPQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
usages:
- client auth
EOF
요청을 진행하고 나면 아래와 같이 Pending(승인이 안된상태) 상태의 test이라는 이름의 서명요청이 생성되었다.
kubectl get csr
##Print
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
devuser 3s kubernetes.io/kube-apiserver-client minikube-user 24h Pending
아래 커맨드를 통해 승인을 진행한다.
kubectl certificate approve devuser
csr을 확인해보면 Pending상태가 Approved, Issued 된 것을 볼 수 있다.
승인이 되고 발급까지 진행이 된 것이다.
k get csr
##Print
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
devuser 23s kubernetes.io/kube-apiserver-client minikube-user 24h Approved,Issued
아래 커맨드를 통해 devuser의 certificate값을 확인할 수 있다.
kubectl get csr devuser -o yaml
##Print
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"certificates.k8s.io/v1","kind":"CertificateSigningRequest","metadata":{"annotations":{},"name":"devuser"},"spec":{"expirationSeconds":86400,"request":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ3ZqQ0NBYVlDQVFBd1hURUxNQWtHQTFVRUJoTUNTMUl4RlRBVEJnTlZCQWNNREVSbFptRjFiSFFnUTJsMAplVEVjTUJvR0ExVUVDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRFWk1CY0dBMVVFQXd3UWQzZDNMblJsCmMzUjFjMlZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1ueWw3eFgKdk5Kdk1Ec3BwM0xZUGZIZndCZVl3VzFqVFIzYlpCOEJRdXF0eGJTWlpWWUJIUGhMTzB6MzFnS2ZRN0ZsK2FZRwpNTi9WVDdaUWVHc0lrc2lzNFZkOWd3dnA1Vms4ZENKTmJlODRreERHckUrRlIxMkF1ZGdrUnRudW1xaS9EelVyCnJRQkZxR3JPQ1hEL1lhbVBrbmZucUZIUjIyWE1ZWGF4dmd1T3JjUThhMUpUbVM0U01IRzBVSGJlTnZuUDd5dXkKa0phMURCTno5dFp0L2prUCtXQU84eXVtTGkwdTRvYlR0QUZZTzdDdnQvNmxDSG4vNVpUcW5VNWFWODRCaHF4Ygp3WCtwTnFQb3JuZWhveGc3WGNBL2tOR3lrQ3cxNDYxSjFzSG9Gb0dDTGlXWTVQbkhrZXk4UEg4UVhnUTdzbmY1CkhXWTdRQlhFTXdPYWZJMENBd0VBQWFBY01Cb0dDU3FHU0liM0RRRUpCekVOREF0eGRXUjBibWR2WjI4eElUQU4KQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBbFNwVDE2cHI3MGduSi82SklVK1h1RVR1ZHA5dllrYlJ5a1g2cm1ZMwpRSi9UNDk4K0NWTEtkQmtMWEdNSjRyZzMvbXRSZmdBbERpSUVMT3lSWnFiMGpvWW9UTjhPR0NNbjhqVkxoYVNVClBSNGhNWndSdy9hRTJsU2Zna2FUbXdLRVllTXFZSUVvTmVhQzlJcTRYbEV1VVhVOVlTcCtra2E2VmZ3YWc2Yk0KSk1FYWVmUTdjeXR5ZkRzMGhuOU91NlJ6WTF5QUxEK2dvRWJQSzNaOEdPbWcvWkRnZ3AwMmhsMlNPbVlhVnpDOQppakNHU3lnSW4xKzEvVEp4dEZSdlZ1SW9qZzVVeWhQWndBUDdza1BBOXFSdmlDSloyb3dFamFmYjVIQzlza1d1ClNGRTQvZWd6b1lENlRUSFV0K3R0MzRidGZpZzJPQmFyNnZlUmZMZGxFVG1IK2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K","signerName":"kubernetes.io/kube-apiserver-client","usages":["client auth"]}}
creationTimestamp: "2022-07-14T04:56:25Z"
name: devuser
resourceVersion: "421568"
uid: cb4009cb-485e-4ca3-b975-4b78db0fd177
spec:
expirationSeconds: 86400
groups:
- system:masters
- system:authenticated
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ3ZqQ0NBYVlDQVFBd1hURUxNQWtHQTFVRUJoTUNTMUl4RlRBVEJnTlZCQWNNREVSbFptRjFiSFFnUTJsMAplVEVjTUJvR0ExVUVDZ3dUUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRFWk1CY0dBMVVFQXd3UWQzZDNMblJsCmMzUjFjMlZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1ueWw3eFgKdk5Kdk1Ec3BwM0xZUGZIZndCZVl3VzFqVFIzYlpCOEJRdXF0eGJTWlpWWUJIUGhMTzB6MzFnS2ZRN0ZsK2FZRwpNTi9WVDdaUWVHc0lrc2lzNFZkOWd3dnA1Vms4ZENKTmJlODRreERHckUrRlIxMkF1ZGdrUnRudW1xaS9EelVyCnJRQkZxR3JPQ1hEL1lhbVBrbmZucUZIUjIyWE1ZWGF4dmd1T3JjUThhMUpUbVM0U01IRzBVSGJlTnZuUDd5dXkKa0phMURCTno5dFp0L2prUCtXQU84eXVtTGkwdTRvYlR0QUZZTzdDdnQvNmxDSG4vNVpUcW5VNWFWODRCaHF4Ygp3WCtwTnFQb3JuZWhveGc3WGNBL2tOR3lrQ3cxNDYxSjFzSG9Gb0dDTGlXWTVQbkhrZXk4UEg4UVhnUTdzbmY1CkhXWTdRQlhFTXdPYWZJMENBd0VBQWFBY01Cb0dDU3FHU0liM0RRRUpCekVOREF0eGRXUjBibWR2WjI4eElUQU4KQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBbFNwVDE2cHI3MGduSi82SklVK1h1RVR1ZHA5dllrYlJ5a1g2cm1ZMwpRSi9UNDk4K0NWTEtkQmtMWEdNSjRyZzMvbXRSZmdBbERpSUVMT3lSWnFiMGpvWW9UTjhPR0NNbjhqVkxoYVNVClBSNGhNWndSdy9hRTJsU2Zna2FUbXdLRVllTXFZSUVvTmVhQzlJcTRYbEV1VVhVOVlTcCtra2E2VmZ3YWc2Yk0KSk1FYWVmUTdjeXR5ZkRzMGhuOU91NlJ6WTF5QUxEK2dvRWJQSzNaOEdPbWcvWkRnZ3AwMmhsMlNPbVlhVnpDOQppakNHU3lnSW4xKzEvVEp4dEZSdlZ1SW9qZzVVeWhQWndBUDdza1BBOXFSdmlDSloyb3dFamFmYjVIQzlza1d1ClNGRTQvZWd6b1lENlRUSFV0K3R0MzRidGZpZzJPQmFyNnZlUmZMZGxFVG1IK2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
username: minikube-user
status:
certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURRakNDQWlxZ0F3SUJBZ0lRZVhXdlR6czhMelZNdlpEdUZEUzFwekFOQmdrcWhraUc5dzBCQVFzRkFEQVYKTVJNd0VRWURWUVFERXdwdGFXNXBhM1ZpWlVOQk1CNFhEVEl5TURjeE5EQTBOVEUwTVZvWERUSXlNRGN4TlRBMApOVEUwTVZvd1hURUxNQWtHQTFVRUJoTUNTMUl4RlRBVEJnTlZCQWNUREVSbFptRjFiSFFnUTJsMGVURWNNQm9HCkExVUVDaE1UUkdWbVlYVnNkQ0JEYjIxd1lXNTVJRXgwWkRFWk1CY0dBMVVFQXhNUWQzZDNMblJsYzNSMWMyVnkKTG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1ueWw3eFh2Tkp2TURzcApwM0xZUGZIZndCZVl3VzFqVFIzYlpCOEJRdXF0eGJTWlpWWUJIUGhMTzB6MzFnS2ZRN0ZsK2FZR01OL1ZUN1pRCmVHc0lrc2lzNFZkOWd3dnA1Vms4ZENKTmJlODRreERHckUrRlIxMkF1ZGdrUnRudW1xaS9EelVyclFCRnFHck8KQ1hEL1lhbVBrbmZucUZIUjIyWE1ZWGF4dmd1T3JjUThhMUpUbVM0U01IRzBVSGJlTnZuUDd5dXlrSmExREJOego5dFp0L2prUCtXQU84eXVtTGkwdTRvYlR0QUZZTzdDdnQvNmxDSG4vNVpUcW5VNWFWODRCaHF4YndYK3BOcVBvCnJuZWhveGc3WGNBL2tOR3lrQ3cxNDYxSjFzSG9Gb0dDTGlXWTVQbkhrZXk4UEg4UVhnUTdzbmY1SFdZN1FCWEUKTXdPYWZJMENBd0VBQWFOR01FUXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUhBd0l3REFZRFZSMFRBUUgvQkFJdwpBREFmQmdOVkhTTUVHREFXZ0JTOFBaei8wZitMN2tnbnlLZyszSVhoVGt1dzN6QU5CZ2txaGtpRzl3MEJBUXNGCkFBT0NBUUVBUkt5RE83NmFXbHovOHpuajd5LzFBTy9mZkhQNEhWa2UrNVJIcXdVU1NXTEdvUjYrYm9VOVBjdUgKZVl2VitlMmdhbk9VYkIxVWUxemtpZTdmaVA1eXZmZ0ZFN0NDdjYrT28wRUFvdU9nVytXM09VT3ZQMm5nbER0NQp0NitFcVBXb2E3OWtzWjQ4cTg0THVtMDlGckh2MGpybXA2bUNjM0kyeGJZMGtHUnR0MEhJZnpqdUVnZlh5SjB0CjJQWUZRM2syKy9SY2lpM05pTUZkZFJGY01MNEFuM0E1UkNqb2xGVFJTVGNSd2s0b3gwWGMyN1owV3ZsVFNNSWsKTXBXUkFTbVltaGE1M0NwL3ZKQUp2WUdPOVVDRXdZSDhhK0JpLzdGUFhlbkNaQlVZaWliR1VuYS91eVB0aUJUMQo4UkIvNU8velI5bTFHdGkvUmpyTzRFTFpQcHphc0E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
conditions:
- lastTransitionTime: "2022-07-14T04:56:41Z"
lastUpdateTime: "2022-07-14T04:56:41Z"
message: This CSR was approved by kubectl certificate approve.
reason: KubectlApprove
status: "True"
type: Approved
아래 커맨드를 통해 certificate 파일을 생성한다.
kubectl get csr devuser -o jsonpath='{.status.certificate}'| base64 -d > devuser.crt
devuser.crt파일이 생성된 것을 확인 할 수 있다.
ls -l
##Print
total 12
-rw-rw-r-- 1 minikube minikube 1192 Jul 14 05:00 devuser.crt
-rw-rw-r-- 1 minikube minikube 1029 Jul 14 04:56 devuser.csr
-rw-rw-r-- 1 minikube minikube 1679 Jul 14 04:55 devuser.key
1.3 Authorization
dev namespace에 대해서만 파드의 reader권한 있는 role을 생성한다.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
위 에서 dev namespace에 대해서 조회 role을 devuser와 binding을 해준다.
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: dev
subjects:
# You can specify more than one "subject"
- kind: User
name: devuser # "name" is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
이렇게 되면 devuser는 dev namespace에 있는 pod만 조회가 가능해야 한다.
1.4 Add to kubeconfig
kubectl config set-credentials devuser --client-key=devuser.key --client-certificate=devuser.crt --embed-certs=true
kubectl config set-context devuser --cluster=minikube --user=devuser
kubectl config use-context devuser
커맨드를 통해 devuser의 context가 생성된 것을 확인할 수 있다.
k config get-contexts
##Print
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
minikube minikube minikube dev
* devuser minikube devuser
1.5 Check
정상 확인을 위해 get pod 커맨드를 확인 해보면 아래와 같이 전체 클러스터의 파드를 조회하고자 하면 오류가 발생한다.
인증은 되었지만 권한이 없어 오류가 발생한 부분이다.
k get pods -A
##Print
Error from server (Forbidden): pods is forbidden: User "testuser" cannot list resource "pods" in API group "" at the cluster scope
dev namespace의 pod에 대해서 정상 조회가 가능하다.
k get pods -n dev
##Print
NAME READY STATUS RESTARTS AGE
nginx-deployment-544dc8b7c4-hcn8g 1/1 Running 0 45h
nginx-deployment-544dc8b7c4-rsfkw 1/1 Running 0 45h
Ref: https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/
kubernetes
minikube
csr
crt
authentication
]