이쿠의 슬기로운 개발생활

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

클라우드/Kubernetes

13. Kubernetes 인증(Authentication) 이론

이쿠우우 2020. 8. 23. 14:50
반응형

Kubernetes 인증(Authentication) 이론


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

 

 

 


 

 

 

Kubeconfig 인증 (Authentication) 이란?

kubectl 명령으로 kubernetes의 API Server 모듈에 접근하기 위해서는 인증(Authentication) 과정을 통과해야 함.

kuberentes 설치 이후 kubectl 명령을 정상적으로 사용할 수 있었던 이유는 

설치 이후에 사용자가 설정하지 않았어도 이미 kubectl 설정에 인증서가 사용되고 있었기 때문임.

kubectl을 사용해서 kubernetes API Seerver 모듈에 접근할 수 있는 기본 포트 : 6443

6443 포트는 기본적으로 TLS 인증이 적용되어 있음

일반적인 https인증은 접근하는 클라이언트에서는 인증서가 필요 없지만,

Kubernetes Api Server 모듈에 열려 있는 6443 Port에 접근하기 위해서는

Api Server에서 가지고 있는 인증서에서 검증 가능한 유효한 인증서를 가지고 접근해야 통신이 가능.

Kubernetes에 인증을 종류는 User Account, Service Account 2가지가 있음

 

 

 

 


 

 

Kubernetes에 인증을 요청할 수 있는 사용자 종류

User Account

일반적인 사용자 아이디의 개념.

kubernetes는 사용자에 대한 정보를 관리하고 인증할 수 없음 

그래서 외부의 별도 인증 시스템을 사용해서 사용자 정보를 사용할 수 있도록 함

 

[User Account로 Pod 생성 예제]

Pod를 생성할 때 yaml 파일로 pod 생성을 명시하고

kubectl 명령으로 Pod를 생성한 경우 User Account로 생성되는 것과 같음

 

[사용자 정보 사용 방법]

구글 계정(Google Account), 오픈스택의 키스톤(keystone), LDAP 등의 인증 시스템과 연동이 가능

파일에 유저명과 비밀번호를 저장해 두고 사용하는 것도 가능

openssl로 인증서 만들어서 해당 인증서 계정으로 접근

추가적으로 User를 그룹화해서 사용하는 User Group 개념도 있음

 

Service Account 

Client 가 kubernetes API를 호출할 때 이는 실제 사람인 사용자가 아니라 시스템이 됨

그래서 kubernetes는 이를 일반 사용자와 분리해서 관리하는데 그것이 바로 Serivce Account 임.

Service Account는 kuberentes 가 직접 관리하는 사용자 계정으로 

Secret Object 가 할당되어서 해당 Service Account에 대한 비밀번호 역할을 함

[Service Account로 Pod 생성 예제]

Pod를 생성할 때 yaml 파일로 Deployment와 같은 Controller로 생성할 경우

Deployment가 Pod를 관리하고 생성하기 때문에

Service Account를 사용해서 생성되는 원리.

 

아래 그림과 같이 우리는 몰랐지만 kubernetes 에는 이미 각종 Controller에 해당하는

Service Account 계정들이 존재해서 

해당 Controller로 Pod를 생성할 때 

Controller와 일치하는 Service Account를 사용해서 생성함.

 


 

 

인증 방법

 

Basic Type 인증

사용자 ID, Password 정보를 파일 형태로 저장하여

해당 파일 정보를 가져와서 인증하는 방식

보안에 취약하여 HTTPS로 접속하는 것을 권장함

 

Kubernetes에서 제공하는 Root CA 인증서와 키를 이용

Kuberentes Root CA 인증서 : /etc/kubernetes/pki/ca.crt

Kuberentes Root CA 키 : /etc/kubernetes/pki/ca.key

Client PKI 생성 후 

해당 PKI를 사용해서 인증을 함

TLS 인증

기본적으로 Kubernetes Api Server 모듈은 6443 Port가 열려 있는데

해당 6443 port는 TLS인증이 걸려있음

공인인증서와 같은 방식

보안성은 가장 높지만 인증서 관리에 노력이 필요함.

 

TLS 인증이란?
Transport Layer Security (전송 계층 보안)
 3 Way Handshake 인터넷 암호화 통신 프로토콜
통신할 때 오고 가는 패킷을 암호화하는 일반적인 방법
SSL (Secure Sockets Layer)로 불리기도 함
TLS는 SSL 3.0을 기반으로 업그레이드한 프로토콜
HTTPS의 S 가 SSL을 뜻하는 것.

 

[제공 기능]

신원 확인

메시지 무결성

메시지 기밀성

 

 

Bearer Token 인증

HTTP 프로토콜이 제공하는 인증 방법인 HTTP Authentication 방법 중 하나로 

HTTP Header를 통해 인증 정보를 서버에게 전달하는 방법.

Kubernetes Master Node의 API Server 모듈도 결국 웹서버와 똑같이 동작하기 때문에 

API Server 모듈도 HTTP Authentication 설정을 적용할 수 있음

 

HTTP Authentication을 사용하기 위해서는

HTTP Header에 "Authorzation " <type><credentials>" 필드가 있어야 함

  • type : 인증 방식 선언

  • credentials : 사용자 인증 정보

kubernetes는 이러한  HTTP Authentication 방식 Type에 Bearer를 지원함

 

Bearer Token은 서버에서 지정한 어떠한 문자열도 token으로 사용할 수 있음

kubernetes는 Bearer 인증으로 사용할 문자열을

Service Account의 Secret 인증 토큰으로 사용함

해당 토큰을 Bearer Type의 credentials 값으로 HTTP Header에 포함하여 인증함

 

이러한 Bearer Token 인증 방식은 굉장히 허술한 면이 많아서

이를 보완하고자 Kubernetes에서 Bearer Token을 전송할 때 주로

JWT (Json Web Token)를 사용함

 

JWT (Json Web Token) 이란?
JSON Web Token의 약자로, 
일반적으로 HTTP API 서버를 만들 때에 인증 방법으로 사용.
서버는 사용자가 로그인할 때 고유한 Token을 생성하고, 
이를 사용자에게 알려주어 사용자가 다른 API를 사용할 때에 헤더에 
이 Token을 넣으면, 자신이라는 것을 증명할 수 있게 하는 것.

Json 형태로 Token을 정의.

[JWT는 3가지 파트로 구분됨]
1. Header : 토큰 형식 와 암호화 알고리즘을 선언
2. Payload : 전송하려는 데이터를 JSON 형식으로 기입
3. Signature : Header와 Payload의 변조 가능성을 검증

각 파트는 Base64로 인코딩 되어서 " . " 로 구분되어 있음
JWT는 보안 기술이 아닌 인증 기술에 해당함

 

Service Account의 Secret으로 생성한 Token 분석

Kuberentes Secret Token 은 Bearer Token을 사용하지만

단순한 문자열이 아닌 위조 방지 장치가 내장된 JWT Token을 사용함

 

Kubernetes에서 JWT 서명 때 사용하는 Private Key : /etc/kubernetes/pki/sa.key

Kubernetes에서 JWT 인증 때 사용하는 Public Key  : /etc/kubernetes/pki/sa.pub

 

생성된 Secret 예제는 아래와 같이

JWT 형식처럼 3가지 파트로 구분되어 있음

 

JWT Decode 참고 사이트 :  https://jwt.io/

 

[ Service Account Secret Token 예제 ]

eyJhbGciOiJSUzI1NiIsImtpZCI6IkpjVFVTT1c3aWd2QmhKbHMtdkp5cE96VlRsYzRjWXN2UDRKWTBuNTdrR1EifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJpa3Nvb24tbnMiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoiaWtzb29uLXNhLXRva2VuLTZoYnF2Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imlrc29vbi1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImM2MTgxOGUzLWUzYmQtNDFmYi05ZGY4LWQwZTE3ZWYxODNkOSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDppa3Nvb24tbnM6aWtzb29uLXNhIn0.igCYwY-L8roXeqH0Fm9XjuIipe_WyK6vD4mC2eEgWgcZiAgELMEu88oZuroijPlxixT4DxaFXxXUALbLuJzzlQeN9xZDJXqXwOHswA5BKefXIyWYS-V3R1QxLRreDXB5CSTYW0Jco6_s2Z2GHv_tH8x6Yh3p4E8Hpoxja1oyQFOoLOgS86S11YgBmtGOcVbHS_CiddvZP8LRea_geKlIMGXEsEtxH4a2vBcrU3HJP7lHQWmDXHNL1zQYuP6DsPBUaVPnyc4AgnX3NMAdeWZHOEd7XZ0d-8cRVPHVVkI_fOeiQkEeUPh4lFt1NIkBUc0LlmKYOhV3CpKqOG3nxqjGqQ

이런 Service Account Secret Token 정보는 아래와 같은 정보를 가지고 있음

 

결과가 Invalid Signature로 나오는 이유는

아직 Public Key로 사용자의 JWT Token을 검증하지 않았기 때문.

Verified를 받기 위해서는 kubernetes의 Service Account public key를 넣어줘야 함

 

[ Service Account Public key 확인법 ]

echo $KUBECONFIG 

위치의 pki 디렉터리

(참고 : default 경로는 /etc/kubernetes/pki 임)

해당 디렉터리의 sa.pub 파일이 

kubernetes service account public key에 해당함

해당 공개키를 넣어주면 인증되는 것을 확인할 수 있음

 

 

 

Webhook 인증

kubernetes에서 Webhook 이벤트를 사용하는 임의의 인증 연동하여 인증을 받을 수 도 있음

 

webhook (웹훅)이란?
서버에서 어떠한 작업이 수행되었을 때 해당 작업이 수행되었음을 HTTP POST로 알리는 개념.
Webhook을 구현한 웹 애플리케이션은, 특정 작업이 수행될 때 URL에 대해 POST방식으로 요청을 생성.
이때, url(콜백 url)은 웹 애플리케이션을 사용하는 유저가 자신의 URL을 지정할 수 있음

kubernetes는 이러한 webhook 기능을 별도의 인증서버와 연동하여 

webhook 인증 기능을 제공함

webhook을 통해 LDAP, Basic Authentication Server 등등 을 자유롭게 연동하여 사용할 수 있음

 

 

 

 


 

 

권한 관리 (Authorization)

 

ABAC (Attribute-Based Access Control)

속성 기반의 권한 관리

ABAC 방식은 권한에 대한 내용을 파일로 관리하기 때문에

권한을 변경하려면 직접 마스터 노드에 들어가서 파일을 변경하고

api server를 재시작해주어야 하기 때문에 번거로워 잘 사용하지 않음

 

 

RBAC (Role-Based Access Control)

역할 기반 권한 관리

kubernetes는 기본적으로 안전한 Cluster 구성을 위해 RBAC을 사용함

종류로는 Role과 RoleBinding, ClusterRole과 ClusterRoleBinding 이 있음

 

Role

특정 API, 리소스에 대한 권한을 명시한 규칙의 집합

Role : 설정한 NameSpace 한 곳에만 적용됨

 

[ 예제 Role.yaml 파일 ]

apiVersion: rbac.authorization.k8s.io/v1

kind: Role

metadata:

  name: iksoon-role     # 해당 Role의 이름

  namespace: iksoon-ns  # Role 이 적용될 namespace 설정
                                # (role 규칙은 모두 해당 namespace에 적용되고 해당 namespace 만 사용 가능)

                                # 해당 namespace는 미리 생성되어있어야 함

rules:                 # 권한 부여

- apiGroups: ["", "extensions", "apps"] # 사용할 API를 명시함

                                                 # 일반 yaml 파일에서 apiVersion을 명시하는데
                                                 # 그 version 그룹에 대한 권한을 설정하는 부분

                                                 # 예) apps/v1 의 apps, batch/v1 의 batch, extenstions/v1beta의 extensions 등등

  resources: ["deployments", "pods", "replicasets"] # pod, deployment, service 등 어떤 자원에 접근이 가능한지 설정

  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 어떤 동작이 가능한지 설정 

                                                                                      # 참고 ["*"] 설정 시 모든 권한 획득

 

 

Role Binding

Role을 사용자에게 부여하기 역할을 수행

Role과 User를 묶어주는 역할을 수행

특정 namespace 하나에만 적용됨

 

[ 예제 RoleBinding.yaml 파일 ]

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

  name: iksoon-rb

  namespace: iksoon-ns # 적용 대상 namespace 설정

subjects:

- kind: User     # 사용자를 설정 [User, Group, ServiceAccout] 가 올 수 있음

  name: iksoon   # 상위 User 종류에 해당하는 name을 넣어줌
                      #해당 user는 상위 kind 종류와 동일해야 하고 기존에 생성되어있어야 함

  apiGroup: ""

roleRef:  # 해당 사용자에게 어떤 Role를 적용할지 설정

  kind: Role

  name: iksoon-role  # RoleBinding에 적용될 Role name을 넣어줌

  apiGroup: rbac.authorization.k8s.io

 

 

ClusterRole

상위에서 설명한 Role과 동일하게 특정 API, 리소스에 대한 권한을 명시한 규칙의 집합

ClusterRole : kubernetes Cluster 전체에 대한 권한을 정의할 수 있음

여러 namespace에 걸쳐있는 worker node 리소스 등 자원에 대해서도 권한을 정의할 수 있음

그렇기 때문에 별도 metadata에 네임스페이스 설정이 없음

 

[ 예제 ClusterRole.yaml 파일 (rules 사용) ]

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  name: iksoon-cluster-role     # 해당 ClusterRole의 이름

  labels: 

    iksoon.cluster.role/aggregationRule-test  

rules:               

- apiGroups: ["", "extensions", "apps"]

  resources: ["deployments", "pods", "replicasets"] 

  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

 

[ 예제 ClusterRole.yaml 파일 (aggregationRule 사용) ]

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  name: iksoon-cluster-role     # 해당 ClusterRole의 이름

aggregationRule:        # aggregationRule을 사용해서 다른 clusterRole을 조합해서 사용할 수 있음
                              # (K8s 1.9 version부터 지원)

  clusterRoleSelectors:

  - matchLabels:

      iksoon.cluster.role/aggregationRule-test  # 만약 상위 예제 clusterRole 이 생성되어있다면 

                                                              # 해당 ClusterRole의 Role을 받아와서 사용할 수 있음

rules: [] # 권한 부여 부분에 Role 방식과 동일하게 권한 설정을 해도 되지만

          # 다음 예제와 같이 공백으로 되어있고 상위에 aggregationRule 설정이 되어있다면

          # matchLabels에 맞는 다른 cluster role에서 필요한 룰들을 가져와서 권한 설정을 할 수 있음

 

ClusterRole Binding

롤 바인딩과 설정이 비슷하지만 metadata 설정에 namespace 항목이 없음

 

[ 예제 ClusterRoleBinding.yaml 파일 ]

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  name: iksoon-crb  # 해당 Cluster Role Binding의 이름

                           # Cluster Role Binding은 metadata부분에 namespace 설정이 없음

subjects:

- kind: ServiceAccount  # 사용자를 설정 [User, Group, ServiceAccout] 가 올 수 있음

  name: iksoon

  namespace: iksoon-ns # ServiceAccount, User는 namespace에 한정되기 때문에 

                               # 어떤 namespace에 속한 service account 인지 명시해야 함

                               # 상위의 kind 가 Group의 경우는 cluster 전체에 사용할 수 있기 때문에
                               # namespace를 명시하지 않음

  apiGroup: ""

roleRef:

  kind: ClusterRole

  name: iksoon-cluster-role

  apiGroup: rbac.authorization.k8s.io

 

 

 


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


 

 

 

 

 

 

참고

 

kubeconfig 사용 이유

https://kin3303.tistory.com/152

 

인증

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/x509/2020/05/02/auth01/

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

 

kubernetes api service 인증 관련

https://kubernetes.io/ko/docs/setup/best-practices/certificates/

 

webhook 인증 참고

https://learnk8s.io/kubernetes-custom-authentication

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

 

webhook 개념

https://smjeon.dev/etc/webhook/

 

LDAP 연동 참고

https://itnext.io/implementing-ldap-authentication-for-kubernetes-732178ec2155

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형

'클라우드 > Kubernetes' 카테고리의 다른 글

15. Kubernetes 인증 ( TLS )  (0) 2020.08.23
14. Kubernetes 인증 ( Basic Authentication )  (0) 2020.08.23
12. Kubernetes Update ( Deployment )  (2) 2020.08.23
11. Kubernetes Secret  (0) 2020.08.17
10. Kubernetes ConfigMap  (0) 2020.08.17