이쿠의 슬기로운 개발생활

함께 성장하기 위한 보안 개발자 EverNote 내용 공유

Kubernetes/Kubernetes 보안

Kubernetes 인증 ( TLS )

이쿠우우 2020. 8. 23. 15:25
반응형

Kubernetes TLS 인증


Kubernetes 인증 관련 글 이동 

1. Kubernetes 인증 ( Authentication ) 이론
2. Kubernetes 인증 ( Basic Authentication )
3. Kubernetes 인증 ( TLS )
4. Kubernetes 인증 ( Bearer Token )
5. Kubernetes 인증 ( Webhook )
6. Kubernetes 인증 ( Webhook 외부 인증 연동 )
7. Kubernetes 인증 ( Webhook 외부 인증 LDAP )
8. Kubernetes 인증 ( Proxy )

 


 

 

참고) 실습환경

 

[Master Node server]

OS = CentOS 7

리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64

docker version : 1.13.1

docker api verison : 1.26

 

[Worker Node server]

OS = CentOS 7

리눅스 커널 버전 : Linux 3.10.0-1062.el7.x86_64

docker version : 1.13.1

docker api verison : 1.26

 

[Kubernetes version]

1.18

 


TLS 인증, RBAC 권한 관리, User Account 사용자 방식으로 인증

 

 

 

1. [TLS인증] kubernetss cluster의 master node에서 인증서를 생성. (OpenSSL 사용)

(Kubernetes Master Node 에서 작업)

 

1.1. Private key 발급 (OpenSSL 사용)

명령어 : openssl genrsa -out [키이름].key 2048

grenrsa :  키를 RSA 알고리즘으로 만들겠다는 의미

2048 : RSA 알고리즘 2048 로 생성하겠다는 의미

 

예) openssl genrsa -out iksoon.key 2048

 

1.2. CSR 생성 (Certificate Signing Request : 인증서 서명 요청)

공개키 인증서 발급을 위해 신청자가 인증기관에 보내는 메시지.

인증에 필요한 정보를 담고 있음

Private Key 없이 변조가 불가능한 특징을 가지고 있음

 

CSR이란?
SSL 인증의 정보를 암호화하여 인증기관에 보내 인증서를 발급받게 하는 신청서.
정보항목에는 국가코드, 도시, 회사명, 부서명, 이메일, 도메인 주소 등이 들어가 있음.

 

[ 명령어 ]

openssl req -new -key [상위에서 만든 개인키 파일 경로] -out [생성할 인증서 서명 파일 이름].csr -subj "/CN=[인증서 이름]/O=[회사명]"

예) openssl req -new -key iksoon.key -out iksoon.csr -subj "/CN=iksoon/O=iksoontest"

 

 

1.3. 인증서 생성 (Certificate Authoriy)

위에서 생성한 개인키와 인증 요청서로 인증서를 생성

 

참고) 

kubernetes cluster의 ROOT CA를 통해 생성해야 함

인증서 발행기관을 kubernetes 의 ca.crt로 생성하면

인증서 속에 들어있는 정보가 모두 kubernetes 정보로 생성되면서 

kubernete cluster와 통신할 때 사용할 수 있는 인증서로 생성됨.

인증서 속에 들어있는 정보
1. 인증서 소유자의 e-mail 주소 
2. 소유자의 이름 
3. 인증서의 용도 
4. 인증서 유효기간 
5. 발행 장소 
6. Distinguished Name (DN) 
- Common Name (CN) 
- 인증서 정보에 대해 서명한 사람의 디지털 ID 
7. Public Key 
8. 해쉬(Hash)

 

 

kubernetes default cluster 인증서 위치 확인법

env로 환경변수 확인

환경변수 KUBECONFIG 값을 찾음

defalut 경로 예시) KUBECONFIG=/etc/kubernetes/pki

해당 경로의 pki 폴더에 인증서가 있음

그중 ca.crt, ca.key를 사용해서 인증서를 생성함

 

[ 명령어 ] 

openssl x509 -req -in [상위에서 생성한 인증서 서명 파일 경로] -CA [kubernetes cluster ca.crt 경로] -CAkey

[kubernetes cluster ca.key 경로]  -CAcreateserial -out [인증서 이름] -days 365

 

예 )

openssl x509 -req -in iksoon.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key  -CAcreateserial -out iksoon.crt -days 365

 

 

 

 

 


 

 

 

2. [RBAC 권한 관리] role, roleBinding 생성

(Kubernetes Master Node에서 작업)

 

[ role2.yaml 파일 예시 ]

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: iksoon-role-a        # 해당 Role의 이름
  namespace: iksoon-ns-a  # Role 이 적용될 namespace 설정
                                   # (role 규칙은 모두 해당 namespace에 적용되고 해당 namespace 만 사용 가능) 

                                   # 해당 namespace는 미리 생성되어있어야 함
rules: # 권한 부여
- apiGroups: ["", "extensions", "apps"]
  resources: ["deployments", "pods", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # you can also use ["*"]


---


apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: iksoon-rb-a
  namespace: iksoon-ns-a
subjects:
- kind: User       # 사용자를 User Account로 사용하기 위해 User로 설정함
  name: iksoon  # 상위 인증서 서명 과정에서 생성한 "/CN=[인증서 이름]"의 인증서 이름을 넣어줘야 함
  apiGroup: ""
roleRef:
  kind: Role
  name: iksoon-role-a  # RoleBinding에 적용될 Role name을 넣어줌
  apiGroup: ""

 

[ 정상 생성 결과 ]

확인 명령어 :  kubectl get role,roleBinding -n [role 에서 선택한 namespace]

예)  kubectl get role,roleBinding -n iksoon-ns-a

 

오류 주의)

만약 -kind: User 하위의 name 설정에

인증서 이름이 동일하지 않으면 이후에 아래의 그림과 같이

id와 password를 물어보고 오류가 발생함

해당 과정에서는 id password는 모두 인증서로 대체돼서 입력할 값이 없음

 

 

 


 

 

 

3. Client에서 kubeconfig.conf 파일 작성

(kubectl 명령으로 붙고자 하는 Client에서 작업)

 

3.1. 사전작업 : kubectl을 다운해야 함 (kubectl 설치 과정은 kubernetes 로컬 설치 과정 문서 참고)

원하는 위치에 kubeconfig.yaml 파일 작성

 

3.2. 해당 yaml 파일 위치 환경변수 설정해야 함

[ 명령어 ]

export KUBECONFIG=/root/k8s/kubeconfig2.conf

참고) 경로와 yaml 파일 이름은 고정이 아님, 환경변수 KUBECONFIG만 고정값

 

[ 적용 확인 ]

해당 환경변수가 설정되어 있으면

kubectl 이 KUBECONFIG 환경변수를 확인하고 동작함

 

예제 1) kubeconfig.conf ( insecrue-skip-verify 가 true, 인증에 사용할 키를 파일 경로로 설정한 경우 )

apiVersion: v1
kind: Config


clusters:
- cluster:
    insecure-skip-tls-verify: true # insecure-skip-tls-verify옵션은 인증서에 대한 내용
           # 일반적으로 웹서버에 대한 TLS인증서를 설정할 때는 공신력 있는 기관에서 발급한 인증서를 발급해서 사용
           # 그러면 브라우저에서 접근할 때 이 인증서가 공인기관에서 발급한 인증서인지를 확인해서
           # 맞다면 정상적으로 접근 가능하게 합

           # 실습은 공인기관에서 생성한 인증서가 아닌 openssl로 생성한 인증서이므로 검증을 할 필요가 없음
           # insecure-skip-tls-verify 옵션을 true로 설정하면 인증서가 공인기관의 인증서인지 검증하는 과정을 건너뜀
    certificate-authority-data:    # insecure-skip-tls-verify: true의 경우 해당 부분을 공백으로 설정
    server: https://10.0.2.15:6443 # 접근하고자 하는 kubernetes master node 주소
  name: kubernetes # cluster 설정 name [고유의 이름값을 넣어줌]
 
contexts:
- context: 
    cluster: kubernetes  # 상위의 cluster 설정 name 값을 넣어줌
    user: iksoon         # 하위의 user: 의 name에 해당하는 값을 넣어줌
  name: iksoon-test@kubernetes # context 설정 name [고유의 이름값을 넣어줌]
current-context: iksoon-test@kubernetes
 
preferences: {}


users:
- name: iksoon    # RoleBinding의 subject/kind: User/name 값을 넣어줌 ["/CN=[인증서 이름]"의 인증서 이름과 동일]
  user:
    client-certificate: /root/k8s/pki/iksoon.crt   # 인증에 사용할 공개키 파일 경로
    client-key: /root/k8s/pki/iksoon.key          # 인증에 사용할 SSL key 파일 경로

예제 2) kubeconfig.conf ( insecrue-skip-verify 가 false, 인증에 사용할 키를 파일 경로로 설정한 경우 )

apiVersion: v1
kind: Config


clusters:
- cluster:
    insecure-skip-tls-verify: false # insecure-skip-tls-verify옵션을 false로 설정할 시 인증서 검증을 거치게 됨
                                         # insecure-skip-tls-verify 옵션을 사용하지 않으면 default로 false 설정.
# insecure-skip-tls-verify: false의 경우 해당 부분에 접속하고자 하는 kubernetes master node의
# certificate-authority-data 값을 넣어줘야 함
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZ~~실제로는 더 긴 내용이 들어감
 
    server: https://10.0.2.15:6443 
  name: kubernetes 


contexts:
- context: 
    cluster: kubernetes
    user: iksoon
  name: iksoon-test@kubernetes
current-context: iksoon-test@kubernetes
 
preferences: {}


users:
- name: iksoon
  user:
    client-certificate: /root/k8s/pki/iksoon.crt
    client-key: /root/k8s/pki/iksoon.key

 

예제 3) kubeconfig.conf ( insecrue-skip-verify 가 false, 인증에 사용할 키를 Data로 설정한 경우 )

apiVersion: v1
kind: Config


clusters:
- cluster:
    insecure-skip-tls-verify: true
    certificate-authority-data:   
    server: https://10.0.2.15:6443
  name: kubernetes


contexts:
- context: 
    cluster: kubernetes
    user: iksoon
  name: iksoon-test@kubernetes
current-context: iksoon-test@kubernetes
preferences: {}


users:
- name: iksoon
  user:
# 파일 경로가 아닌 공개키의 data로 설정할 수도 있음 
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1J~~~~ 뒤에 data더 많지만 생략
    client-key-dataLS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRV~~~~~뒤에 data더 많지만 생략

 

 

참고)

client-certificate-data 값에 사용되는

crt 파일 data 추출 명령어 : cat iksoon.crt  | base64 | tr -d '\n'

 

client-key-data 값에 사용되는

key 파일 data 추출 명령어 : cat iksoon.key  | base64 | tr -d '\n'

 


 

 

4. 결과 확인

(kubectl 명령으로 붙고자 하는 Client에서 작업)

 

role에 설정한 namespace와 권한에 해당하는 명령 실행

 

[ 정상적인 경우 ]

아래와 같이 명령어가 정상적으로 실행됨

 

[ 권한이 없는 경우 ]

명령 실행이 안됨

 

 

 

 


제 글을 복사할 시 출처를 명시해주세요.
글에 오타, 오류가 있다면 댓글로 알려주세요! 바로 수정하겠습니다!


 

 

 

 

 

 

 

 

참고

인증

https://kubernetes.io/docs/reference/access-authn-authz/authentication/

https://arisu1000.tistory.com/27847

https://bcho.tistory.com/1272

https://blog.naver.com/alice_k106/221596406973

https://blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221492934710&redirect=Dlog&widgetTypeCall=true&directAccess=false

https://hyperconnect.github.io/2019/12/17/kubehook.html

https://www.youtube.com/watch?v=_vVdSaPi7e0

 

권한 (Cluster role Binding, role Binding)

https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/

https://kubernetes.io/docs/reference/access-authn-authz/rbac/

https://jonnung.dev/kubernetes/2020/06/18/kubernetes-user-authorizations/

https://nirsa.tistory.com/155?category=871751

https://nirsa.tistory.com/154?category=871751

https://v1-16.docs.kubernetes.io/docs/reference/access-authn-authz/rbac/

 

kubeconfig 파일 참고

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#config

https://codefarm.me/2019/02/01/access-kubernetes-api-with-client-certificates/

 

예시

https://coffeewhale.com/kubernetes/authentication/http-auth/2020/05/03/auth02/

 

 

반응형