K8S 보안 위협
K8S의 각 계층별 보안
1. 안전한 worker node 선정
1) EKS Optimized AMI 사용
2) Custom AMI를 사용 시 inspector와 같은 취약점 점검 서비스를 통해서 worker node의 취약점을 주기적으로 점검
3) worker node는 EC2를 사용하는 것이기 때문에 이미 hardening 처리된 것을 사용하는 것도 좋음
4) aws에서는 container를 위한 bottleroket 을 제공함
5) EC2에 대한 접근 제어 사용
2. Runtime Security 강화 방법
1) SElinux 활용
- K8S에서도 보안을 위해서 사용하는 것이 좋습니다.
- container와 Host간의 격리를 지원합니다.
- container 간의 격리를 지원합니다.
- Pod의 설정과 연계하여 보안 설정을 적용할 수 있습니다.
- SElinux의 Label은 사용자, 룰 , 타입 등으로 정의할 수 있습니다.
- SElinux 정책에 있는 내용을 Pod의 spec에 있는 SecurityContext에 지정해서 사용할 수 있습니다.
- SElinux를 사용하게 되면 파일이나 프로세스에 대한 접근 제어를 구현하여 불필요한 container 자원이
중요 파일에 접근하는 것을 막을 수 있습니다.
2) SECCOMP(SEcure COMPuting mode)
- application의 systemcall을 제어하는 목적입니다.
- selinux처럼 파일이나 프로세스, 포트 등을 제어하는 것이 아닙니다.
2) AppArmor(Application Armor)
- SELinux와 비슷 그러나 Label을 사용하지 않음
- Security Policy를 기반으로 해서 Host위에서 구동되는 Container에 대한 보안 기능을 제공합니다.
- container와 host 간의 격리만 지원합니다.
Ex) Pod에서 Host의 특정 경로에 대한 접근을 차단하거나 허용합니다.
Container image관리
1) ECR과 관련된 IAM을 통해서 접근 제어를 수행 가능
2) open policy agent를 통해서 정책을 수립하여 적용할 수도 있습니다.
3) ECR에서 제공한 Image scanning 기능을 통해서 Image의 보안 상태를 점검 가능합니다.
- 기존 제공 : Basic Scanning
- 강화된 기능: Basic Scanning + New Inspector 가 합쳐진 Enhanced Scanning 기능을 제공하고 있습니다.
4) VPC Endpoint를 적용
- ECR의 이용환경을 좀 더 private 하게 할 수 있습니다.
- VPC Endpoin에 대해서는 VPC Endpoint를 호출하는 자격증명을 조직 내에 속한 자격증명으로 제한하는 Endpoint
정책을 적용하는 것을 권고합니다.
Image 저장소 보안
- registry에 대한 접근 권한을 관련 팀별로 적용하는 것도 중요합니다.
- repository에 resource 기반 정책(policy)을 작성하여 특정 자격증명에 대해서만 지정된 repository에 접근 가능하게
설정
개발 ~ 배포까지의 전체 프로세스 보안
권한 관리
K8S의 인증과 인가
1. K8S 인증 방식
- K8S의 API 사용을 위한 인증 구조는 포함하고 있지 않습니다.
- 자체적으로 인증을 수행하지 않는 대신 외부의 인증 수단을 통해 인증 정보를 수신하고 K8S에서는 권한에 대한 인가만
수행
2. K8S의 권한
1) 권한을 갖는 사용자
2) Service Account
3) 권한을 명시한 Role
(1) 일반 Role
- 특정 namespace에서 만 사용
(2) Cluster Role
- clust 전체에 사용 가능
4) Role Binding
- Role과 사용자나 service Account를 연경 하는 데 사용
EKS의 인증과 인가
1. EKS의 인증
- EKS에서는 IAM Authenticator를 통해서 EKS의 인증을 AWS IAM과 연계시켜 인증을 합니다.
- EKS사용을 위해서는 사용자 단말에 kubectl과 함께 IAM Authenticator가 설치되어 있어야 합니다.
2. EKS의 인증 상세 절차
1) K8S Action
- kubectl을 통하여 명령을 실행합니다.
2) token 발급
- IAM-authenticator의 Client Module이 내부적으로 단말에 설정된 IAM 사용자의 자격증명 정보를 기반으로
Token을 발급합니다.
3) action + Token
- 사용자의 명령(action)은 token과 함께 API 서버로 전달됩니다.
4) Id Token 확인
- API 서버는 사용자로부터 받은 Token을 검증하기 위해 API 내부에 설치된 IAM Authenticator Server에게 Token
전달
- Token을 전달받은 IAM Authenticator Server는 Token의 유효성 검증을 위하여 해당 Token을 AWS STS로 전달
5) sts: GetCallerIndentify
- STS에서는 Authenticator Server로부터 수신한 호출의 유효성을 검증합니다.
6) 성공
- STS에서 정상적인 IAM 자격증명이라고 판단되면 성공 메시지는 Authenticator Server에 전달합니다.
7) K8S User 확인
- STS로부터 성공 메시지를 수신한 Authenticator Server는 AWS Auth Config Map을 통해 해당 자격증명에
mapping 되어있는 K8S 사용자 정보를 확인하면 API Server에 인증에 대한 성공을 전달합니다.
8) K8S Role 확인
- 인증 성공을 전달받은 API Server는 인가를 위해 해당 사용자에 대한 권한을 확인하는 작업을 수행합니다.
9) 허용 / 차단
- 만일 사용자에 바인딩되어 있는 권한이 사용자가 실행한 Action을 포함하고 있다면 사용자의 요청은 허용됩니다.
결론)
- 즉, EKS 환경에서는 IAM Authenticator client와 Server가 각각 사용자와 API Server에서 동작하면서 IAM에
기반한 인증을 수행한다고 보면 됩니다.
3. service account에서 AWS API 접근 권한 부여
- service account에 IAM Role을 mapping 하여 권한을 부여할 수 있습니다.
4. serivce account에 대한 IAM 기능
- K8S를 AWS 환경에서 사용하다 보면 각 Pod에서 AWS 서비스에 대한 접근 권한이 필요한 경우가 생길 수밖에 없습니다.
이때 권한 부여할 수 있는 방식은 각 Pod에서 사용 가능한 Service Account를 이용하여 권한을 부여하거나
EC2에 할당된 Instance profile을 활용하는 것입니다.
- instance profile을 이용하면 간단한 code를 통해서 Role의 권한을 사용할 수 있다는 장점이 있지만 하나의 노드에서
구동되는 여러 Pod가 동일한 권한을 가졌다는 점에서 보면 바람직한 권한 부여 방식은 아니라고 볼 수 있을 것 같습니다.
따라서 AWS에서는 이러한 Pod 별로 서로 다른 Role에 mapping이 가능하도록 IAM Role for Sevice Account라는
기능을 제공하고 있습니다.
- IAM Role for Sevice Account(IRSA) 기능은 Pod에서 사용하는 Service Account 별로 IAM Role을 사용하는 것을
목적으로 하고 있습니다.
5. IAM Role for Sevice Account(IRSA)
- IRSA를 이용하여 각 Service Account 별로 IAM Role을 mapping 하는 방법
1) OIDC IdP 등록
- OIDC rlqksdml IdP를 IAM 등록해야 합니다.
2) IAM Role 생성
- Sevice Account에 Mapping 할 IAM Role을 생성
3) IAM Policy 할당
- IAM Role에 Policy를 할당해 줘야 합니다.
4) K8S SA 생성
- Role을 사용할 Service Account(SA)를 생성합니다.
5) SA Annotation 추가
- Service Account에 대한 Annotation을 추가합니다.
K8S 외부 네트워크 보안
1. AWS Network Firewall
2. Network Access Control List (NACL)
3. AWS Security Groups
K8S 내부 Pod 단위의 네트워크 보안
- network policy는 K8S에서 제공하는 기능을 통하여 네트워크에 대한 통제를 구현할 수 있습니다.
1. pod에 할당된 label을 기반으로 여러 가지 네트워크 경로에 대한 보안을 고려해볼 수가 있습니다.
Ex) 푸른색 namespace에서는 다른 namespace로 통신을 시작할 수 없다거나 특정 namespace나 외부에서 유입되는
트래픽을 차단하는 것과 같은 여러 가지 정책을 생각해볼 수 있습니다.
2. Network policy
- 다양한 네트워크 보안 요건을 구현하는 사용 합니다.
- ipblock , namespace selector, pod select 등을 조합하여 원하는 트래픽 플로우에 대한 허용 혹은 차단에 대한
정책을 구현하실 수 있습니다.
Secuity Group For Pod
- 관리자 입장에서는 network policy를 사용하는 것은 관리 point를 늘리는 것이기 때문에 이를 대체 하기 위해서 EKS
에서 사용하는 것입니다.
- 하나의 Node에서 구동되는 개별 Pod에 각각 하나의 Branch Interface를 Mapping 한 후 각 Branch Interface에
Security Group을 할당할 수 있도록 한 기능입니다.
- 요약하면 Node 레벨에서 적용하던 Security Group을 Pod 레벨로 적용이 가능하다고 생각하면 됩니다.
이걸 사용하면 Node에 위치한 Pod 간의 통신도 VPC Flow Log를 통해서 로깅할 수 있고, 네트워크 접근 통제도
Security Group을 통하여 통일화할 수 있습니다.
- 단 이 기능은 Nitro Type의 인스턴스만 지원합니다. 그리고 각 Node당 최대 생성 가능한 Pod개수도 고려해야 합니다.
Data Secuity 암호화
1. Secrity -EKS를 활용한 암호화
- K8S에서 secret은 중요 정보를 저장하기 위한 용도로 사용되기 때문에 안전한 암호화 알고리즘을 통해서 보관하는 것이
바람직합니다.
- EKS환경에서는 AWS KMS를 통해서 secret에 대한 암호화/복호화를 자동화할 수 있습니다.
- 기본적인 사용 환경은 사용자가 kubectl을 통해서 secret을 생성하게 되면 API 서버가 해당 secret을 암호화해서 etcd
에 저장하게 된다고 보시면 됩니다.
- 이때 secret을 암호화하는 데이 터키를 KMS를 통해서 암호화한 후에 secret과 함께 봉투 암호화하여 저장하는 게 핵심
입니다.
- 봉투 암호화되어 etcd에 저장된 secret은 사용자가 복호화를 요청하면 API 서버가 KMS와 연동되어 봉투 암호화 처리된
secret을 복호화한다고 보시면 됩니다.
2. KMS를 이용한 secret 암호화 과정
1) 사용자가 secret을 생성 (kubectl create secret)
2) secret 생성 시 발생한 API요청을 API 서버가 수신
3) 요청을 수신한 API 서버는 sercret을 함호화 할 새로운 데이터 암호화 키를 자체적으로 생성
4) 새롭게 생성된 데이터 암호화 키를 메모리에 로딩한 후 사용자가 요청한 secret을 암호화합니다.
5) AWS Encryption Provider는 봉투 암호화를 수행하기 위해 API 서버가 생성한 데이 터키를 KMS로 보내 암호화하는
작업을 수행
* AWS Encryption Provider를 이용하여 AWS KMS와 API 서버를 연동합니다.
AWS Encryption Provider는 API 서버를 대신하여 KMS에 데이 터키에 대한 암복화 호출을 수행하는 역할을 합니다.
6) KMS가 데이터키를 암호화하게되면 API 서버에는 암호화된 secret과 KMS에서 암호화한 데이터키가 존재하게 됩니다.
7) API 서버는 사용자가 생성한 secret을 etcd에 저장할 때 암호화된 secret만 저장하는 것이 아니라 암호화된 데이터키를
봉투 암호화하여 함께 저장하게 됩니다.
2. ETCD에 저장된 secret을 복호화
1) 사용자가 kubectl get secret 호출
2) API 서버는 사용자의 secret 요청을 받으면 etcd로부터 봉투 암호화 처리된 secret을 가지고 오게 되는데요.
이때 메모리에 사용 가능한 평문 데이터 암호화 키가 있는지 확인합니다.
만일 평문 데이터 암호화 키가 있다면 해당 키를 통해서 바로 암호화된 secret을 복호화한 후에 사용자에게 리턴합니다
3) 봉투 암호화 처리된 secret에서 평문 암호화 키를 추출해야 합니다.
이를 위해서 AWS encryption provider는 암호화된 데이 터키를 이용해 KMS로 Decrypt API를 호출합니다.
4) KMS는 요청받은 암호화된 데이 터키에 대한 Decrypt 호출에 대해서 데이터키에 mapping 된 CMK로 복호화 작업을
수행하여 복호화된 데이 터키를 AWS Encryption Provider에게 전달하게 됩니다.
5) 이렇게 전달받은 평문의 데이 터키를 API 서버의 메모리에 로딩되게 됩니다.
6) 그리고 API 서버는 이렇게 로딩된 평문 데이터키를 이용하여 봉투 암호화 처리된 secret을 복호화한 후 사용자에게
리턴 합니다.
위협 탐지(GuardDuty)
- AWS에서 느 GuardDuty라는 완전 관리형 위협 탐지 서비스를 제공합니다.
- GuardDuty는 VPC Flow Log, DNS Log, CloudTrail Log 등을 분석하여 다양한 위협을 탐지하는 기능을 제공합니다.
- 2022년 1월 EKS에 대한 위협 탐지 기능이 GuardDuty에 추가되었습니다.
- GuardDuty에서 제공하는 EKS위협 탐지 기능은 EKS Audit Log를 기반으로 동작합니다.
그 외 보안 설루션
'내맘대로 Study > AWS의 모든것' 카테고리의 다른 글
[AWS-DOP-CO1] CodeCommit (0) | 2022.10.12 |
---|---|
[AWS-DOP-CO1] CICD Overview (0) | 2022.06.13 |
[2022 AWS summit] NFT (0) | 2022.05.11 |
[2022 AWS summit] 블록체인 개요 정리 (0) | 2022.05.11 |
[AWS] Cloudtail 과 CloudWatch 비교 (0) | 2022.02.24 |