# Security: 컨테이너 취약점 스캔 및 보안 정책 강화 # node 수 조정 - pod 가 많이 배포되어야 해서 노드를 늘린다. 5대. ASG_NAME=eks-general-20260210103125336500000003-d6ce238d-8ee2-d0d6-12f2-61e53649fa2b echo ${ASG_NAME} aws autoscaling update-auto-scaling-group --auto-scaling-group-name ${ASG_NAME} --min-size 1 --desired-capacity 5 --max-size 6 <1> trivy 1 # 레포지토리 설정 추가 cat < trivy image --severity CRITICAL 588752323301.dkr.ecr.ap-northeast-2.amazonaws.com/my-web-app 2 # ECR 로그인 aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 588752323301.dkr.ecr.ap-northeast-2.amazonaws.com 3 trivy image --severity CRITICAL 588752323301.dkr.ecr.ap-northeast-2.amazonaws.com/my-web-app <2> Kyverno를 실행 # 1. Kyverno 공식 Helm 저장소 추가 helm repo add kyverno https://kyverno.github.io/kyverno/ # 2. 저장소 정보 최신화 helm repo update # 3. 다시 설치 시도 helm install kyverno kyverno/kyverno -n kyverno --create-namespace yverno를 성공적으로 설치하셨으니, 이제 실질적으로 정책(Policy)을 적용하여 클러스터를 제어해 볼 차례입니다. Kyverno는 **"Admission Controller"**로 작동하여, 파드가 생성될 때 보안 규칙을 위반하면 생성을 막거나 설정을 자동으로 수정합니다. 가장 대표적이고 유용한 "보안 정책" 하나를 같이 실행해 보겠습니다. 제: 이미지 취약점 스캔(Trivy) 결과가 없는 이미지 배포 금지 방금 Trivy를 사용하셨으니, "이미지 스캔 결과가 없는 컨테이너는 배포되지 않도록" 하는 정책을 적용해 볼 수 있습니다. (여기서는 가장 기초적인 '최신 이미지만 사용 강제' 정책을 예로 들어보겠습니다.) 1. 정책 파일 생성 (disallow-latest-tag.yaml) 개발자가 실수로 :latest 태그를 사용하는 것을 막는 정책입니다. (방금 겪으신 latest 이미지 누락 이슈를 방지하는 데 도움을 줍니다.) cat < disallow-latest-tag.yaml apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: disallow-latest-tag spec: validationFailureAction: Enforce background: true rules: - name: require-image-tag match: any: - resources: kinds: - Pod validate: message: "Using the 'latest' tag is not allowed. Please specify a version tag." pattern: spec: containers: - image: "!*:latest" EOF 정책 적용 kubectl apply -f disallow-latest-tag.yaml 작동 테스트 이제 실수로 :latest 태그를 사용하여 파드를 생성하려고 시도해 보세요. # 이 명령은 Kyverno에 의해 차단되어야 합니다. kubectl run test-mario --image=588752323301.dkr.ecr.ap-northeast-2.amazonaws.com/my-web-app:latest oot@myeks2-bastion-EC2 kube-ops-view]# kubectl run test-mario --image=588752323301.dkr.ecr.ap-northeast-2.amazonaws.com/my-web-app:latest Error from server: admission webhook "validate.kyverno.svc-fail" denied the request: resource Pod/default/test-mario was blocked due to the following policies disallow-latest-tag: require-image-tag: 'validation error: Using the ''latest'' tag is not allowed. Please specify a version tag. rule require-image-tag failed at path /spec/containers/0/image/' [root@myeks2-bastion-EC2 kube-ops-view]# 설치된 정책 목록 보기: kubectl get clusterpolicy (또는 cpol) [root@myeks2-bastion-EC2 kube-ops-view]# kubectl get clusterpolicy NAME ADMISSION BACKGROUND READY AGE MESSAGE disallow-latest-tag true true True 28s Ready [root@myeks2-bastion-EC2 kube-ops-view]# 정책 위반 보고서 확인: kubectl get policyreports -A Kyverno 로그 실시간 확인 (문제 발생 시): kubectl logs -f -l app.kubernetes.io/name=kyverno -n kyverno <3> Falco 설치 Falco는 쿠버네티스 환경에서 런타임 보안 위험을 감지하는 가장 대표적인 오픈소스 도구입니다. 비정상적인 시스템 콜, 파일 쓰기, 쉘 실행 등을 실시간으로 감시할 수 있습니다. 이미 Kyverno를 설치하실 때 사용했던 Helm을 이용해 설치하는 것이 가장 간편합니다. 1. Falco Helm 저장소 추가 및 업데이트 # Falco 공식 차트 저장소 추가 helm repo add falcosecurity https://falcosecurity.github.io/charts # 저장소 정보 최신화 helm repo update 2. Falco 설치 (기본 설정) 쿠버네티스 클러스터의 모든 노드에 설치되어 보안을 감시하게 됩니다. # falco 네임스페이스 생성 및 설치 helm install falco falcosecurity/falco \ --namespace falco \ --create-namespace \ --set tty=true 3. 설치 상태 확인 모든 노드에 DaemonSet 형태로 배포되므로, 노드 개수만큼 파드가 떠야 합니다. kubectl get pods -n falco -w 5 alco가 무엇을 감시하나요? Falco는 미리 정의된 규칙(Rules)에 따라 다음과 같은 행위를 탐지합니다. 비정상적인 쉘 실행: 실행 중인 컨테이너 내부에서 누군가 쉘(bin/bash)을 띄우는 경우. 민감한 파일 접근: /etc/shadow 같은 시스템 설정 파일을 읽으려고 시도하는 경우. 권한 상승: 특정 프로세스가 루트(root) 권한을 획득하려고 시도하는 경우. 아웃바운드 연결: 데이터 탈취를 위해 컨테이너가 외부 모르는 IP로 데이터를 보내는 경우. 6 제대로 설치되었는지 테스트 (보안 위반 시뮬레이션) 설치가 끝났다면, 강제로 보안 규칙을 위반해 보겠습니다. # 1. 아무 파드에 접속해서 쉘을 실행합니다. kubectl exec -it <아무-파드-이름> -- sh k ns default kubectl exec -it pod/mario-8645856df8-84nwp -- sh # 2. Falco 로그를 확인해 봅니다. $ kubectl logs -f -l app.kubernetes.io/name=falco -n falco sh: 2: kubectl: not found 로그를 확인하려면 컨테이너 안이 아니라, 원래 작업을 하시던 Bastion 호스트 터미널에서 명령어를 입력하셔야 합니다. kubectl logs -f -l app.kubernetes.io/name=falco -n falco 위 로그를 보면 "A shell was spawned in a container with an attached terminal" 같은 경고 메시지가 출력되는 것을 확인할 수 있습니다. # kubectl logs -f -l app.kubernetes.io/name=falco -n falco | more grep shell <4> popeye 보안 도구 시리즈의 완성인 Popeye 설치 단계입니다! Popeye는 쿠버네티스 클러스터를 실시간으로 스캔하여 리소스 부족, 잘못된 설정, 보안 위험 등을 찾아내어 점수를 매겨주는 아주 유용한 도구입니다. popeye 설치 방법 가장 간편한 방법은 바이너리 파일을 직접 다운로드하여 설치하는 것입니다. 아래 명령어를 차례대로 입력하세요. 한줄씩 실행 2 # 1. Popeye 최신 버전 다운로드 (Linux 64bit 기준) # 최신 버전의 tar.gz 파일 주소를 찾아서 다운로드합니다. wget https://github.com/derailed/popeye/releases/download/v0.22.1/popeye_Linux_amd64.tar.gz tar -zxvf popeye_Linux_amd64.tar.gz sudo mv popeye /usr/local/bin/ popeye version 3 # 전체 클러스터 스캔 시작 popeye opeye 결과 보는 법 실행하면 대시보드 형태의 리포트가 나오는데, 핵심은 **Score(점수)**입니다. 점수 (Score): A(우수)부터 F(심각)까지 나옵니다. 목록: * ✅ OK: 설정이 잘 되어 있는 리소스 ⚠️ WARN: 리소스 제한(Limit)이 없거나 사용량이 적은 경우 ❌ ERROR: 심각한 보안 위협이나 설정 오류 금까지 설치하신 도구들을 이렇게 활용하시면 완벽한 보안 환경이 됩니다: Trivy: 이미지를 배포하기 전(CI 단계)에 취약점을 미리 잡습니다. Kyverno: 잘못된 설정이 클러스터에 들어오지 못하게 **입구(Admission)**에서 막습니다. Falco: 이미 돌아가고 있는 컨테이너 내부의 침입을 실시간으로 감시합니다. Popeye: 클러스터 전체에 방치된 위험이나 리소스 낭비를 주기적으로 점검합니다. - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: 'my-web-app:${{ github.sha }}' format: 'table' exit-code: '1' # 취약점 발견 시 빌드 실패 처리 severity: 'CRITICAL,HIGH'