Kubernetes/Certificates

[CKS] Cluster Setup

Operation CWAL 2021. 4. 30. 23:51

Network Policy

Default Deny

default 네임스페이스에 속한 모든 Pod의 트래픽(ingress, egress)을 차단하는 기본 Network Policy를 아래와 같이 정의한다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny
spec:
  podSelector: {}
  policyTypes:
  - Egress
  - Ingress

위 설정은 DNS 서버(ex: coredns)의 접근도 거부되므로, 아래와 같이 DNS 포트는 허용할 수 있다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny
spec:
  podSelector: {}
  policyTypes:
  - Egress
  - Ingress
  egress:
  - to:
    ports:
      - port: 53
        protocol: TCP
      - port: 53
        protocol: UDP

Frontend to Backend

Frontend Pod으로부터 'run=backend' 레이블인 Pod으로만 Egress 트래픽을 허용하도록 다음과 같이 Network Policy를 정의한다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend
spec:
  podSelector:
    matchLabels:
      run: frontend
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          run: backend

마찬가지로 Backend Pod에 대한 Ingress 트래픽을 'run=frontend' 레이블인 Pod에만 허용하도록 다음과 같이 Network Policy를 정의한다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend
spec:
  podSelector:
    matchLabels:
      run: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          run: frontend

Backend to Database in another namespace

Database가 다른 Namespace에 위치한 Pod일 경우, 아래와 같이 'namespaceSelector'를 사용한다. 물론 DB가 위치한 Namespace에는 해당 Label이 존재해야 한다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend
  namespace: default
spec:
  podSelector:
    matchLabels:
      run: backend
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
      - podSelector:
          matchLabels:
            run: frontend
  egress:
    - to:
      - namespaceSelector:
          matchLabels:
            foo: bar

 

다른 Namespace에도 Default Deny 정책이 설정되었다면, 위와 동일한 방식으로 default 네임스페이스에 대한 Network Policy를 정의해야 한다.

GUI Element

K8s Dashboard 설치 

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml

Dashboard UI 접근

kubectl proxy

 

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy 를 통해 Dashboard UI에 접근할 수 있다.

RBAC 설정

Dashboard의 ServiceAccount에 클러스터 리소스에 접근할 수 있는 권한이 없는 상태이므로, 다음과 같이 RBAC 설정을 한다. 기본으로 제공되는 Cluster Role인 'view'를 사용하여 보기 권한만 제공한다.

kubectl create rolebinding -n kubernetes-dashboard k8s-dashboard --serviceaccount kubernetes-dashboard:kubernetes-dashboard --clusterrole view
kubectl create clusterrolebinding -n kubernetes-dashboard k8s-dashboard --serviceaccount kubernetes-dashboard:kubernetes-dashboard --clusterrole view

 

Ingress 보안

Nginx Ingress Controller 생성

Baremetal 환경에서 구축한 K8s 클러스터의 경우 다음과 같이 Nginx Ingress Controller를 추가할 수 있다.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.40.2/deploy/static/provider/baremetal/deploy.yaml

TLS 인증서 설정

K8s에 Nginx Ingress Controller 배포시, 기본적으로 Self-signed TLS 인증서을 포함한다. 사용자가 생성한 TLS 인증서를 적용하기 위해선 다음과 같이 진행한다.

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

CN 필드는 Ingress로 사용할 Domain을 입력한다(ex: my-secure-ingress.com). 그 다음은 TLS 인증서를 바탕으로 K8s Secret을 생성한다.

kubectl create secret tls secure-ingress --cert=cert.pem --key=key.pem

마지막으로 다음과 같은 Ingress를 정의한다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
      - my-secure-ingress.com
    secretName: testsecret-tls
  rules:
  - host: my-secure-ingress.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80

 

curl 명령어를 통해 테스트 가능하다.

curl https://my-secure-ingress.com:<Node Port>/service1 -kv --resolve my-secure-ingress.com:<Node Port>:<Node IP>

 

 

Ingress

FEATURE STATE: Kubernetes v1.19 [stable] An API object that manages external access to the services in a cluster, typically HTTP. Ingress may provide load balancing, SSL termination and name-based virtual hosting. Terminology For clarity, this guide define

kubernetes.io

Node Metadata 보호

Network Policy 설정을 통한 Node Metadata 보호

대부분의 Cloud Provider가 '169.254.169.254'를 통해 현재 인스턴스의 Metadata를 조회할 수 있으며, 이는 Pod 내부에서도 가능하다. 만약 Pod이 해커에 의해 장악되었다면, 해당 Pod을 수행중인 Node의 Metadata 역시 노출되기 때문에 다음과 같이 Network Policy를 정의하여 이러한 문제를 미연에 방지할 수 있다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cloud-metadata-deny
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 169.254.169.254/32

특정 label을 갖는 Pod에서만 Metadata 접근이 가능하도록 설정할 수도 있다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cloud-metadata-allow
spec:
  podSelector:
    matchLabels:
      role: metadata-accessor
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 169.254.169.254/32

 

CIS(Center for Internet Security) Benchmark

K8s 클러스터의 보안 설정 검토를 위한 지침으로 다운로드는 아래 링크 확인(가입 필요)

 

CIS Benchmarks™

CIS Benchmarks help you safeguard systems, software, and networks against today's evolving cyber threats.

www.cisecurity.org

kube-bench

CIS Benchmark를 Programming 방식으로 점검할 수 있는 툴로, Docker를 통해 실행 가능하다.

# run on master
docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t aquasec/kube-bench:latest run --targets=master --version 1.21

# run on worker
docker run --pid=host -v /etc:/etc:ro -v /var:/var:ro -t aquasec/kube-bench:latest run --targets=node --version 1.21

변경해야할 설정에 대해서도 따로 가이드가 이루어진다.

 

Platform Binary 검증

K8s Release 다운로드 및 검증

Github에서 안내하는 K8s 플랫폼 바이너리와 실제 Checksum 값이 동일한지 확인

wget https://dl.k8s.io/v1.19.1/kubernetes-server-linux-amd64.tar.gz
sha512sum kubernetes-server-linux-amd64.tar.gz

 

실행 중인 API 서버의 Binary 파일 검증

다운로드한 플랫폼 바이너리 중 kube-apiserver의 checksum 값이 현재 클러스터에서 실행중인 API 서버와 동일한지 비교할 수 있다.

tar xzf kubernetes-server-linux-amd64.tar.gz
sha512sum kubernetes/server/bin/kube-apiserver
kubectl cp -n kube-system kube-apiserver-master:/usr/local/bin/kube-apiserver ./kube-apiserver
sha512sum kube-apiserver

'Kubernetes > Certificates' 카테고리의 다른 글

[CKS] Runtime Security  (0) 2021.05.08
[CKS] Minimize Microservice Vulnerabilities  (0) 2021.05.03
[CKS] System Hardening  (0) 2021.05.02
[CKS] Cluster Hardening  (0) 2021.05.01
Certified Kubernetes Security Specialist (CKS)  (0) 2021.04.27