Kubernetes - (7) Security

임쿠쿠·2022년 5월 21일
0

kubernetes

목록 보기
7/8
post-thumbnail

1. Kubernetes Security Primitives

  • kube api sever는 모든 운영의 중심이므로 API server에 대한 Controlling Access 필요

1) Authentication

  • Username and Password
  • Username and Tokens
  • Certificates
  • External Authentication providers - LDAP

2) Authorization

  • RBAC(Role Based Access Control) Authorization
  • ABAC(Attribute Based Access Control) Authorization
  • Node Authorization
  • Webhook Mode

3) TLS Encryption

  • API Server, Kubelet, ETCD 등 모든 커뮤니케이션은 TLS 진행

4) Network Policies

  • 같은 cluster 내 POD은 다른 POD에 기본적으로 접근 할 수 있으므로, Network Policies로 이를 제한 가능

2. Authentication

  • 쿠버네티스는 user account 생성을 지원하지 않으므로 외부 자원에 의존함 단, service account는 생성 가능

1) Username and Password

  • kubectl or curl을 통한 직접 접근 시, 외부 account 파일을 kube-apiserver.service에 저장 및 kube-apiserver.yaml 수정

2) Username and Tokens

  • staticFile 생성 후, Bearer Token으로 접속 가능

3. TLS In Kubernetes

  • user가 쿠버네티스 클러스터와 통신 시 TLS 커넥션 유지 필요
  • Client Certifictes : 클라이언트 측 Certificates
  • Server Certificates: 서버 측 Certificates
  • Root Cetificates: public, private key pair를 소유하고 있고 해당 키는 cetificate를 사인하는데 사용된다.

1) Kube-API server

  • Server: User, Kube-Scheduler, Kube-Controller-Manager, Kube-Proxy, Kubelet의 대상
  • Client: Kubelet, ETCD Server로 요청

2) Kube-API server

  • Server: Kube-API server의 대상
  • Client: Kube-API server로 요청

3) ETCD server

  • Server: Kube-API server의 대상

4) Practice

Kube-api server certificate file 확인

cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -i tls-cert-file

Kube-api server의 ETCD client 측 certificate file 확인

cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -i etcd-certfile 

Kube-api server의 Kublet client 측 key 확인

cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -i kubelet

ETCD server의 certificate file 확인

cat /etc/kubernetes/manifests/etcd.yaml | grep -i cert-file

ETCD server의 Root certificate file 확인

cat /etc/kubernetes/manifests/etcd.yaml | grep -i trusted-ca-file

ETCD server의 Root certificate file 확인

cat /etc/kubernetes/manifests/etcd.yaml | grep -i trusted-ca-file

Kube-api server Certificate Common Name 확인

openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text | grep -i Subject

ETCD server Certificate Common Name 확인

openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -text

4. Certificates API

  • 다수의 사용자가 있을 시, admin을 제외한 다른 사용자는 certificate와 private key를 admin에게 전달하여 인증 작업을 진행하는 단점 발생
  • certificate 유지 및 만료 등의 자동화된 관리 필요, Certificate API를 통해 타 사용자는 쿠버네티스에 다이렉트로 certificate signing request 가능
  • certificate related operation은 Controller manger에 의해 수행된다.

1) Create CertificateSingingRequest Object

openssl genrsa -out test.key 2048
oppenssl req -new -key test.key -subj "/CN=test" -out test.csr
  • 유저는 key를 생성하고 이를 administrator는 전송
  • administrator는 key를 받은 후, certificateSingingRequest Object를 manifest file로 생성
cat test.csr | base64 | tr -d "\n"
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: akshay
spec:
  groups:
  - system:authenticated
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFV(중략...) - base 64인코딩 필요
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth
kubectl apply -f 파일명.yaml
  • 중요) manifest file 생성 시, request 항목에는 base64로 인코딩

2) Review Requests

kubectl get csr
kubectl get csr test -o yaml
// echo TEXT | base64 --decode ~ certificate 디코딩

3) Approve Requests

kubectl certificate approve csr명
kubectl certificate deny csr명
kubectl delete csr csr명

4) Share Certs to Users

5. KubeConfig

  • 위와 같이 key, ca 등의 조회 시, 하나씩 타이핑 필요하므로 이를 config로 전환
  • config는 기본적으로 /.kube/config를 path로 지정

1) kubeConfig File 구성 요소

(1) Clusters : dev, Prod, test등의 멀티 클러스트
(2) Users : 클러스터에 접근하는 User로 각각 다른 권한 소유
(3) Contexts : 어떤 User가 특정 Cluster에 접근할 건지 정의

2) Kubectl Config

// config File 조회
kubectl config view
// default config File외 조회
kubectl config view --kubeconfig CONFIG파일명
// 현재 context 설정 조회
kubectl config --kubeconfig=PATH current-context
ex) kubectl config --kubeconfig=/root/my-kube-config current-context
// context 스위칭
kubectl config --kubeconfig=PATH use-context CONTEXT명
ex) kubectl config --kubeconfig=/root/my-kube-config use-context research
// default config 변경
cp 변경할 CONFIG 파일 ~/.kube/config
ex) cp /root/my-kube-config ~/.kube/config

API Groups

  • API server와 연결 시, api(core Group) / apis(named Group)로 나누어진다.
  • kubectl proxy !== kube proxy ~ kubectl proxy는 kubectl로 API sever와 연결 시 사용하는 HTTP proxy이다.

6. Authorization

  • Admin외 User가 클러스터 접근할 수 있게 했을때, 수정 및 삭제와 같은 작업은 방지하기 위해 Authorization 필요
// authorization mode 확인
kubectl describe pod kube-apiserver-controlplane -n kube-system | grep -i authorization

1) ABAC(attribute based access control)

// Role 생성
kubectl create role Role명 --namespace=Namespace명 --verb=권한 --resource=resource명
ex) kubectl create role developer --namespace=default --verb=list,create,delete --resource=pods
// RoleBinding 생성
kubectl create rolebinding RoleBinding명 --namespace=Namespace명 --role=Role명 --user=User명
ex) kubectl create rolebinding dev-user-binding --namespace=default --role=developer --user=dev-user
  • policy file 생성 후 JSON 포맷으로 정책 설정
  • 유저별 policy file 생성 필요하므로 비효율적임

2) RBAC(role based access control)

  • role 생성 후 이를 유저별 연결

(1) role definition file 생성

Role 생성

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: developer
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["list", "create","delete"]

RoleBinding 생성

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dev-user-binding
subjects:
- kind: User
  name: dev-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer
  apiGroup: rbac.authorization.k8s.io

(2) user-role binding

  • 같은 namespace여야 하며, 다른 namespace를 적용하려면 metadata에 namespace 명시해야한다.

(3) view RBAC

kubectl get roles
kubectl get roles --all-namespaces // 모든 네임스페이스 role 조회
kubectl get rolebindings
kubectl describe role role명 // role 상세정보
kubectl describe role role명 -n namespace명 
kubectl describe rolebinding rolebinding명 // role binding 상세정보
kubectl describe rolebinding rolebinding명 -n namespace명
kubectl edit role Role명 -n Namespace명 // role 수정 

(4) Check Access

kubectl auth can-i create deployments // 접속한 유저가 create deploy 권한있는지 체크
kubectl auth can-i create deployments --as dev-user // dev-user가 create deploy 권한있는지 체크
kubectl auth can-i create deployments --as dev-user --namespace namespace명 // dev-user가 해당 namespace에서 create deploy 권한있는지 체크

3) Cluster Roles and Role Bindings

  • Cluster의 리소스에 대한 Role 및 RoleBinding 생성
  • 기존 Role은 특정 네임스페이스의 리소스에만 Role을 부여했지만, Cluster Role을 통해 클러스터 내 모든 리소스에 Role 부여
kubectl get clusterroles // clusterRole 조회
kubectl get clusterroles --no-headers | wc -l // 갯수 조회
kubectl get clusterrolebindings // clusterRoleBindings 조회

ClusterRole & ClusterRoleBinding 생성

// Node
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: node-admin
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "watch", "list", "create", "delete"]

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: michelle-binding
subjects:
- kind: User
  name: michelle
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: node-admin
  apiGroup: rbac.authorization.k8s.io
// Storage
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: storage-admin
rules:
- apiGroups: [""]
  resources: ["persistentvolumes"]
  verbs: ["get", "watch", "list", "create", "delete"]
- apiGroups: ["storage.k8s.io"]
  resources: ["storageclasses"]
  verbs: ["get", "watch", "list", "create", "delete"]

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: michelle-storage-admin
subjects:
- kind: User
  name: michelle
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: storage-admin
  apiGroup: rbac.authorization.k8s.io

7. Service Account

  • service account는 애플리케이션과 쿠버네티스 클러스터간의 상호작용 시 사용
    ex) kube API server에 요청을 보내는 애플리케이션의 경우 service account 필요

  • 애플리케이션이 쿠버네티스 내에서 운영되면 자동으로 default service account가 해당 POD에 마운트 되므로 수동으로 설정할 필요 없음

// service account 생성
kubectl create serviceaccount SERVICEACCOUNT명
  • service account 생성 시, 자동적으로 토큰이 생성되고 해당 토큰은 외부 애플리케이션이 쿠버네티스 api 인증 시 사용
// service account 조회
kubectl get serviceaccounts
// Pod이 어떤 service account 사용하고 있는지 조회
kubectl get pod -o yaml
// mount된 credential path 조회
kubectl describe pod POD명 ~ Mounts 참조
// service account 상세정보 조회
kubectl describe serviceaccount SERVICEACCOUNT명

// Tokens에 secret Object 정보를 알 수 있고, 아래 명령어로 상세 정보 조회
kubectl describe secret SECRETOBJECT명
  • secret 조회를 통해 해당 토큰을 Bearer 적용 가능
  • 생성한 serviceaccount를 yaml파일 spec에 serviceAccountName에 적용 가능

8. Image Security

  • 도커의 이미지가 private repository에 있을 시, secret을 생성하고 이를 definition file에 적용한다

(1) docker-registry SECRET 생성

// 도커 레포 SECRET 생성
kubectl create secret docker-registry SECRET명
--docker-username=USERNAME 
--docker-password=PASSWORD
--docker-server=PRIVATEREPO 
--docker-email=EMAIL

(2) docker-registry SECRET 적용

  • image에 priviate repo 추가
  • imagePullSecrets에 해당 docker-registry SECRET 적용

9. Network Security

  • 쿠버네티스의 클러스터 내 여러 Node의 여러 POD은 virtual private network에 속해있으며 Node1의 POD1은 Node2의 POD2와 IP, POD name, service를 통해 연결할 수 있다.
  • 기본적으로 클러스터 내 트래픽 은 All Allow다.

1) Network Policy

  • 쿠버네티스는 기본적으로 클러스터 내 여러 POD 간의 트래픽 전달 가능하기 때문에 자칫 front-server가 db-server에 직접 접근할 수 있는데 이를 막는 방법이 Network policy다.
  • Network policy는 쿠버네티스 namespace의 objcet다. 해당 규칙을 POD에 적용하여 ingress 트래픽에 대한 제한

2) Network Policy Type

(1) Ingress : 해당 POD으로 들어오는 요청에 대한 규칙, ingress 요청 수락 시 응답은 자동적으로 허락 ex) API server => DB Server

(2) Egress : 해당 POD에서 다른 POD으로 데이터 전달 ex) DB server => Backup Server

3) Practice

// network policy 조회
kubectl get netpol
// network policy type조회
kubectl describe netpol NETPOL명

Network Policy에 연결된 POD 조회

kubectl get netpol // 조회 후, Selector를 토대로 POD labes 조회
kubectl get po --show-labels
profile
Pay it forward

0개의 댓글