90DaysOfDevOps (Day 9)

고태규·2025년 9월 14일

DevOps

목록 보기
8/51
post-thumbnail

해당 스터디는 90DaysOfDevOps
https://github.com/MichaelCade/90DaysOfDevOps
를 기반으로 진행한 내용입니다.

Day 9 - Why should developers care about container security?


1.컨테이너 보안


개발자로서 어플리케이션을 컨테이너화하기 시작하면, 새로운 문제들을 고려해야 한다.

과거에는 운영체제 패키지, 파일권한 같은 문제들을 운영팀이나 보안팀이 처리해주었으나, 이제는 해당 설정들이 Dockerfile이나 다른 설정 파일 (Manifest) 형태로 코드 바로 옆에 위치하게 된다.

문제는 대부분 개발자들은 어떤 운영체제 배포판이 더 보안적으로 우수한지, 특정 패키지가 왜 필요한지 전문적인 지식이 없다. 이로 인해 자신도 모르게 보안 취약점을 만들 수 있다.

따라서, 해당 강의에서는 Snyk과 같은 도구를 사용하여 개발 초기 단계에서 이를 탐지하고 수정하는 방법인 Shift-Left Security 알려지지 않은 위협에 대비하기 위한 심층방어 (Defense-in-Depth) 전략을 제시한다.


2. 개발 초기 단계에 탐지,수정 (Shift-Left Security)


해당 방식을 사용하기 위해 먼저 시나리오를 제시한다.

시나리오: 취약한 레거시 어플리케이션 해킹

  1. 시나리오의 앱의 Dockerfile은 Maven으로 앱을 빌드하고, 공식 Tomcat 이미지를 베이스로 사용하여 빌드 결과물을 올리고 실행
  2. 해커의 입장에서 Apache Tomcat의 보안 패치 내역을 살펴보던 중, Tomcat 8.5.23 이전 버전에 '원격 코드 실행 (Remote Code Execution) 취약점'이 있었다는 사실을 발견
  3. 오래된 취약점은 보통 공격용 스크립트 (Proof of Concept, PoC) 존재함. -> Exploit-DB에서 취약점을 공격하는 Python 스크립트 발견
  4. 공격용 스크립트를 사용하여 서버에 파일 주입하여, 서버의 명령어를 실행할 수 있게됨.
    • whoami -> root 권한 확인. 컨테이너 내부의 최고 관리자 권한을 획득.
    • touch /etc/foo -> 시스템 폴더에 파일 생성 성공. 파일 시스템에 쓰기 권한이 있음을 의미.
    • curl google.com -> 외부 인터넷 통신 성공. 악성 스크립트를 추가로 다운로드할 수 있는 경로 확보.
    • apt update -> 패키지 매니저 사용 가능. nmap과 같은 추가 공격 도구를 설치하여 내부망의 다른 시스템을 공격하는 발판으로 삼을 수 있음.

이처럼 단순히 레거시 어플리케이션 버전을 사용함으로써 이미 인터넷에 존재하는 PoC를 통해 쉽게 컨테이너에 접근하여 해킹을 진행할 수 있다.


이러한 해킹 상황이 발생하기 전에, 개발자가 미리 막기 위해 Snyk라는 툴을 사용하여 로컬에서 빌드한 이미지를 스캔하여 보안적 취약점을 분석할 수 있다.

Snyk은 이미지의 모든 패키지를 분석하고 '구성 요소 명세서 (BOM)'을 만든뒤, Synk의 취약점 데이터 베이스와 비교한다.

# Snyk (보안 취약점 분석 도구)를 이용한 컨테이너 보안 취약점 확인 명령어
# java-goof 이름의 컨테이너 이미지를 분석
snyk container test java-goof --file=Dockerfile

해당 사진처럼, Snyk가 제공하는 수많은 단순 CVE (Common Vulnerabilites and Exposures) 목록과 함께 '실행 가능한 조언'이 출력으로 나온다. 이는 보안 전문가가 아닌 개발자도 문제를 명확히 인지하고 즉각적인 조치를 취할 수 있도록 돕는다.

해당 이미지 '실행 가능한 조언' 의미

"현재 베이스 이미지(tomcat:8.5.21)는 735개의 취약점을 가지고 있습니다. 하지만 tomcat:8.5.97 버전으로 업데이트하면, 심각/높음 등급의 취약점은 0개가 되고 총 취약점 수도 28개로 크게 줄어듭니다."

Snyk를 이용하여 베이스 이미지의 보안 취약점을 미리 알 수 있으며, 이후 Dockerfile에 베이스 이미지 버전을 업그레이드하여 다시 빌드하게 되면 취약점이 대폭 줄어든 것을 확인할 수 있다.

추가적으로, 해당 모든 과정은 GitHub 연동을 통해 취약점 수정 pull Request를 자동으로 생성하는 방식으로 자동화할 수 있다. CI/CD 파이프라인에 통합하면 코드가 푸시될 때마다 자동으로 보안 검사를 수행하여, 개발자는 코드에만 집중하면서도 높은 보안 수준을 유지할 수 있다


3. 자동화 및 심층 방어 (Defense-in Depth)


앞서 말한 Shift-Left Security 방식을 사용하여 개발자가 개발 초기에 베이스 이미지에 대한 취약점을 보완할 수 있고, 알려진 취약점 외에 Log4Shell 같은 제로데이 공격 (방어하는 쪽에서 해당 공격을 막을 수 있는 대응책이 나온날이 0일) 에 대비하기 위해 어려 계층의 방어막을 구축해야한다.


  • 1단계: 이미지 강화 (Image Hardening)

    • 최소화: slim 버전처럼 꼭 필요한 파일만 포함된 베이스 이미지를 사용하여 공격자가 악용할 도구(curl, apt 등)를 사전에 제거
    • 보안 공급망: Docker Hub 공식 이미지나 자체 검증된 레지스트리의 이미지처럼 신뢰할 수 있는 출처의 이미지만 사용
    • 빌드 전략: 멀티스테이지 빌드를 활용하고, Jib(Java)나 ko(Go)처럼 보안에 최적화된 빌드 도구를 고려
  • 2단계: 런타임 방어 (Runtime Defenses)

    • 최소 권한 원칙: 컨테이너를 절대 root로 실행하지 않고, 권한 없는 일반 사용자(non-root user)로 실행
    • 권한 상승 방지: 컨테이너 내부에서 해커가 권한을 상승시킬 수 없도록 설정
    • 읽기 전용 파일 시스템: 컨테이너의 루트 파일 시스템을 읽기 전용(Read-Only)으로 설정하여 악성 파일 쓰기나 설정 변경을 원천적으로 차단
  • 3단계: 쿠버네티스 보안 (Orchestrator Security)

    • Secret 관리: 비밀번호, API 키 등은 쿠버네티스 시크릿(Secret)이나 Vault 같은 전문 관리 도구를 사용
    • RBAC (역할 기반 접근 제어): 서비스 계정에 필요한 최소한의 권한만 부여하여 권한 남용을 막기
    • 네트워크 정책 (Network Policy): 제로 트러스트 원칙에 따라 기본적으로 모든 Pod 간 통신을 차단하고, 허용된 통신만 명시적으로 정의하여 공격 전파를 막기
    • 어드미션 컨트롤러: 보안 정책에 위배되는 Pod(예: root로 실행되는 컨테이너)가 클러스터에 배포되지 않도록 사전에 차단

결론적으로, 우리가 아직 알지 못하는 제로데이 공격에 대비하기 위해, 하나의 보안 솔루션이나 방법에만 의존하지 않고, 각기 다른 역할을 하는 여러 보안 장치를 쌓아올려, 공격자가 공격하기 최대한 어렵고 복잡하게 만들어야 한다.


4. 결론


컨테이너 환경에서 보안은 더이상 운영팀, 보안팀의 일이 아닌, 개발자의 핵심 책임이 되었다.

따라서, 개발자는 'Shift-Left' 접근법을 통해 Snyk과 같은 도구로 '개발 초기에 알려진 취약점을 빠르게 수정' 해야 한다.

동시에, 아직 알려지지 않은 위협에 대비하기 위해 이미지, 런타임, 쿠버네티스에 걸친 '심층 방어' 전략으로 견고하고 다층적인 보안체계를 구축해야한다.

0개의 댓글