이쿠의 슬기로운 개발생활

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

Kubernetes/Kubernetes 보안

Kubernetes 인증 ( Webhook )

이쿠우우 2020. 8. 29. 16:39
반응형

Kubernetes Webhook 인증

 

 


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 )


 

 

참고) 환경

 

Webhook Server

 OS = CentOS 7

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

 

Master Node server

 OS = CentOS 7

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

 docker version : 1.13.1

 api verison : 1.26

 

Worker Node server

 OS = CentOS 7

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

 docker version : 1.13.1

 api verison : 1.26

 

Kubernetes version

 1.18

 


 

 

 

Webhook 서버 구축 후 kubernetes 인증 연동

 

 

[목표]

테스트 용도로 인증 결과를 무조건 True 로 리턴하는 Webhook 을 구성하고

해당 Webhook 과 Kubernetes 를 연동하는 형태로

kubernetes 인증 서버를 구성.

 

 

 

 

 

 

 


 

 

1. Webhook 인증 서버 구축을 위해 python 설치 및 flask 패키지 설치

(WebHook 인증 서버를 구축할 서버에서 작업)

 

CentOS7은 기본적으로 Python 2.7.5 version 이 설치되어 있음

 

[Python 3.8 version 으로 변경하는 작업 진행]

 

 

1.1. 먼저 python 설치 시 필요한 tool 설치

yum install -y gcc openssl-devel bzip2-devel libffi-devel wget

yum update

 

1.2. python 최신버전 설치

wget https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tgz   

tar xvf Python-3.8.5.tgz

cd Python-3.8.5/

./configure --enable-optimizations

make altinstall

 

1.3. python 3.8을 main 으로 쓸 수 있도록 링크 작업 진행

ls -l /bin/python*

unlink /bin/python

ln -s /usr/local/bin/python3.8 /bin/python

 

1.4. pip 명령으로 flask 패키지 설치

python3.8을 설치해서 pip3.8 명령으로 pip 를 사용해야함

명령어 : pip3.8 install flask

 

참고) flask 란

플라스크(Flask)는 아주 가벼운 마이크로(Micro) 서버 프레임워크.

마이크로라는 이름에 걸맞게 아주 작고 가벼우며, 빠르게 동작. 

Flask는 서버 프레임워크에 필요한 핵심 기능만 제공하고, 

나머지는 개발자가 직접 개발하거나 다른 패키지로 확장시켜서 사용되도록 유연하게 설계되어있음

 

 

 


 

 

 

2. Webhook 인증 서버 구축

(WebHook 인증 서버를 구축할 서버에서 작업)

 

iksoon-webhook.py (무조건 인증통과되게 하는 코드)

import pprint
from flask import Flask, request, jsonify


app = Flask(__name__)


@app.route('/', methods=['POST'])
def auth():
        # API 서버로부터 TokenReview 수신
        tokenReview = request.json


        # 인증 결과 (하드코딩)
        status = {}
        status['authenticated'] = True
        status['user'] = {
                'username': 'iksoon',
                'uid': 'iksoon',
                'groups': ['system:masters'] # group 설정을 'system:masters'로 설정하면 해당 user에게 관리자 권한을 부여함
                 # group 설정을 공백 or 설정하지 않으면 해당 username과 동일한 rolebinding 권한을 부여함
        }


        # TokenReview에 인증결과 객체 삽입
        tokenReview['status'] = status
        pprint.pprint(tokenReview)


        # API 서버로 json 응답
        return jsonify(tokenReview)




if __name__ == '__main__':
        app.run(host= '0.0.0.0', port=6000, debug=True)

 

서버 실행 :  python iksoon-webhook.py

결과 : 정상 실행됨

 

 

 


 

 

 

3. Kubernetes Webhook 인증 설정 작업

(Kubernetes Master Node 에서 작업)

 

kubernetes 가 webhook 서버에 연결하기 위해 webhook server 의 정보를 설정해야함

설정 방법은 kubeconfig 파일(/etc/kubernetes/admin.conf)의 형식과 동일함

해당 설정을 kube-apiserver 가 가져감

 

[참고]

webhook server ip : 10.0.2.5

 

[/etc/kubernetes/pki/webhook.yaml 파일 생성]

apiVersion: v1
kind: Config
clusters:
- cluster:
    insecure-skip-tls-verify: true
    server: http://10.0.2.5:6000  # WebHook server의 주소를 명시함
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kube-apiserver
  name: iksoon-test@kubernetes
current-context: iksoon-test@kubernetes
users:
- name: kube-apiserver

 

/etc/kubernetes/manifests 경로의  kube-apiserver.yaml 파일 설정 추가

 

[설정]

--authentication-token-webhook-config-file=[상위에서 생성한 webhook 설정 yaml 파일 경로]

예) --authentication-token-webhook-config-file=/etc/kubernetes/pki/webhook.yaml

 

추가 후  적용 명령어 : kubeadm init --config kube-apiserver.yaml

 

 

 

 

 

 

 

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

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

 

kubectl 을 사용할 client kubeconfig 파일 환경변수 설정 작업 진행

export KUBECONFIG="kubeconfig 파일 경로"

 

 

[kubeconfig.conf 파일 예시]

apiVersion: v1
kind: Config
clusters:
- cluster:
    insecure-skip-tls-verify: true
    certificate-authority-data:
    server: https://10.0.2.15:6443  # kubernetes master node 주소: apiserver 접근 포트
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: iksoon
  name: iksoon-test@kubernetes
current-context: iksoon-test@kubernetes
preferences: {}
users:
- name: iksoon
  user:
    token: test

 

kubeconfig.conf 로  KUBECONFIG 환경변수가 설정되어 있어서

kubectl 명령하면 default 로 KUBECONFIG 경로를 참조해서 동작함

 

 

 

 


 

 

5. 결과 확인

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

 

client 에서 kubectl 명령 실행 결과

 

[결과 정상]

현재 kubernetes default namespace 에서 생성된 pod 가 없기 때문에 아래와 같이 나옴

 

만약 인증에 실패했을경우 아래와 같은 결과가 나옴

 

[결과 성공 시 webhook flask server log 상태]

아래와 같이 flask 코드에서 무조건 성공으로 리턴하는 data를 확인할 수 있음

해당 예시는 단순 webhook server test이기 때문에

인증의 과정은 없이 없어서 무조건 인증 성공으로 리턴했음

 

 

 


 

 

 

 

6. (참고) Kubernetes Webhook 인증 RBAC 연동

(Kubernetes Master Node 에서 작업)

 

iksoon-webhook.py (무조건 인증통과되게 하는 코드) 

(group : ['system:masters'] 를 주석처리하고 RBAC 권한을 부여하는법)

import pprint
from flask import Flask, request, jsonify


app = Flask(__name__)


@app.route('/', methods=['POST'])
def auth():
        # API 서버로부터 TokenReview 수신
        tokenReview = request.json


        # 인증 결과 (하드코딩)
        status = {}
        status['authenticated'] = True
        status['user'] = {
                'username': 'iksoon',
                'uid': 'iksoon',
           #'groups': ['system:masters'] # group 설정을 'system:masters'로 설정하면 해당 user에게 관리자 권한을 부여함
           # group 설정을 공백 or 설정하지 않으면 해당 username과 동일한 rolebinding 권한을 부여함
        }


        # TokenReview에 인증결과 객체 삽입
        tokenReview['status'] = status
        pprint.pprint(tokenReview)


        # API 서버로 json 응답
        return jsonify(tokenReview)




if __name__ == '__main__':
        app.run(host= '0.0.0.0', port=6000, debug=True)

 

위와같이 webhook server 를 실행 시킨 후

status['user'] = {
                'username': 'iksoon',
                'uid': 'iksoon',

 

 

부분과 동일한 username 으로 role, rolebinding 설정하면 

해당 user에 RBAC 권한을 부여할 수 있음

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: iksoon-rb
  namespace: iksoon-ns
subjects:
- kind: User
  name: iksoon   # 상위 status['user'] 의 username 과 동일하게 설정
  namespace : iksoon-ns 
roleRef:
  kind: Role
  name: iksoon-role  # RoleBinding 에 적용될 Role name을 넣어줌
  apiGroup: rbac.authorization.k8s.io

 

 

 

 

 

 

 


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


 

 

 

 

 

참고

인증

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/webhook/2020/05/05/auth04/

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형