AWS EKS 보안

AWS EKS 보안 관련 정보를 알아봅니다. EKS 보안을 설정, 관리하는 방법을 소개합니다. 클러스터 보안, 노드 보안, 파드보안, 네트워크 보안 등을 설명합니다.

AWS EKS 클러스터 보안

인증

# kubeconfig 자동 설정
aws eks update-kubeconfig --name <클러스터 이름>

인가

  • kubectl로 접속한 요청이 정상적으로 인증된 후에 요청한 조작이 허가를 받은 것인지 점검합니다.
  • Role-Based Access Control 기능을 이용합니다.
  • 롤과 롤바인딩이라는 쿠버네티스 오브젝트를 사용하여 설정합니다.
  • 롤 오브젝트 : 어떤 조작을 허가할 것인가라는 권한셋과 같은 것을 정의합니다.
  • 롤바인딩 오브젝트 : 어떤 사용자에게 어떤 롤을 부여할 것인지 정의합니다.
  • aws-auth라는 이름의 컨피그맵 안에 AWS CLI 인증 정보로 설정한 IAM 사용자, IAM 역할의 Amazon 리소스 이름, 쿠버네티스 오브젝트로 그룹을 연결해놓고 롤바인딩으로 그 그룹과 롤을 연결시키는 것으로 구현합니다.
# 롤과 롤바인딩 생성
kubectl apply -f security/rbac.yaml
  • rbac.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: rbac-test-ns
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rbac-test-role
rules:
  # 허가할 조작을 설정
  - apiGroups: ["extensions", "apps", ""]
    resources: ["pods","pods/log","deployments","replicasets","services"]
    verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rbac-test-role-binding
  # 대상 네임스페이스만 조작 허가
  namespace: rbac-test-ns
roleRef:
  kind: ClusterRole
  name: rbac-test-role # ClusterRole명을 지정
  apiGroup: rbac.authorization.k8s.io
subjects:
  - kind: Group
    name: rbac-test-group # 허가할 그룹을 지정
    apiGroup: rbac.authorization.k8s.io

eksctl create iamidentitymapping \\
–region ap-northeast-2 \\
–cluster eks-work-cluster \\
–username rbacTest
# 새로 만든 IAM 사용자 이름 –group rbac-test-group
# 롤바인딩에서 지정한 그룹 이름 –arn <IAM 사용자의 ARN>
# 새로 생성한 IAM 사용자와 IAM 역할의 ARN

# 사용자 정보 변경
aws configure

# 기존에 사용하던 eks-work 네임스페이스로 변경
kubectl config use-context eks-work

# 기본 네임스페이스의 파드, 디플로이먼트, 서비스를 참조할 수 없음
kubectl get pod,deployment,replicast,service

# rbac-test-ns 네임스페이스의 파드, 디플로이먼트, 서비스는 참조 가능
kubectl get pod,deployment,replicast,service -n rbac-test-ns

# 네임스페이스 ‘default’에 리소스 추가는 허가되지 않음
kubectl create deployment tnginx-test –image=nginx:latest

# 네임스페이스 ‘rbac-test-ns’에 리소스 추가도 허가되지 않음
kubectl create deployment tnginx-test –image=nginx:latest -n rbac-test-ns

노드 보안

파드에 부여하는 호스트 권한 제어

  • Pod Security Policy : 악의가 있는 사용자가 노드상의 중요한 파일을 변경할 수 있고 노드상의 특수 권한을 이용해 나쁜 행위를 할 수도 있는 위험성을 해결.
  • 특정 사용자에게만 권한 제어를 적용할 경우
  • Pod Security Policy, 파드 보안 정책
# 기본 파드 시큐리티 폴리시는 아무 제한도 걸려 있지 않음
kubectl get psp

https://kubernetes.io/ko/docs/concept/policy/pod-security-policy/#파드-시큐리티- 폴리시란

# 파드 시큐리티 폴리시 변경
kubectl edit psp eks.privileged

privileged: false. # 이 부분은 false로 변경

# 파드는 정상적으로 동작한다.
kubectl apply -f - <<EOF

# 확인
kubectl get pod nginx

# 삭제
kubectl delete pod nginx

# 특권 컨테이너 파드는 동작 불가
kubectl apply -f - <<EOF
# 파드 시큐리티 폴리시 변경
kubectl edit psp eks.privileged

spec.privileged를 true로 변경

파드 보안

컨테이저 라이프사이클에 맞춘 보안 대책의 필요성

  • 컨테이너 이미지 취약성
  • 동작 감시(런타임 보호)

네트워크 보안

엔트포인트 IP 주소 제한

  • EKS에서는 엔드포인트의 IP 주소 제한 기능

kubectl을 VPC 내부로 제한하는 프라이빗 엔드포인트

네트워크 정책을 사용한 클러스터 내부 통신 제어

  • 네트워크 정책을 사용하려면 프로젝트 칼리코(Calico)라는 쿠버네티스 네트워크 정책 엔진을 적용해야 함.

Calico 네트워크 정책 엔진 추가 기능 설치

  • 서비스 A, 서비스 B, 서비스 C가 있을 경우 ‘서비스 A는 서비스 B에만 접속을 허가하고 서비스 C에서의 접속은 허가하지 않는다.’ 가능. network-policy-all-deny.yaml
  • network-policy-all-deny.yaml
# 기본 설정으로 모든 통신 차단(security/network-policy-all-deny.yaml)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector:
    # 모든 파드에 적용
    matchLabels: {}
  • network-policy-allow-http-from-serviceB2ServiceA.yaml
# 서비스 B에서 http 접속만 허가하는 예(security/network-policy-allow-http-from-serviceB2ServiceA.yaml)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: network-policy-for-servicea
  # 적용 대상 네임스페이스 지정
spec:
  podSelector:
    matchLabels:
    # 적용 대상 파드 레이블 지정
      app: ServiceA
  policyTypes:
  - Ingress
  ingress:
  #수신 룰을 지정
  - from:
    - podSelector:
        matchLabels:
          app: ServiceB
    ports:
    - protocol: TCP
      port: 80
# 모든 통신을 거부
kubectl apply -f security/network-policy-all-deny.yaml

# 서비스 B에서 서비스 A로의 HTTP(80) 통신만 허가
kubectl apply -f security/network-policy-allow-http-from-serviceB2ServiceA.yaml

# 서비스 A 배포
kubectl apply -f security/network-policy-sample-serviceA.yaml
# 윈도우 10 환경의 경우 다음 명령 실행
exec winpty bash

# 칼리코 설치
kubectl apply -f <https://raw.githubsercontent.com/aws/> \\
amazon-vpc-cni-k8s/master/config/v1.7/calico.yaml

# 서비스 B 파드를 실행
kubectl run -it serviceb --image=busybox --labels="app=ServiceB" --rm -- sh

# 프롬프트가 표시되면 서비스 A로 HTTPS 요청을 보낸다.
wget -q -0 - <http://servicea.eks-work.svc.cluster.local>

# nginx의 메인 페이지가 표시된다.
...

# 파드에서 접속 종료
exit
# 윈도우 10 환경의 경우 다음 명령 실행
exec winpty bash

# 서비스 B 파드를 실행
kubectl run -it servicec --image=busybox --labels="app=ServiceC" --rm -- sh

# 프롬프트가 표시되면 서비스 A로 HTTPS 요청을 보낸다.
wget -q -0 - <http://servicea.eks-work.svc.cluster.local>

# 아무 응담이 없음.(=네트워크 정책으로 거부됨)
# [Ctrl] + [C]로 명령 강제 종료

# 파드에서 접속 종료
exit

리소스 삭제

# 칼리코 삭제
kubectl delete -f <https://raw.githubusercontent.com/aws/> \\
amazon-vpc-cni-k8s/master/config/v1.7/calico.yaml

# 보안 관련 리소스를 모두 삭제
kubectl delete -f security

Column EKS가 AWS CLI로 인증하는 구조

Column EKS 클러스터를 생성했지만 인증이 안 되는 사례

  • 생성자는 자동으로 eks에 등록됨. 실제관리하는 자에 대한 등록이 필요함.

AWS EKS 공식문서 보안 문서

Back to top