Udemy CKA course 7. Security (보안): Authentication (인증) - 고정 파일, 비대칭 암호와 인증서 (TLS), 인증서 API, KubeConfig

jihyelee·2024년 1월 14일
1

kubernetes

목록 보기
8/15

Certified Kubernetes Administrator (CKA) with Practice Tests (강의 링크, 레퍼런스 노트)

  • 평소 강의 할인도 많이 하고, 연습문제도 풀어볼 수 있으니 실제 강의 수강을 추천
  • 아래는 강의 내용 번역 및 정리본 (문제 시 댓글로 알려주세요)

쿠버네티스 보안 기초요소

  • kube-apiserver를 통해 거의 모든 동작을 수행할 수 있기 때문에 접근을 제한해야 함
  • 누가 접속할 수 있는가
    • 인증 (Authentication)
      • 사용자명 및 비밀번호 (파일)
      • 사용자명 및 토큰 (파일)
      • 인증서
      • 외부 인증 제공 - LDAP
      • 서비스 계정
  • 무엇을 할 수 있는가
    • RBAC 허가 (Authorization)
    • ABAC 허가 (Authorization)
    • Node 허가 (Authorization)
    • Webhook Mode
  • TLS 인증서 (Certificate)
    • ETCD 클러스터, Kube Controller Manager, Kube Scheduler, Kube Proxy, Kubelet 등의 통신은 TLS 암호화로 이루어짐
  • 네트워크 정책
    • 기본적으로 모든 pod는 클러스터 내 모든 pod에 대해 접근 가능 (노드와 상관없이)
    • 네트워크 정책을 통해서 통신을 제한할 수 있음

Authentication (인증)

Account (계정)

  • 계정 종류
    • 사용자 (user): 관리자, 개발자 등
    • 서비스 계정 (service account): 봇 등
  • 쿠버네티스가 직접 사용자 계정을 관리하지는 않음
    • 인증서, 사용자 정보 파일, LDAP 등의 외부 소스 혹은 서비스 활용
    • 사용할 수 없는 명령어
      • kubectl create user [사용자명]
      • kubectl list users
    • 사용할 수 있는 명령어
      • kubectl create serviceaccount [계정명]
      • kubectl get serviceaccount

사용자 계정

  • 모든 사용자 접근은 apiserver에 의해 관리됨
    • kubectl 로 접근
    • curl [경로] 로 접근

인증 메커니즘

  • 고정 비밀번호 파일
    • 비밀번호, 사용자명, 사용자 ID (+ 그룹 ID)를 담은 csv 파일이 있다고 가정
    • 방법 1. kube-apiserver.service 파일에 --basic-auth-file=[csv파일명].csv 추가
      • kube-apiserver 재시작
    • 방법 2. kube-apiserver pod yaml 파일의 command에 --basic-auth-file=[csv파일명].csv 추가
      • kubeadm tool로 쿠버네티스 구성한 경우 사용 가능
      • kube-apiserver가 자동으로 재시작
    • apiserver 접근 시 인증이 필요할 경우, curl -v -k [경로] -u "사용자:비밀번호" 처럼 사용
  • 고정 토큰 파일
    • --token-auth-file=[토큰파일명].csv 추가
    • apiserver 접근 시 curl -v -k [경로] --header "Authorization: Bearer [토큰] 처럼 사용
      • curl 명령어 옵션에 관한 설명은 해당 링크 참고
    • 고정 파일을 이용한 형식은 추천되는 인증 방식은 아님 (insecure)
    • kubeadm 세팅의 경우 volume mount를 고려하는 것이 좋음
  • 인증서
  • 제 3의 인증 프로토콜 (e.g. LDAP)

TLS 배경지식

  • 키를 활용하여 통신을 암호화하여 안전한 송신/수신을 가능케 함
  • 관련하여 처음 학습한다면 해당 동영상 링크 유용

대칭 암호 (symmetric encryption)

  • 암호화 및 복호화에 동일한 키를 사용하는 방식
  • 수신자, 발신자 간 키가 교환되기 때문에 해킹의 위험이 있음

비대칭 암호 (asymmetric encryption)

  • 키의 쌍(pair)을 활용 (개인 키(private key), 공개 키(public key))
  • 하나의 키로 암호화하면 다른 키로 복호화할 수 있음
  • case 1. ssh 목적으로 개인 키, 공개 키 생성
    • ssh-keygen
      • ssh 목적으로 개인 키와 공개 키 생성
    • cat ~/.ssh/authorized_keys
      • authorized keys에 존재하는 공개 키 이외에는 서버로 접근이 불가능하도록 막음
  • case 2. 클라이언트와 서버 통신 시 서버에서 개인 키, 공개 키 생성
    • openssl genrsa -out [개인키명].key 1024
      • 서버의 개인 키 생성
    • openssl rsa -in [개인키명].key -pubout > [공개키명].[pem]
      • 서버의 공개 키 생성
    • 사용자가 https로 서버에 접근할 경우 서버로부터 서버의 공개 키를 얻게 됨
      • 해커의 서버가 아니라 제대로 된 서버임을 알기 위해 공개 키는 인증서와 함께 이동
        • e.g. 사용자가 검색한 url과 일치하는지
      • 인증서는 생성 시 서명이 되는데, 이를 통해 합법적인 인증서인지 확인 가능
        • 서명을 생성하고 인증하는 CA (Certificate Authority) 존재
    • 서버의 공개 키를 사용해 사용자가 자신의 개인 키(symmetric)를 암호화, 이를 서버로 보냄
    • 서버는 자신의 개인 키(asymmetric)를 사용해 사용자의 개인 키(symmetric)를 복호화
      • 서버의 개인 키와 사용자의 개인 키가 다름에 주의

PKI (Public Key Infrastructure)

  • 인증서를 생성하고, 배포하고, 유지하는 CA를 포함한 이러한 과정을 일컫는 용어
  • 공개 키 혹은 인증서는 일반적으로 .crt, .pem으로 이름이 붙음
  • 개인 키는 일반적으로 .key, -key.pem으로 이름이 붙음

CA (Certificate Authority)

  • 서명을 생성하고 인증하는 기관
    • e.g. Symantec, GlobalSign, digicert, ...
  • 인증서 서명 절차
      1. CSR (Certificate Signing Requiest) 생성
      • openssl req -new -key [개인키명].key -out [이름].csr -subj "/C=US/ST=CA/O=MyOrg,Inc./CN=mydomain.com"
      1. CA에서 정보 인증
      1. 서명 및 인증서 송부
  • CA의 진위여부 판별
    • 모든 CA는 각자의 개인 키와 공개 키를 가지고 있음
    • CA들의 공개 키는 모두 브라우저에 빌트인 되어있음

쿠버네티스에서의 인증서

  • 인증서 종류
    • Root Certificate: CA 소유
    • Client Certificate: 사용자 소유
    • Server Certificate: 서버 소유
  • 쿠버네티스 내 모든 통신은 안전해야 함
    • 쿠버네티스는 마스터 노드와 워커 노드로 이루어져 있음
      • 서버를 위한 Server Certificate 필요
    • 쿠버네티스의 관리자는 kubectl 유틸리티를 활용하거나 직접 apiserver에 접근 가능
      • 사용자를 위한 Client Certificate 필요

서버

  • kube-apiserver
    • apiserver.crt, apiserver.key 필요
    • 인증서와 개인 키의 이름은 달라질 수 있음
  • ETCD server
    • etcdserver.crt, etcdserver.key 필요
  • kubelet server
    • 워커노드의 kubelet 또한 https API 엔드포인트를 노출, apiserver와 소통할 수 있음
    • kubelet.crt, kubelet.key 필요

클라이언트

  • 관리자
    • kubectl REST API를 통해 kube-apiserver와 소통
    • admin.crt, admin.key 필요
  • kube-scheduler
    • apiserver와 통신하면서 스케줄링이 필요한 pod를 찾고 apiserver로 하여금 pod를 알맞은 노드에 스케줄되게 함
    • scheduler.crt, scheduler.key 필요
  • kube-controller-manager
    • 마찬가지로 apiserver와 통신
    • controller-manager.crt, controller-manager.key 필요
  • kube-proxy
    • kube-apiserver를 인증하기 위해 필요
    • kube-proxy.crt, kube-proxy.key
  • kube-apiserver
    • ETCD 서버와 통신할 때, kube-apiserver는 client의 역할
    • kubelet 서버와 통신할 때, kube-apiserver는 client의 역할이 되기도 하고 반대로 server의 역할이 되기도 함 (이럴 경우 kubelet이 client)
    • 서버 인증서로 사용했던 인증서와 개인 키를 그대로 사용하거나, 새로운 쌍을 만들어 사용할 수도 있음

CA

  • 클러스터 내 최소 1개의 CA 필요 (1개 이상 가능)
  • ca.crt, ca.key 필요

쿠버네티스에서 인증서 생성

  • EASYRSA, OPENSSL, CFSSL 등을 사용해 생성 가능

CA

    1. openssl genrsa -out ca.key
    • 개인 키 생성
    1. openssl req -new -key ca.key -subj "/CN=KUBERNETES-CA" -out ca.csr
    • 인증서 서명 요청 (Certificate Signing Request) 생성
    • 모든 세부 정보를 담은 인증서와 유사하나 서명이 없다는 차이 존재
    • CN은 Common Name의 약자로, 인증서를 사용할 요소의 이름을 특정하는 부분
    1. openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
    • 앞서 생성한 CA의 개인 키를 활용해 인증서 서명
  • CA의 root certificate는 모든 클라이언트와 서버에 복사되어 존재
    • admin, kube-scheduler, kube-controller-manager, kube-proxy, kube-apiserver, etcd server, kubelet server, ...
    • e.g. yaml 파일의 --trusted-ca-file=...

클라이언트

관리자 클라이언트

    1. openssl genrsa -out admin.key
    1. openssl req -new -key admin.key -subj "/CN=kube-admin/O=system:masters" -out admin.csr
    • 관리자를 일반 사용자와 구분하기 위해서는 인증서에 그룹 정보를 포함하는 방법이 있음
    • e.g. CSR에 그룹 정보 (/O=system:masters) 포함
    1. openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -out admin.crt
    • CA와 다른 점은 CA의 인증서와 개인 키를 사용했다는 점

kube-scheduler, kube-controller-manager

  • controlplane의 요소인 시스템
  • 이름에 SYSTEM:이라는 키워드를 붙여줘야 함 (prefix)
    • e.g. SYSTEM:KUBE-SCHEDULER
  • 클라이언트 인증서 및 개인 키 사용 방법
      1. REST API 호출 시 사용자명, 비밀번호 대신 옵션으로 전달
      • curl https://kube-apiserver:6443/api/v1/pods --key admin.key --cert admin.crt --cacert ca.crt
      1. 인증서 및 개인 키 정보를 KubeConfig 파일로 관리 및 사용

서버

ETCD 서버

  • etcd-server는 여러 개의 서버에 걸친 클러스터의 형태로 배포될 수 있음
  • 클러스터 내 다른 멤버들의 안전한 통신을 위해 peer certificate를 추가적으로 생성
    • e.g. --peer-cert-file= 등의 정보를 etcd.yaml이 가지고 있어야 함

kube-apiserver

  • 거의 모든 요소들과 소통하기 때문에 여러 가지 이름으로 불리곤 함
    • e.g. kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local, IP 주소 등
  • 해당 정보들이 모두 인증서에 작성되어야 함
    1. openssl genrsa -out apiserver.key 2048
    1. openssl req -new -key apiserver.key -subj "/CN=kube-apiserver" -out apiserver.csr -config openssl.cnf
    • openssl.cnf 파일에 이름들을 모두 작성해 config로 넘김
    • e.g. DNS_1 = kubernetes, DNS_2 = kubernetes.default, ...
    1. openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -out apiserver.crt
  • --client-ca-file을 통해 CA 인증서 제공
  • --tls-cert-file, --tls-private-key-file을 통해 서버 인증서 및 키 정보 제공
  • --etcd-cafile, --etcd-certfile, --etcd-keyfile 등을 통해 ETCD와 소통할 때 클라이언트 인증서 및 키 정보를 제공
  • --kubelet-certificate-authority, --kubelet-client-certificate, --kubelet-client-key 등을 통해 Kubelet과 소통할 때 클라이언트 인증서 및 키 정보를 제공

kubelet

  • 클러스터의 각 노드마다 인증서 및 키 정보 존재
    • kubelet 인증서의 이름은 노드의 이름을 따라감
    • e.g. 서버일 경우 node01, 클라이언트일 경우 system:node:node01
    • 클라이언트일 경우 그룹 정보를 인증서에 포함해야 함 (e.g. SYSTEM:NODES)
  • KubeletConfiguration 파일로 인증서, 키 관리
    • authentication: x509: clientCAFile: 이용해 CA 인증서 관리
    • tlsCertFile, tlsPrivateKeyFile: 이용해 서버 인증서 및 키 관리

인증서 확인

  • 인증서 위치 확인
    • kubeadm을 활용해 클러스터 구성했을 때
      • /etc/kubernetes/manifests/kube-apiserver.yaml
    • 처음부터 직접 클러스터 구성했을 때
      • /etc/systemd/system/kube-apiserver.service
  • 인증서 보기
    • openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout
    • 이름(CN), 별명(Alternative Name), 만료일자(Validity), 발행자(Issuer) 등 확인 가능
  • 서비스 로그 확인
    • kubeadm을 활용해 클러스터 구성했을 때
      • kubeadm logs [pod명]
      • kubeadm이 제대로 작동하지 않을 때
        • docker logs [컨테이너ID] 혹은 crictl logs [컨테이너ID]
    • 처음부터 직접 클러스터 구성했을 때
      • journalctl -u etcd.service -l
      • journalctl은 systemd의 서비스 로그 확인 명령어 (참고 링크)

인증서 API

  • 쿠버네티스에서 CA는 우리가 생성한 키와 인증서의 쌍을 의미
    • 해당 파일에 접근할 수 있다면 누구나 인증서에 서명을 받을 수 있음
    • 이를 막기 위해, CA 서버라는 안전한 환경에 CA 키와 인증서가 존재해야 함
    • 쿠버네티스에서는 마스터 노드에 CA 키와 인증서 저장
  • 쿠버네티스는 빌트인 인증서 API를 가짐
    • 마스터 노드에 로그인해 수동으로 서명을 받는 게 아니라, API 호출을 통해 인증서 서명이 이루어짐
    • 자동으로 인증서 및 인증서 서명 요청 관리 + 유효기간 만료 시 인증서 변경

인증서 서명 관련 명령어

    1. 사용자가 개인 키와 CSR 생성하여 관리자에게 전송
    • openssl genrsa -out jane.key 2048
    • openssl req -new -key jane.key -subj "/CN=jane" -out jane.csr
    1. 관리자가 CertificateSigningRequest 객체 생성
    • apiVersion: certificates.k8s.io/v1
    • kind: CertificationSigningRequest
    • metadata:
      • name: jane
    • spec:
      • expirationSeconds: 600
      • usages:
        • -digital signature
        • -key encipherment
        • -server auth
      • request:
        • cat jane.csr | base64 | tr -d "\n" 혹은 cat jane.csr | base64 -w 0 등을 통해 인코딩된 텍스트
    1. 요청 리뷰 및 승인 (kubectl 이용)
    • kubectl get csr
    • kubectl certificate approve jane : 승인
    • kubectl certificate deny jane : 거절
    • controller-manager에서 인증서 관련 동작을 담당
      • csr-approving, csr-signing 등 존재
      • yaml 파일에 --cluster-signing-cert-file, --cluster-sigining-key-file
    1. 사용자에게 인증서 공유
    • kubectl get csr jane -o yaml
      • yaml 파일 형식으로 csr 확인
    • echo [status:certificate 하위 인코딩 텍스트] | base64 --decode

KubeConfig

  • 명령어를 사용할 때 인증서 정보를 항상 작성하는 것은 번거로움
  • KubeConfig 파일을 활용하는 것이 편리
      1. 명령어에 --kubeconfig config 추가
      • kubectl get pods --kubeconfig config
      1. $HOME/.kube/config 경로에 저장
      • kubectl get pods 만 작성해도 됨
  • 객체를 별도로 만들 필요 없이 파일만 있으면 됨

KubeConfig 파일 구성요소

  • 섹션 1. 클러스터
    • e.g. 개발환경, 운영환경, 테스트환경, 타조직(Google), ...
    • 명령어에서 --server, --certificate-authority (서버 사양) 관련 부분이 여기에 포함
  • 섹션 2. 사용자
    • e.g. 관리자, 개발환경 사용자, 운영환경 사용자, ...
    • 클러스터마다 다른 권리(priviledge)를 가질 수 있음
    • 명령어에서 --client, client-certificate (클라이언트 사양) 관련 부분이 여기에 포함
  • 섹션 3. 컨텍스트
    • 어떤 사용자 계정이 어떤 클러스터를 접속하는데 사용될 지를 결정
    • e.g. Admin@Production, Dev@Google, ...

KubeConfig Yaml 예시

  • apiVersion: v1
  • kind: Config
  • current-context: dev-user@google
  • clusters: array 형식
    • -name: my-kube-playground
    • cluster:
      • certificate-authority: /etc/kubernetes/pki/ca.crt
      • (혹은 certificate-authority-data: 인코딩된 파일 내용)
      • server: https://my-kube-playground:6443
    • -name: google (하위 변수 생략)
  • contexts:
    • -name: my-kube-admin@my-kube-playground
    • context:
      • cluster: my-kube-playground
      • user: my-kube-admin
      • namespace: finance
    • -name: dev-user@google (하위 변수 생략)
  • users:
    • -name: my-kube-admin
    • user:
      • client-certificate: admin.crt
      • client-key: admin.key
    • -name: dev-user (하위 변수 생략)

관련 명령어

  • kubectl config view
    • 사용되고 있는 config 확인 (기본 파일)
  • kubectl config view --kubeconfig=[config명]
    • 확인하고자 하는 config 명시 및 확인
  • kubectl config use-context [context명]
    • 기본 컨텍스트 변경
    • 실제로 파일 내 current-context 내용이 변경됨
    • 컨텍스트가 변경될 때 namespace가 달라진다면 namespace도 자동으로 변경됨
  • cat [파일경로] | base64
    • 파일내용 인코딩
  • echo "[인코딩된 내용]" | base64 --decode
    • 인코딩된 내용 디코딩
profile
Graduate student at Seoul National University, majoring in Artificial Intelligence (NLP). Currently AI Researcher at LG CNS AI Lab

2개의 댓글

comment-user-thumbnail
2024년 7월 22일

cka 자격증 준비중이고, udemy에서 현재 security부분 듣고 있는데요
시험에서 해당 영역도 나올까요?
이 부분 좀 어렵고 길고 해서 시험에 해당 하는 영역이 아니면 가볍게 듣고 넘기고 싶어서요 ㅠㅠ

1개의 답글