컨테이너 보안: DevOps 환경에서 필수적인 요소
DevOps 환경에서 컨테이너는 더 이상 새로운 개념이 아닙니다. 컨테이너는 대규모 애플리케이션과 마이크로서비스를 실행하는 데 필요한 모든 것을 담고 있는 격리된 가상 환경, 즉 ‘샌드박스’와 같습니다.
컨테이너는 애플리케이션 실행에 필요한 모든 요소(예: 런타임 환경, 바이너리 코드 등)를 한 곳에 모아 패키징하는 시스템으로 이해할 수 있습니다.
컨테이너 기술은 개발자가 애플리케이션을 여러 환경으로 이동시키는 과정을 단순화합니다. 예를 들어, 로컬 시스템에서 가상 환경으로, 개발 단계에서 프로덕션 환경으로 애플리케이션을 쉽게 배포할 수 있게 해 줍니다. 이를 통해 개발 및 프로덕션 환경 간의 소프트웨어 및 구성 설정 불일치로 인한 문제를 해결하는 데 도움이 됩니다.
Statista의 보고서에 따르면, 전 세계 조직의 절반이 컨테이너 오케스트레이션 기술을 활용하고 있습니다. 컨테이너 기술 도입은 그 유용성에 따라 계속 증가하고 있지만, 보안을 간과하면 사이버 공격의 통로가 될 수 있다는 점을 명심해야 합니다.
CVE Details와 같은 보안 취약점 데이터베이스에 따르면, 작성 시점을 기준으로 62개의 Docker 관련 맞춤형 취약점이 발견되었습니다. 성공적인 DevOps 프로세스를 위해서는 이러한 보안 위협에 대응하고 컨테이너를 보호하기 위한 모범 사례가 반드시 필요합니다.
이 글에서는 컨테이너 보안의 개념을 상세히 분석하고, 주요 문제점을 강조하며, 컨테이너 기술 사용 시 적용해야 할 모범 사례를 제시합니다.
컨테이너 보안이란 무엇인가?
컨테이너 보안은 컨테이너와 그 환경을 잠재적인 위협으로부터 보호하기 위해 보안 프로토콜(도구 및 정책)을 지속적으로 사용하는 프로세스입니다.
보안 조치를 제대로 취하지 않으면, 애플리케이션, 인프라, 런타임 환경, 시스템 라이브러리, 운영 체제 및 커널 등 다양한 요소가 공격에 노출될 수 있습니다.
컨테이너는 일시적이며, 동적 배포 및 확장이 가능하다는 점을 고려할 때, 자동화된 보안과 소프트웨어 개발 수명 주기(SDLC)의 모든 단계에서 보안을 적용해야 합니다.
참고: 초보자를 위한 Kubernetes Kops 소개
컨테이너 보안의 주요 과제는 무엇인가?
컨테이너는 소프트웨어 제공 속도 향상과 같은 여러 장점을 제공하지만, 자체적인 보안 기능이 부족하기 때문에 여러 가지 보안 문제에 취약합니다.
컨테이너는 호스트 운영 체제(OS)를 통해 하드웨어에 접근하기 때문에, 하나의 컨테이너에 여러 개의 기본 컨테이너 이미지가 포함될 수 있습니다. 이는 공격 표면을 넓혀 다양한 보안 문제를 야기할 수 있습니다.
첫 번째 주요 과제는 잘못된 컨테이너 구성입니다. 개발자들이 기본 컨테이너 설정을 그대로 사용하거나, 애플리케이션에 적합하지 않은 설정을 사용할 수 있습니다. 예를 들어, 노출된 보안 포트, 암호, 인증 토큰 등의 자격 증명 유출, 컨테이너 런타임을 루트 권한으로 실행하는 경우 등이 있습니다. 이러한 기본 설정은 공격자에게 손쉬운 공격 기회를 제공할 수 있습니다.
두 번째 과제는 컨테이너 인프라의 취약성입니다. 애플리케이션 코드, 라이브러리, 구성 파일과 같은 컨테이너 내장 패키지 또는 호스트 운영 체제 패키지에 취약점이 있을 수 있습니다. 이러한 취약성은 애플리케이션 수명 주기의 모든 단계에서 발생할 수 있습니다. 예를 들어, 외부 종속성이 컨테이너 이미지에 빌드되거나, 오픈 소스 라이브러리가 애플리케이션의 일부로 설치되거나, 타사 컨테이너 레지스트리나 호스트에서 기본 이미지를 가져오는 경우 등이 해당됩니다. 이러한 취약점은 네트워크 및 엔드포인트를 통해 악용될 수 있습니다.
세 번째 과제는 컨테이너 워크로드에 대한 가시성 부족입니다. 컨테이너의 동적인 특성 때문에 모니터링 도구가 실행 중인 컨테이너를 찾고 네트워크 동작을 제대로 검사하기 어렵습니다. 가시성 개선은 보안 위반을 방지하고 발생 시 대응 시간을 단축하는 데 중요합니다.
마지막으로, CI/CD 파이프라인의 모든 단계에서 보안이 확보되지 않으면 컨테이너가 취약해집니다. 애플리케이션 수명 주기가 끝날 때 개발자가 보안 문제를 해결해야 하지만, 개발 초기 단계부터 보안을 관리하면 앱을 더욱 효과적으로 보호할 수 있습니다.
컨테이너 보안 문제를 해결하는 데 도움이 되는 도구는 무엇인가?
보안 도구를 사용하면 컨테이너의 보안 및 무결성을 유지하고, 배포된 엔터프라이즈 솔루션을 안전하게 보호할 수 있습니다. 이러한 도구는 취약점을 검색하고, 공격, 버그 또는 기타 문제점을 지속적으로 모니터링합니다.
컨테이너 보안 도구는 오픈 소스 또는 상업용으로 제공됩니다. 모든 도구는 컨테이너 인프라를 감사하고, 일반적인 취약점 및 노출(CVE)을 탐지하는 기능을 제공합니다.
다음은 몇 가지 유용한 도구 목록입니다: Pingsafe Editors Choice, Datadog Cloud SIEM, Anchore, Sophos Cloud-Native Security, Bitdefender GravityZone, Sysdig secure, Aqua Security 및 RedHat Advanced Cluster Security for Kubernetes.
참고: 취약점 분석을 위한 11가지 컨테이너 보안 스캐너
컨테이너 보안을 위한 모범 사례
앞서 언급한 컨테이너 보안 문제에도 불구하고, 다음은 애플리케이션 수명 주기의 모든 단계에서 컨테이너 보안을 최적화하기 위해 구현할 수 있는 모범 사례입니다.
이미지 보안
컨테이너 이미지는 컨테이너를 만드는 데 사용됩니다. 잘못된 설정이나 악의적인 요소로 인해 프로덕션 환경에서 컨테이너 취약점이 발생할 수 있습니다. 다음과 같은 방법으로 보안을 강화할 수 있습니다.
- 신뢰할 수 있는 이미지 사용: 이미지를 직접 만들지 않을 때는 항상 신뢰할 수 있는 소스의 이미지를 선택하십시오. Docker Hub와 같은 공개 리포지토리에는 악성코드나 구성 오류가 포함된 이미지가 있을 수 있습니다.
- 필요한 구성 요소만 포함: 애플리케이션에 필요하지 않은 구성 요소는 제거하는 것이 가장 좋습니다. 예를 들어, UNIX 시스템은 ‘awk’ 및 ‘sed’ 바이너리를 기본적으로 제공합니다.
- 컨테이너 이미지에 애플리케이션 포함: 컨테이너 이미지는 운영 체제(OS)와 실행 중인 애플리케이션의 하위 집합을 포함합니다. 컨테이너에 포함된 모든 도구와 라이브러리는 잠재적인 위협 요소가 될 수 있습니다. 이러한 위험을 줄이려면 컨테이너 이미지에 애플리케이션 자체를 포함시키는 것이 좋습니다. 이 방법은 필요한 모든 종속성이 포함된 정적으로 컴파일된 바이너리를 통해 구현할 수 있습니다.
취약점 및 관리 스캔 자동화
컨테이너 및 호스트에 대한 정기적인 취약점 검색 및 관리는 애플리케이션 수명 주기의 모든 단계에서 취약점을 감지하는 데 도움이 됩니다.
코드 스캔을 실행하여 버그를 감지하고, 정적 애플리케이션 보안 테스트(SAST)를 실행하여 애플리케이션 코드의 취약점을 찾을 수 있습니다. 소프트웨어 구성 분석(SCA)은 공개적으로 알려진 취약점에 대한 정보를 제공하며, 소프트웨어 BOM(Bill of Materials)을 생성하여 오픈 소스 소프트웨어 구성 요소의 가시성을 확보할 수 있습니다.
이미지 스캔은 컨테이너 이미지의 내용과 빌드 프로세스를 분석하여 민감한 정보를 확인합니다. Clair와 같은 도구를 사용하여 알려진 취약점을 스캔할 수 있습니다. 또한, 컨테이너 동작을 기반으로 보안 위험을 식별하는 동적 애플리케이션 보안 테스트(DAST)를 사용할 수 있습니다. DAST 도구는 컨테이너 호스트 구성 요소(호스트 커널 및 OS)를 검사하여 잘못된 구성을 찾을 수도 있습니다.
이러한 보안 조치는 컨테이너 수명 주기 전반에 걸쳐 지속적으로 적용해야 하며, “왼쪽으로 이동(Shift Left)” 철학을 채택하는 것이 좋습니다. 이는 개발 초기 단계부터 보안을 고려해야 함을 의미합니다. 이러한 접근 방식을 선택하는 경우 Trivy와 같은 도구를 사용할 수 있습니다.
컨테이너 레지스트리 보안
컨테이너 레지스트리는 이미지를 저장하고 배포하는 중앙 집중식 방법입니다. 많은 조직에서 수천 개의 이미지를 공용 또는 개인 레지스트리에 저장합니다. 모든 팀원 및 협력자가 취약점 없는 이미지를 사용하도록 보장하기 위해 몇 가지 보안 조치를 취해야 합니다.
먼저, 개인 레지스트리의 경우 사용자 액세스 제어를 구현하여 누가 이미지를 게시하고 액세스할 수 있는지 설정해야 합니다. 이는 권한 없는 사용자가 이미지를 게시, 수정 또는 삭제하는 것을 방지하는 기본적인 보안 조치입니다.
두 번째로, 이미지 서명을 통해 이미지를 게시한 사람을 확인할 수 있도록 하여, 손상된 이미지를 대체하기 어렵게 만들 수 있습니다. Docker Content Trust 기술을 사용하여 레지스트리에서 주고받는 데이터에 디지털 서명을 추가할 수 있습니다. 마지막으로, 이미지를 지속적으로 스캔하여 심각한 취약점을 감지해야 합니다.
컨테이너 모니터링
관찰 가능성 도구를 사용하여 컨테이너 워크로드에 대한 가시성을 높일 수 있습니다. 이러한 도구는 모든 구성 요소의 취약성을 모니터링 및 테스트하고, 컨테이너 환경에 대한 실시간 이벤트 로깅을 활성화할 수 있어야 합니다.
관찰 가능성 도구는 컨테이너 스택의 모든 구성 요소에서 메트릭과 로그를 분석하여 이상 징후를 감지하고 위협을 식별합니다. 이러한 접근 방식을 통해 잘못된 구성을 즉시 수정할 수 있습니다.
리소스 사용량 메트릭을 수집하려면 cAdvisor 또는 kube-state-metrics와 같은 도구를 사용하십시오. 컨테이너 활동 및 클러스터 성능을 모니터링하려면 Grafana 또는 Prometheus와 같은 도구를 사용하십시오.
컨테이너 간의 네트워크 트래픽을 분석하려면 Wireshark 또는 tcpdump를 사용하십시오. AKS(Azure Kubernetes Service)와 같은 관리형 Kubernetes 서비스를 사용하는 경우, Azure Monitor를 사용하여 리소스 및 보안 위협을 추적하십시오. Azure Log Analytics는 AKS 리소스를 수집하고 분석할 수 있습니다. Amazon EKS를 사용하는 경우, Amazon CloudTrail을 사용하여 로깅 및 감시를 수행하고, Amazon CloudWatch를 사용하여 모니터링하십시오.
네트워크 보안 구현
네트워크 보안 제어 조치는 무단 컨테이너 액세스로부터 시스템을 보호하는 데 도움이 됩니다. 컨테이너를 격리하고 필요한 서비스에만 액세스하도록 제한하는 네트워크 세분화 전략을 적용해야 합니다.
Kubernetes에서 컨테이너화된 애플리케이션을 실행하는 경우, K8s 네트워크 정책을 사용하여 클러스터의 수신 및 발신 포드 트래픽을 구성할 수 있습니다. 이렇게 하면 레이블을 기반으로 특정 포드에 대한 트래픽이 제한됩니다.
포드 간 통신에는 전송 계층 보안(TLS)을 강화할 수 있습니다. API 서버와 다른 구성 요소 간의 보안 통신을 위해 TLS 또는 SSL(Secure Sockets Layer) 기술을 사용할 수 있습니다. 로드 밸런서는 클러스터로의 트래픽 항목을 제한하는 데에도 효과적인 솔루션입니다.
클러스터에 마이크로서비스가 있는 경우, Meshery 또는 Linkerd와 같은 서비스 메시 도구를 사용하여 안전한 트래픽을 보장할 수 있습니다. 클라우드 제공업체를 사용하여 클러스터를 호스팅하는 경우, 해당 네트워크를 보호해야 합니다. AKS(Azure Kubernetes Service)를 사용하는 경우, 네트워크 트래픽 관리를 위해 NSG(네트워크 보안 그룹)를 사용하고, Amazon EKS(Elastic Kubernetes Service)를 사용하는 경우, Amazon Virtual Private Cloud(VPC) 보안 그룹을 사용하는 것이 좋습니다.
공격 표면 감소
공격 표면을 최소화하면 서비스 속도를 향상시키고 보안 위반 가능성을 줄이는 두 가지 이점을 얻을 수 있습니다.
다단계 빌드를 사용하면 경량 이미지를 만들 수 있으며, 이는 더 적은 공격 표면과 빠른 부팅 시간, 향상된 성능을 제공합니다. Linux를 사용하는 경우, Alpine Linux, BusyBox 또는 Tiny Core Linux를 사용할 수 있습니다. Ubuntu의 경우, Ubuntu Minimal을 사용할 수 있습니다. 또한, Docker 이미지인 Scratch를 사용하여 최소한의 이미지를 처음부터 빌드할 수도 있습니다.
컨테이너 권한 제한
여기서 중요한 원칙은 특정 작업을 수행하는 데 필요한 최소한의 권한만 부여하는 것입니다. 컨테이너를 루트 권한으로 실행하면, 사용자에게 운영 체제에서 패키지 설치 또는 읽기-쓰기 작업 권한과 같은 다양한 권한이 부여됩니다.
공격자가 손상된 경우, 컨테이너 런타임에 대한 권한 상승을 통해 시스템을 장악할 수 있다는 위험이 있습니다. 따라서 두 가지 실행 가능한 해결책이 있습니다. 루트 권한 없이 컨테이너를 실행하거나, LINUX 커널 기능을 컨테이너 워크로드에 필요한 기능으로만 제한해야 합니다.
안전한 비밀 관리
컨테이너 및 도커 구성 파일에 비밀 정보를 저장해서는 안 됩니다. 여기에는 인증서, 암호, API(애플리케이션 프로그래밍 인터페이스) 키 및 토큰이 포함됩니다. 이러한 비밀이 빌드 프로세스 또는 소스 코드 이미지에 하드 코딩되어 있는 경우가 많습니다.
이 경우 중요한 데이터는 컨테이너에 포함되어 컨테이너를 제거한 후에도 중간 컨테이너 계층에 캐시됩니다. 이러한 문제를 해결하기 위해서는 AWS Secrets Manager 및 Vault와 같은 비밀 관리 솔루션을 배포하여 비밀 자격 증명을 안전하게 저장하고 관리해야 합니다.
팀 역량 강화
마지막으로, 팀에 최상의 보안 방법을 교육하는 것이 중요합니다. 모든 팀원이 보안 위협을 식별하고 대응할 수 있도록 해야 합니다.
이를 위해 팀 온보딩 프로세스에 컨테이너 보안 교육을 추가하는 것이 좋습니다. 실습 교육, 지속적인 학습 및 정기적인 보안 평가를 제공하면 DevOps 팀이 최신 보안 트렌드에 대응할 수 있도록 준비할 수 있습니다.
결론
컨테이너 보안은 소프트웨어 개발 수명 주기에서 중요한 지속적인 프로세스입니다. 애플리케이션 코드부터 컨테이너 런타임, 호스트 운영 체제, 기본 네트워크 인프라까지 모든 측면에 대한 보안을 통합하는 것이 최적의 접근 방식입니다.
컨테이너를 철저히 검증하고, 신뢰할 수 있는 소스의 컨테이너만 사용해야 합니다. 필요한 서비스만 포함되도록 컨테이너를 강화하고, 모니터링 도구를 통해 쉽게 적용할 수 있는 로깅 방법을 사용해야 합니다. 또한, 컨테이너가 전체 인프라에서 격리되도록 네트워크를 분할해야 합니다.
서비스를 통한 데이터 입력 및 출력의 유효성을 검사하기 위해 항상 이미지에 서명해야 합니다. 또한 정기적인 스캔과 침투 테스트를 통해 취약점을 확인하고 즉시 시정 조치를 취해야 합니다. 그리고 기술 환경이 발전함에 따라 항상 최신 보안 관행을 적용해야 합니다.
다음으로, 보안을 자동화하는 방법을 알아보십시오.