들어가며

안녕하세요. 오픈소스컨설팅 엔지니어 조철진입니다.

저는 올해 초에 CKS 자격증을 공부하면서 쿠버네티스의 다양한 보안 컴포넌트를 접해볼 기회가 있었는데요. 이를 토대로 쿠버네티스 공식 문서의 보안 지침을 정리해두고 추후 실무에서 정리된 내용을 보면서 적용 시 참고가 되었으면 좋겠다는 생각으로 블로그를 작성하게 되었습니다.

최근에는 CWPP, CSPM, CIEM, CNAPP 등 이름도 어려운 다양한 클라우드 환경을 위한 보안 솔루션들이 등장하였는데요. 쿠버네티스도 버전 v1.29가 릴리즈 되면서 보안 관련 공식 문서에 많은 변화가 있었습니다. 이번 글에서는 공식 문서가 어떻게 바뀌면서 트렌드가 반영되었는지 알아보도록 하겠습니다.


기존의 클라우드 네이티브 보안(~v1.28)

클라우드 네이티브 환경의 보안은 4개의 계층으로 이루어져 있습니다. 각 계층은 바깥에 위치한 계층을 기반으로 구축되며 클라우드(Cloud), 클러스터(Cluster), 컨테이너(Container)와 코드(Code) 네 가지를 합하여 “4C”라고 부릅니다.

코드 영역의 보안은 하위의 인프라 영역인 클라우드, 클러스터, 컨테이너의 보안이 강력하게 구성되어 있어야 이점을 누릴 수 있습니다. 코드 수준에서의 보안 강화 만으로는 하위 인프라 계층의 부족한 보안을 보완할 수 없습니다.

Cloud

쿠버네티스 클러스터 인프라 단의 보안을 위한 권장 사항입니다.

  1. Network access to API Server (Control plane)

모든 쿠버네티스 Control plane에 대한 네트워크 접근은 공개적으로 허용되지 않아야 하며, 관리 IP 주소 범위에 대한 네트워크 ACL 설정을 권장합니다.

  1. Network access to Nodes (nodes)

쿠버네티스 노드는 Control plane과의 연결 만을 허용해야 하며, NodePort 및 LoadBalancer 유형의 서비스에 대한 연결을 허용해야 합니다. 가능하면 노드는 외부에 노출되지 않아야 합니다.

  1. Access to etcd

etcd는 Kubernetes의 데이터 저장소로 중요한 역할을 합니다. 따라서 etcd에 대한 액세스는 Control plane만 허용되어야 합니다.

  1. etcd Encryption

etcd는 전체 클러스터의 상태와 Secrets을 보유하기 때문에 저장소의 데이터를 암호화하는 것이 중요합니다. 특히 etcd의 디스크는 저장된 데이터를 암호화해야 합니다.

Cluster

다음은 클러스터의 보안을 위한 권장 사항입니다.
대부분의 항목이 쿠버네티스의 자체 기능으로, 운영자가 적용을 고려할 수 있게 정리되어 있습니다.

  1. Controlling access to the Kubernetes API
  • 모든 API 트래픽에 대해 전송 계층 보안(TLS) 사용
  • API 인증 적절한 메커니즘 선택(인증서, 정적 Bearer 토큰 등)
  • API 권한 부여, 사용자/그룹에 권한 할당 위해 RBAC 활용
  1. Controlling access to the Kubelet
  • Kubelet 인증 및 권한 부여 활성화
  1. Controlling the capabilities of a workload or user at runtime
  • Resource quota, Limit ranges를 통해 리소스 사용량 제한
  • Security Context 사용 및 Pod Security Admission, Pod Security Standard과 병행하여 파드 실행 제어
  • 원치 않는 커널 모듈을 로드하지 않도록 방지
  • NetworkPolicy 혹은 방화벽을 통한 네트워크 엑세스 제어
  • taint 또는 NodeSelector를 통해 파드가 실행될 노드 제어
  1. Protecting cluster components from compromise
  • etcd에 대한 액세스 제한
  • Audit 로깅 활성화 및 모니터링
  • 개발 중인 기능에 대한 액세스 제한
  • 인증서, 토큰 등 발급 시 사용 기간을 지정하고, 가능한 짧게 지정하여 관리
  • Encryption Confidential Data at Rest 기능을 활용한 Secret 암호화
  • 보안 업데이트 및 취약점에 대해 정보 수신
  1. Protecting Application
  • RBAC 인증 사용, API 인증 사용
  • Encryption Confidential Data at Rest 기능을 활용한 Secret 암호화
  • Pod Security Standards를 통한 파드 실행 제어
  • QoS 기능을 통해 Pod 리소스 제한 설정
  • Network Policy를 통한 액세스 제어
  • Ingress TLS 암호화

Container

다음은 컨테이너의 보안을 위한 권장 사항입니다.

  1. Container Vulnerability Scanning and OS Dependency Security

컨테이너의 이미지 빌드 단계부터 알려진 취약점을 검사해야 합니다.

  1. Image Signing and Enforcement

컨테이너 이미지에 디지털 서명을 활용하여 컨테이너 콘텐츠에 대한 신뢰성을 유지합니다.

  1. Disallow privileged users

컨테이너 구성 시, 생성하는 사용자는 목표를 수행하는데 필요한 최소한의 권한을 갖도록 설정합니다.

  1. Use container runtime with stronger isolation

gVisor와 같은 더 강력한 격리를 지원하는 컨테이너 런타임 클래스를 사용합니다.

Code

애플리케이션 코드는 가장 많은 제어권을 가지고 있는 주요 공격 표면 중 하나 입니다. 애플리케이션 코드를 보호하는 것은 Kubernetes 보안 주제의 범위를 벗어나지만, 애플리케이션 코드를 보호하기 위한 권장 사항은 다음과 같습니다.

  1. Access over TLS only

프로그램 코드가 TCP로 통신해야 하는 경우, 가능한 모든 항목을 암호화 하는 것이 좋습니다.

  1. Limiting port ranges of communication

가능한 서비스에서 통신이나 메트릭 수집에 꼭 필요한 포트만 서비스에 노출합니다.

  1. 3rd Party Dependency Security

알려진 보안 취약점이 있는지 애플리케이션의 3rd Party 라이브러리를 정기적으로 검사하는 것이 좋은 방법입니다. 각 프로그래밍 언어에는 일반적으로 자동으로 이러한 확인을 수행하는 도구가 있습니다.

  1. Static Code Analysis

대부분의 언어는 잠재적으로 안전하지 않은 코딩 방식을 분석하는 방법을 제공합니다.
주기적으로 코드 베이스에서 스캔할 수 있는 자동화된 도구를 사용하여 분석하는 것을 권장 드립니다.

  1. Dynamic probing attacks

OWASP10 과 같은 알려진 공격을 테스트하는 도구를 사용해 주기적으로 점검하는 것을 권장 드립니다.


최근의 클라우드 네이티브 보안(v1.29)

쿠버네티스의 최신 버전인 1.29 의 공식 문서부터, 클라우드 네이티브 보안에 대한 관점이 달라졌습니다.
기존과 다르게 인프라적인 측면만이 아닌 개발, 공급망, 배포, 런타임이라는 네 가지 수명 주기로 구분되어 보안이 중요시되고 있습니다. 이제부터 업데이트된 클라우드 네이티브 환경의 보안에 대한 접근 방식과 지침을 알아보도록 하겠습니다.

Develop(개발) lifecycle phase

  • 개발 환경의 무결성을 보장해야 합니다.
  • 정보 보안에 대한 모범 사례에 따라 상황에 적합한 애플리케이션을 설계하도록 합니다.
  • 솔루션 설계 시, 최종 사용자 단의 보안을 고려해야 합니다.

이를 달성하기 위해서는 다음과 같은 작업을 수행할 수 있습니다.

  1. 내부 위협에 대해서 공격 표면의 최소화를 위하여 ZeroTrust아키텍처를 채택합니다.
  2. 보안 문제를 점검하는 코드 리뷰 프로세스를 정의하고 진행합니다.
  3. 시스템 또는 애플리케이션의 위협 모델을 구축합니다.
    이를 통해 신뢰 경계를 식별하고 위험을 파악하여 그에 대한 대응 방안을 찾는데 도움을 줄 수 있습니다.
  4. Fuzzing 및 Security Chaos Engineering과 같은 고급 보안 자동화를 통합합니다.

Distribute(공급망) lifecycle phase

  • 실행하는 컨테이너 이미지에 대한 공급망 보안을 보장해야 합니다.
  • 애플리케이션을 실행하는 클러스터와 기타 구성 요소에 대한 공급망 보안을 보장해야 합니다.
    다른 구성 요소의 예로는 애플리케이션에서 사용하는 외부 데이터베이스가 있을 수 있습니다.

이를 달성하기 위해서는 다음과 같은 작업을 수행할 수 있습니다.

  1. 알려진 취약점을 검사하기 위해 컨테이너 이미지 및 기타 항목을 검사합니다.
  2. 소프트웨어 배포 과정에서 데이터가 전송되는 동안 암호화를 적용하고, 소프트웨어 소스의 신뢰를 확인하기 위한 신뢰 체인을 구축합니다.
  3. 소프트웨어 업데이트가 가능할 때 라이브러리와 같은 종속적인 소프트웨어의 업데이트를 위한 프로세스를 정의하고 준수합니다. 특히 보안 공지에 대응하여야 합니다.
  4. 공급망의 신뢰성 보증을 위해 디지털 인증서와 같은 유효성 검사 메커니즘을 사용합니다.
  5. 보안 위험에 대해 경고하는 피드 및 기타 메커니즘을 구독하여 주기적으로 확인합니다.
  6. 접근을 제한하여 권한이 있는 클라이언트만 이미지를 가져올 수 있도록 Private Registry에 컨테이너 이미지를 배치합니다.

Deploy(배포) lifecycle phase

배포 과정에서는 무엇이 배포 될 수 있는지, 누가 배포할 수 있는지, 그리고 어디에 배포될 수 있는지 에 대한 적절한 제한을 해야 합니다. 이러한 제한은 공급망 단계에서 컨테이너 이미지의 암호화된 식별 정보를 확인하는 등의 조치를 통해 진행할 수 있습니다.

쿠버네티스 클러스터를 배포할 때, 응용 프로그램의 런타임 환경을 위한 기반을 설정해야 합니다.
클러스터가 실행되는 기반 인프라는 반드시 상위 계층에서 요구하는 보안을 보장해야 합니다.

Runtime(실행) lifecycle phase

런타임 단계는 Access, Compute 및 Storage 라는 세 가지 주 영역으로 구성됩니다

Runtime protection: Access

쿠버네티스 API는 클러스터가 작동하는 핵심입니다. API를 보호하는 것은 효과적인 클러스터 보안을 제공하는 데 중요합니다. Security Checklist 문서에는 기본적인 클러스터 보안 체크리스트가 있습니다.

또한, API 액세스에 대해 효과적인 인증 및 권한 부여를 구현하기 위해서 ServiceAccounts를 사용하여 워크로드와 클러스터 구성 요소에 대한 ID를 제공하고 관리하도록 권장합니다.

쿠버네티스는 API 트래픽을 보호하기 위해 TLS를 사용하며 이를 사용해 클러스터를 배포하고 암호화 키를 보호해야 합니다. CertificateSigningRequests 사용 시 쿠버네티스 자체 API를 사용한다면, 오남용을 제한하기 위해서 특별한 주의가 필요합니다.

Runtime protection: Compute

컨테이너는 서로 다른 애플리케이션을 격리하는 것과, 격리된 애플리케이션을 결합하여 동일한 호스트 컴퓨터에 실행하는 것 두 가지 기능을 제공합니다. 런타임 보안은 이 두 가지 측면, 격리와 결합에 대한 적절한 균형을 찾는 것이 중요합니다.

쿠버네티스는 컨테이너를 설정하고 실행하기 위해 컨테이너 런타임에 의존합니다. 쿠버네티스 프로젝트는 특정한 컨테이너 런타임을 권장하지 않으며, 선택한 런타임이 보안 요구 사항을 충족하는지 확인해야 합니다.

런타임에서 Compute 자원을 보호하기 위해서는 다음과 같은 작업을 수행할 수 있습니다:

  1. Pod Security Standards 설정을 강제하여 애플리케이션을 필요한 권한으로만 실행하도록 합니다.
  2. 컨테이너 워크로드를 실행하기 위해 설계된 전용 OS Image를 사용합니다. 이는 일반적으로 컨테이너를 실행하는데 필수적인 서비스만을 제공하는 읽기 전용 OS(Immutable Image)를 기반으로 합니다. 컨테이너 전용 OS는 시스템 구성 요소를 격리하고 공격 표면을 최소화 하는데 도움이 됩니다.
  3. 리소스 할당을 공정하게 하기 위해 ResourceQuotas를 정의하고, Pod의 리소스의 사용을 제한하기 위해 LimitRanges 기능을 사용하도록 합니다.
  4. NodeSelector와 같은 기능을 사용하여 여러 노드에 워크로드를 분할합니다.
    다른 신뢰 수준을 가진 Pod는 별도의 노드 집합에서 실행되도록 합니다.
  5. 보안 적인 제한을 제공하는 컨테이너 런타임을 사용합니다.
  6. 호스트 Linux 서버에서 AppArmor 또는 seccomp와 같은 Linux 보안 모듈을 사용합니다.

Runtime protection: Storage

클러스터에서 실행되는 애플리케이션의 Storage를 보호하기 위해 다음과 같은 작업을 수행할 수 있습니다.

  1. 볼륨에 대한 암호화를 제공하는 외부 스토리지 플러그인과 클러스터를 통합합니다.
  2. API 객체에 대하여 Encryption Confidential Data at Rest 기능을 활성화합니다.
  3. 백업을 사용하여 데이터를 보호합니다. 필요할 때 언제든지 이를 복원할 수 있는지 확인합니다.
  4. 클러스터 노드와 네트워크 스토리지 사이의 연결에 인증을 사용합니다.
  5. 애플리케이션 내에서 데이터 암호화를 구현합니다.

암호화 키의 경우, 특수 하드웨어에서 이를 생성하면 정보 누출 위험에 대한 최상의 보호를 제공합니다. 하드웨어 보안 모듈을 사용하면 보안 키가 다른 곳에 복사 되지 않고 암호화 작업을 수행할 수 있습니다.

Networking and security

네트워크 보안을 위하여 NetworkPolicy나 Service Mesh와 같은 것들을 고려해야 합니다. Kubernetes의 일부 네트워크 플러그인은 VPN Overlay와 같은 기술을 사용하여 클러스터 네트워크에 대한 암호화를 제공합니다.

Kubernetes는 클러스터에 자체 네트워킹 플러그인을 사용할 수 있도록 설계되어 있으며, 선택한 네트워크 플러그인 및 통합 방식이 전송하는 정보 보안에 큰 영향을 미칠 수 있습니다.

Observability and runtime security

Kubernetes 자체에는 기본적인 Observability 기능이 내장되어 있으며, 애플리케이션과 클러스터의 모니터링 또는 문제 해결을 위해 3rd Party 솔루션을 설정할 수 있습니다. 컨테이너에서 실행되는 코드는 로그를 생성하거나 지표를 생성하거나 기타 관측 가능한 데이터를 제공할 수 있습니다. 배포 시 클러스터가 적절한 수준의 보호를 제공하는지 확인해야 합니다.

지표에 대한 대시보드나 유사한 도구를 설정하는 경우 대시보드 자체뿐만 아니라 해당 대시보드로 데이터를 제공하는 구성 요소를 검토하는 것이 중요합니다. 전체 구성 요소가 클러스터 성능이 저하될 수 있는 사고 중에도 신뢰할 수 있는 충분한 내구성과 무결성 보호 기능을 갖추도록 설계되었는지 확인해야 합니다.

Kubernetes 보다 Low level 단의 추가적인 보안을 권장합니다. 예를 들어, 암호화된 부팅 및 시간 동기화와 같은 조치가 있습니다. 이러한 조치는 로그 및 감사 기록의 정확성을 보장하는 데 도움이 됩니다.

로그의 변조를 방지하고 기밀을 보장하기 위해 로그를 암호화합니다.


마무리

이상으로 변경된 쿠버네티스 최신 버전의 문서를 확인해보며 클라우드 네이티브 보안의 트렌드 변화에 대해 알아보았습니다. 기존 문서에는 인프라 자체를 보호하는 것에 중점을 두고 지침이 작성되었다면, 최근의 관점은 개발, 공급망 단계까지 포함하여 IT 서비스 전반에 이르는 모든 프로세스의 보안에 대한 중요성을 강조하도록 변화 되었습니다.

개인적으로는 클라우드 네이티브라는 개념이 도입되면서 요구되는 지식의 수준이 상당히 높아지면서 넓어졌다고 생각되며, 이러한 지침들을 한 기업에서 독자적으로 수행하는 것은 상당히 어려운 프로세스기에 CNAPP과 같은 복잡하고 다양한 기능을 탑재한 솔루션이 출시되어 주목 받고 있다고 생각되네요.

제가 정리해본 내용이 독자 분들에게 도움이 되었기를 바라며 글을 마치겠습니다. 감사합니다!


보안 용어 모음 및 참고 문서

공격 표면(Attack Surface): 시스템이 공격을 받을 수 있는 모든 장치, 경로, 네트워크 등의 지점을 의미합니다.

제로 트러스트(Zero Trust): 모든 네트워크에 요청에 대하여 신뢰하지 않고 인증 및 허가 과정을 추가하는 보안 모델입니다.

카오스 엔지니어링(Chaos Engineering): 컴퓨터 시스템이 예상치 못한 스트레스를 견딜 수 있는지 테스트하는 과정을 말합니다.

신뢰 경계(Trust Boundary): 시스템 내에서 신뢰할 수 있는 부분과 신뢰할 수 없는 부분의 경계를 의미합니다. 예를 들어, 전통적인 네트워크 보안에서는 내부 네트워크가 신뢰할 수 있는 영역으로 간주되고, 외부 네트워크는 신뢰할 수 없는 영역으로 여겨집니다.

신뢰 체인(Chain of Trust): 여기서 말하는 신뢰 체인이란 소프트웨어의 무결성을 확인하기 위한 메커니즘으로 GPG 키나 소프트웨어 Hash 값으로 인증 절차를 추가하여 구성하는 것을 권장하고 있습니다.

https://v1-28.docs.kubernetes.io/docs/concepts/security/overview/

https://kubernetes.io/docs/concepts/security/cloud-native-security/

오픈소스를 다루는 것을 좋아하는 Linux팀의 엔지니어 조철진이라고 합니다. 기왕 일을 시작했다면 긍정적인 마인드를 가지려고 노력하며 다양한 IT기술에 관심이 있습니다.

Leave a Reply

Your email address will not be published. Required fields are marked *