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 |