클라우드 네이티브 보안과 Kubernetes
클라우드 네이티브 보안과 Kubernetes (Cloud Native Security and Kubernetes)
클라우드 네이티브 워크로드를 안전하게 유지하기 위한 개념을 다룹니다.
Kubernetes는 클라우드 네이티브 아키텍처를 기반으로 하며, 클라우드 네이티브 정보 보안의 모범 사례에 대한 CNCF의 권고를 활용합니다.
계속해서 Kubernetes가 안전한 클라우드 네이티브 플랫폼을 배포하는 데 어떻게 도움을 주도록 설계되었는지 개요를 살펴볼게요.
클라우드 네이티브 정보 보안 (Cloud native information security)
CNCF의 클라우드 네이티브 보안에 관한 백서(white paper)는 서로 다른 *수명주기 단계(lifecycle phases)*에 적합한 보안 통제와 실천 방법을 정의합니다.
개발(Develop) 수명주기 단계
- 개발 환경의 무결성을 보장합니다.
- 여러분의 맥락에 적절한 정보 보안 모범 사례를 따라 애플리케이션을 설계해요.
- 최종 사용자 보안을 솔루션 설계의 일부로 고려합니다.
이를 달성하려면 다음을 할 수 있어요.
- 내부 위협에 대해서도 공격 표면을 최소화하는 제로 트러스트(zero trust) 같은 아키텍처를 채택하세요.
- 보안 우려를 고려하는 코드 리뷰 프로세스를 정의합니다.
- 신뢰 경계(trust boundaries)를 식별하는 시스템 또는 애플리케이션의 *위협 모델(threat model)*을 구축해요. 그 위협 모델을 사용해서 위험을 식별하고 어떻게 처리할지 결정합니다.
- 정당화되는 곳에서는 *퍼징(fuzzing)*과 보안 카오스 공학(security chaos engineering) 같은 고급 보안 자동화를 통합합니다.
배포(Distribute) 수명주기 단계
- 실행하는 컨테이너 이미지의 공급망 보안을 보장합니다.
- 애플리케이션을 실행하는 클러스터와 다른 컴포넌트의 공급망 보안을 보장해요. 예를 들어, 클라우드 네이티브 애플리케이션이 영속성을 위해 사용하는 외부 데이터베이스가 포함될 수 있습니다.
이를 달성하려면 다음을 할 수 있어요.
- 알려진 취약점에 대해 컨테이너 이미지 및 기타 아티팩트를 스캔합니다.
- 소프트웨어 배포가 소프트웨어 소스에 대한 신뢰 체인과 함께 전송 중 암호화를 사용하도록 보장해요.
- 특히 보안 발표에 대응하여, 업데이트가 가능할 때 의존성을 업데이트하는 프로세스를 채택하고 따릅니다.
- 공급망 보증을 위해 디지털 인증서 같은 검증 메커니즘을 사용해요.
- 보안 위험을 알려주는 피드 및 기타 메커니즘을 구독합니다.
- 아티팩트에 대한 접근을 제한하세요. 권한 있는 클라이언트만 이미지를 가져올(pull) 수 있는 프라이빗 레지스트리에 컨테이너 이미지를 배치합니다.
배포(Deploy) 수명주기 단계
무엇을 배포할 수 있는지, 누가 배포할 수 있는지, 어디에 배포할 수 있는지에 대한 적절한 제한을 보장해요. 컨테이너 이미지 아티팩트의 암호화 신원을 검증하는 것 같은 배포 단계의 조치를 강제할 수 있습니다.
서로 다른 애플리케이션과 클러스터 컴포넌트를 서로 다른 네임스페이스에 배포할 수 있어요. 컨테이너와 네임스페이스는 모두 정보 보안과 관련된 격리 메커니즘을 제공합니다.
Kubernetes를 배포할 때, 애플리케이션의 런타임 환경을 위한 기반도 설정하는 셈이에요. Kubernetes 클러스터(또는 여러 클러스터)가 바로 그것이죠. 그 인프라는 상위 계층이 기대하는 보안 보장을 제공해야 합니다.
러타임(Runtime) 수명주기 단계
Runtime 단계는 접근(access), 컴퓨트(compute), 스토리지(storage)라는 세 가지 중요한 영역으로 구성됩니다.
런타임 보호: 접근 (Runtime protection: access)
Kubernetes API가 클러스터가 작동하게 만드는 핵심이에요. 이 API를 보호하는 것은 효과적인 클러스터 보안을 제공하는 데 핵심입니다.
Kubernetes 문서의 다른 페이지들은 접근 통제의 특정 측면을 설정하는 방법에 대해 더 자세히 설명합니다. 보안 체크리스트(security checklist)는 클러스터에 대해 권장되는 기본 검사를 제공해요.
그 너머로, 클러스터를 안전하게 만드는 것은 API 접근에 대한 효과적인 인증(authentication)과 권한 부여(authorization)를 구현하는 것을 의미합니다. ServiceAccount를 사용해서 워크로드와 클러스터 컴포넌트를 위한 보안 신원을 제공하고 관리해요.
Kubernetes는 API 트래픽을 보호하기 위해 TLS를 사용합니다. TLS를 사용하도록 클러스터를 배포하고(노드와 컨트롤 플레인 사이의 트래픽도 포함), 암호화 키를 보호해야 합니다. Kubernetes 자체 API를 CertificateSigningRequests에 사용한다면, 그곳에서의 오용을 제한하는 데 특별한 주의를 기울이세요.
런타임 보호: 컴퓨트 (Runtime protection: compute)
컨테이너는 두 가지를 제공합니다. 애플리케이션 간의 격리와, 그것들을 결합해서 같은 호스트 컴퓨터에서 실행하게 만드는 메커니즘이에요. 격리와 집합이라는 이 두 측면은 런타임 보안이 트레이드오프를 식별하고 적절한 균형을 찾는 것을 포함한다는 것을 의미합니다.
Kubernetes는 컨테이너를 설정하고 실행하기 위해 컨테이너 런타임(container runtime)에 의존합니다. Kubernetes 프로젝트는 특정 컨테이너 런타임을 권장하지 않으며, 여러분이 선택한 런타임이 정보 보안 요구를 충족하는지 확인해야 해요.
런타임에서 컴퓨트를 보호하려면 다음을 할 수 있어요.
- 애플리케이션에 파드 보안 표준(Pod Security Standards)을 강제해서 필요한 권한으로만 실행되도록 돕습니다.
- 컨테이너화된 워크로드를 실행하기 위해 특별히 설계된 전문화된 운영체제를 노드에서 실행하세요. 이는 일반적으로 컨테이너를 실행하는 데 필수적인 서비스만 제공하는 읽기 전용 운영체제(불변 이미지, immutable image)를 기반으로 합니다. 컨테이너 전용 운영체제는 시스템 컴포넌트를 격리하고 컨테이너 탈출(container escape)의 경우 공격 표면을 줄이는 데 도움을 줍니다.
- 공유 리소스를 공정하게 할당하기 위해 ResourceQuota를 정의하고, 파드가 자원 요구를 지정하도록 보장하기 위해 LimitRange 같은 메커니즘을 사용합니다.
- 워크로드를 서로 다른 노드에 분할해서 격리를 개선하세요. Kubernetes 자체 또는 생태계의 노드 격리(node isolation) 메커니즘을 사용해서 신뢰 맥락이 다른 파드가 별도의 노드 집합에서 실행되도록 보장합니다.
- 보안 제한을 제공하는 컨테이너 런타임을 사용해요.
- Linux 노드에서는 AppArmor나 seccomp 같은 Linux 보안 모듈을 사용합니다.
런타임 보호: 스토리지 (Runtime protection: storage)
클러스터와 그곳에서 실행되는 애플리케이션의 스토리지를 보호하려면 다음을 할 수 있어요.
- 볼륨에 대한 저장 시 암호화를 제공하는 외부 스토리지 플러그인과 클러스터를 통합합니다.
- API 객체에 대해 저장 시 암호화(encryption at rest)를 활성화해요.
- 백업을 사용해서 데이터 내구성을 보호하고, 필요할 때마다 복원할 수 있는지 검증합니다.
- 클러스터 노드와 그들이 의존하는 모든 네트워크 스토리지 사이의 연결을 인증해요.
- 자체 애플리케이션 내에서 데이터 암호화를 구현합니다.
암호화 키의 경우, 전문화된 하드웨어에서 생성하는 것이 노출 위험에 대한 최상의 보호를 제공합니다. *하드웨어 보안 모듈(hardware security module)*은 보안 키가 다른 곳으로 복사되는 것을 허용하지 않으면서 암호화 작업을 수행하게 해줍니다.
네트워킹과 보안 (Networking and security)
NetworkPolicy나 서비스 메시(service mesh) 같은 네트워크 보안 조치도 고려해야 해요. 일부 Kubernetes용 네트워크 플러그인은 가상 사설망(VPN) 오버레이 같은 기술을 사용해서 클러스터 네트워크에 대한 암호화를 제공합니다. 설계상 Kubernetes는 클러스터에 자체 네트워킹 플러그인을 사용하도록 허용합니다. 관리형 Kubernetes를 사용한다면 제공자가 이미 네트워크 플러그인을 선택했을 수도 있어요.
선택한 네트워크 플러그인과 그것을 통합하는 방식은 전송 중 정보의 보안에 큰 영향을 미칠 수 있습니다.
관측성과 런타임 보안 (Observability and runtime security)
Kubernetes는 추가 도구로 클러스터를 확장하게 해줍니다. 애플리케이션과 그들이 실행되는 클러스터를 모니터링하거나 문제를 해결하는 데 도움을 주는 제3자 솔루션을 설정할 수 있어요. Kubernetes 자체에도 기본적인 관측성 기능이 내장되어 있습니다. 컨테이너에서 실행되는 코드는 로그를 생성하고, 메트릭을 게시하거나, 다른 관측성 데이터를 제공할 수 있어요. 배포 시점에 클러스터가 거기에 적절한 수준의 보호를 제공하는지 확인해야 합니다.
메트릭 대시보드나 비슷한 것을 설정한다면, 그 대시보드에 데이터를 채우는 컴포넌트 체인과 대시보드 자체를 검토하세요. 전체 체인이 충분한 복원력과 무결성 보호로 설계되어, 클러스터가 저하될 수 있는 사고 중에도 그것을 신뢰할 수 있는지 확인합니다.
적절한 곳에서는 암호화적으로 측정된 부팅(cryptographically measured boot)이나 인증된 시간 배포(authenticated distribution of time) 같은 Kubernetes 계층 아래의 보안 조치를 배포하세요. 이는 로그와 감사 기록의 충실도를 보장하는 데 도움이 됩니다.
높은 보증(high-assurance) 환경의 경우, 로그가 변조 방지되고 기밀임을 보장하기 위해 암호화 보호를 배포합니다.
다음 단계 (What's next)
클라우드 네이티브 보안
- 클라우드 네이티브 보안에 관한 CNCF 백서.
- 소프트웨어 공급망 보안 모범 사례에 관한 CNCF 백서.
- Fixing the Kubernetes clusterf**k: Understanding security from the kernel up (FOSDEM 2020)
- Kubernetes Security Best Practices (Kubernetes Forum Seoul 2019)
- Towards Measured Boot Out of the Box (Linux Security Summit 2016)
Kubernetes와 정보 보안
- Kubernetes 보안
- 클러스터 보안 유지하기
- 컨트롤 플레인을 위한 전송 중 데이터 암호화
- 저장 시 데이터 암호화
- Kubernetes의 시크릿
- Kubernetes API 접근 통제하기
- 파드를 위한 네트워크 정책
- 파드 보안 표준
- RuntimeClass