Amazon ECS 태스크 및 컨테이너 보안 모범 사례
컨테이너 이미지를 공격에 대한 첫 번째 방어선으로 보아야 합니다. 이미지가 안전하지 않고 잘못 구성되어 있으면 공격자가 컨테이너의 경계를 벗어나 호스트에 액세스할 수 있습니다. 이러한 상황이 발생할 위험을 줄이려면 다음과 같이 해야 합니다.
작업 및 컨텐이너를 설정할 때 다음을 수행하는 것이 좋습니다.
최소로 생성하거나 distroless 이미지 사용
먼저 컨테이너 이미지에서 불필요한 바이너리를 모두 제거합니다. Amazon ECR 퍼블릭 갤러리의 익숙하지 않은 이미지를 사용하는 경우 이미지를 검사하여 각 컨테이너 레이어의 콘텐츠를 참조하는지 확인합니다. 이를 위해 Dive
또는 애플리케이션과 해당 런타임 종속성만 포함하는 distroless 이미지를 사용할 수도 있습니다. 이런 이미지는 패키지 관리자 또는 셸을 포함하지 않습니다. Distroless 이미지는 “스캐너의 신호 대 노이즈 비율을 개선하고 프로비넌스를 필요한 만큼으로 설정하여 부담을 줄입니다”. 자세한 내용을 알아보려면 GitHub 설명서의 distroless
Docker에는 scratch라고 하는 예약된 최소 이미지에서 이미지를 생성하는 메커니즘이 있습니다. 자세한 내용은 Docker 설명서의 Creating a simple parent image using scratch
############################ # STEP 1 build executable binary ############################ FROM golang:alpine AS builder # Install git. # Git is required for fetching the dependencies. RUN apk update && apk add --no-cache git WORKDIR $GOPATH/src/mypackage/myapp/ COPY . . # Fetch dependencies. # Using go get. RUN go get -d -v # Build the binary. RUN go build -o /go/bin/hello ############################ # STEP 2 build a small image ############################ FROM scratch # Copy our static executable. COPY --from=builder /go/bin/hello /go/bin/hello # Run the hello binary. ENTRYPOINT ["/go/bin/hello"] This creates a container image that consists of your application and nothing else, making it extremely secure.
앞의 예제는 다단계 빌드의 예이기도 합니다. 이러한 유형의 빌드는 컨테이너 레지스트리로 푸시되는 최종 이미지의 크기를 최소화하는 데 사용할 수 있으므로 보안 측면에서 매력적입니다. 빌드 도구 및 기타 불필요한 바이너리가 없는 컨테이너 이미지는 이미지의 공격 표면을 줄여 보안 태세를 향상합니다. 다단계 빌드에 대한 자세한 내용은 Docker 설명서의 다단계 빌드
이미지를 스캔하여 취약성 확인
컨테이너 이미지는 해당하는 가상 머신과 마찬가지로 취약성이 있는 바이너리 및 애플리케이션 라이브러리를 포함하거나 시간에 따라 취약성이 증가할 수 있습니다. 악용을 방지하는 가장 좋은 방법은 이미지 스캐너로 이미지를 정기적으로 스캔하는 것입니다.
Amazon ECR에 저장된 이미지는 푸시할 때 스캔하거나 온디맨드로 스캔(24시간마다 한 번)할 수 있습니다. Amazon ECR 기본 스캔에서는 오픈 소스 이미지 스캔 솔루션인 ClairHIGH
또는 CRITICAL
취약성이 있는 이미지는 삭제하거나 다시 빌드해야 합니다. 배포된 이미지에서 취약성이 발견되면 가능한 한 빨리 교체해야 합니다.
Docker Desktop Edge 버전 2.3.6.0
-
Automating image compliance using Amazon ECR and AWS Security Hub
에서는 AWS Security Hub에서 Amazon ECR의 취약성 정보를 표시하고 취약한 이미지에 대한 액세스를 차단하여 문제 해결을 자동화하는 방법을 설명합니다.
이미지에서 특수 권한 제거
액세스 권한 플래그 setuid
및 setgid
가 지정되면 실행 파일의 소유자 또는 그룹의 권한으로 실행 파일을 실행할 수 있습니다. 이러한 액세스 권한이 있는 바이너리는 권한을 에스컬레이션하는 데 사용될 수 있으므로 이미지에서 모두 제거하세요. 악의적인 목적으로 사용될 수 nc
및 curl
과 같은 셸 및 유틸리티를 모두 제거하는 것이 좋습니다. setuid
및 setgid
액세스 권한이 있는 파일을 찾으려면 다음 명령을 사용할 수 있습니다.
find / -perm /6000 -type f -exec ls -ld {} \;
이러한 파일에서 이러한 특수 권한을 제거하려면 컨테이너 이미지에 다음 지시문을 추가합니다.
RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true
큐레이팅한 이미지 세트 생성
개발자가 직접 이미지를 생성하도록 하지 말고, 조직의 다양한 애플리케이션 스택에 대해 검증된 이미지 세트를 생성하세요. 이렇게 하면 개발자는 Dockerfile 작성 방법을 배울 필요 없이 코드 작성에 집중할 수 있습니다. 변경 사항이 코드베이스에 병합되면 CI/CD 파이프라인은 자산을 자동으로 컴파일한 다음 아티팩트 리포지토리에 저장할 수 있습니다. 그리고 마지막으로, 아티팩트를 적절한 이미지에 복사한 다음 Amazon ECR과 같은 Docker 레지스트리로 푸시할 수 있습니다. 최소한 기본 이미지 세트를 생성해야 합니다. 그래야만 개발자가 이를 바탕으로 자체 Dockerfile을 생성할 수 있습니다. 이미지를 Docker Hub에서 가져오지 마세요. 이미지에 무엇이 들어 있는지 항상 알 수 있는 것은 아니며, 상위 1000개 이미지 중 약 5분의 1에 취약성이 있습니다. 이러한 이미지의 목록과 취약성은 https://vulnerablecontainers.org/
애플리케이션 패키지 및 라이브러리에서 취약성 스캔
이제는 오픈 소스 라이브러리를 일반적으로 사용합니다. 운영 체제 및 OS 패키지와 마찬가지로 이러한 라이브러리에는 취약성이 있을 수 있습니다. 개발 수명 주기의 일부로 이러한 라이브러리를 스캔하고 중요한 취약성이 발견되면 업데이트해야 합니다.
Docker Desktop은 Snyk를 사용하여 로컬 스캔을 수행합니다. Snyk는 오픈 소스 라이브러리의 취약성과 잠재적 라이선스 문제를 찾는 데에도 사용할 수 있습니다. 개발자 워크플로에 직접 통합하여 오픈 소스 라이브러리로 인한 위험을 완화할 수 있습니다. 자세한 정보는 다음의 주제를 참조하세요.
-
Open Source Application Security Tools
에는 애플리케이션의 취약성을 탐지하기 위한 도구 목록이 포함되어 있습니다.
정적 코드 분석 수행
컨테이너 이미지를 빌드하기 전에 정적 코드 분석을 수행해야 합니다. 이 분석은 소스 코드를 대상으로 수행되며 코딩 오류뿐 아니라 오류 주입과 같이 악의적인 행위자가 악용할 수 있는 코드를 식별하는 데 사용됩니다. Amazon Inspector를 사용할 수 있습니다. 자세한 내용은 Amazon Inspector 사용 설명서의 Amazon Inspector로 Amazon ECR 컨테이너 이미지 스캔을 참조하세요.
루트가 아닌 사용자로 컨테이너 실행
루트가 아닌 사용자로 컨테이너를 실행해야 합니다. 기본적으로 컨테이너는 Dockerfile에 USER
지시문이 포함되어 있지 않으면 root
사용자로 실행됩니다. Docker에서 할당하는 기본 Linux 기능에 따라 root
로 실행할 수 있는 작업이 제한되지만, 그 효과는 미미합니다. 예를 들어 root
로 실행되는 컨테이너는 여전히 디바이스에 액세스할 수 없습니다.
CI/CD 파이프라인의 일부로 Dockerfiles를 lint하여 USER
지시문을 찾고 이 지시문이 없으면 빌드할 수 없게 해야 합니다. 자세한 정보는 다음의 주제를 참조하세요.
-
Dockerfile-lint
는 파일이 모범 사례를 따르는지 확인하는 데 사용할 수 있는 RedHat의 오픈 소스 도구입니다. -
Hadolint
는 모범 사례를 준수하는 Docker 이미지를 빌드하기 위한 또 다른 도구입니다.
읽기 전용 루트 파일 시스템 사용
읽기 전용 루트 파일 시스템을 사용해야 합니다. 컨테이너의 루트 파일 시스템은 기본적으로 쓰기 가능합니다. RO
(읽기 전용) 루트 파일 시스템으로 컨테이너를 구성하면 데이터를 유지할 수 있는 위치를 명시적으로 정의해야 합니다. 이 경우 특별히 권한을 부여받지 않는 한 컨테이너의 파일 시스템에 쓸 수 없으므로 공격 표면이 줄어듭니다.
참고
읽기 전용 루트 파일 시스템을 사용하면 파일 시스템에 쓸 수 있어야 하는 특정 OS 패키지에서 문제가 발생할 수 있습니다. 읽기 전용 루트 파일 시스템을 사용할 계획이라면 사전에 철저히 테스트하세요.
CPU 및 메모리 제한과 함께 작업 구성(Amazon EC2)
CPU 및 메모리 제한과 함께 작업을 구성하여 다음과 같은 위험을 최소화해야 합니다. 작업의 리소스 제한은 작업 내의 모든 컨테이너에서 예약할 수 있는 CPU 및 메모리 양의 상한을 설정합니다. 제한을 설정하지 않으면 작업에서 호스트의 CPU와 메모리에 액세스할 수 있습니다. 이로 인해 공유 호스트에 배포된 작업이 다른 작업의 시스템 리소스를 부족하게 만드는 문제가 발생할 수 있습니다.
참고
AWS Fargate 기반 Amazon ECS 작업에서는 CPU 및 메모리 제한 값이 결제 목적으로 사용되므로 이러한 값을 지정해야 합니다. Amazon ECS Fargate에서는 각 작업이 자체 전용 인스턴스에서 실행되므로 하나의 작업이 시스템 리소스를 모두 독차지하더라도 문제가 되지 않습니다. 메모리 제한을 지정하지 않는 경우 Amazon ECS는 각 컨테이너에 최소 4MB를 할당합니다. 마찬가지로 작업의 CPU 제한을 설정하지 않으면 Amazon ECS 컨테이너 에이전트는 최소 2개 CPU를 할당합니다.
Amazon ECR에서 변경 불가능한 태그 사용
Amazon ECR에서는 변경 불가능한 태그를 사용하여 이미지를 구성할 수 있으며, 구성해야 합니다. 이렇게 하면 이미지의 변경 또는 업데이트된 버전을 동일한 태그를 사용하여 이미지 리포지토리로 푸시하지 못하게 됩니다. 따라서 공격자가 손상된 버전의 이미지를 동일한 태그가 지정된 이미지에 푸시하는 것을 방지할 수 있습니다. 변경 불가능한 태그를 사용하면 결과적으로 변경할 때마다 다른 태그의 새 이미지를 푸시할 수밖에 없게 됩니다.
컨테이너를 privileged로 실행하지 않음(Amazon EC2)
컨테이너를 privileged로 실행하지 않아야 합니다. 백그라운드의 경우 privileged
로 실행되는 컨테이너는 호스트에서 확장된 권한으로 실행됩니다. 즉, 이 컨테이너는 호스트에서 root
에 할당된 Linux 기능을 모두 상속합니다. 이 파라미터 사용을 엄격하게 제한하거나 금지해야 합니다. Amazon ECS 컨테이너 에이전트 환경 변수 ECS_DISABLE_PRIVILEGED
를 true
로 설정하여 privileged
가 필요하지 않은 경우 특정 호스트에서 컨테이너가 privileged
로 실행되지 않게 하는 것이 좋습니다. 또는 AWS Lambda를 사용하여 작업 정의를 스캔하고 privileged
파라미터를 사용하는지 확인할 수 있습니다.
참고
AWS Fargate 기반 Amazon ECS에서는 컨테이너를 privileged
로 실행할 수 없습니다.
컨테이너에서 불필요한 Linux 기능 제거
다음은 Docker 컨테이너에 할당되는 기본 Linux 기능의 목록입니다. 각 기능에 대한 자세한 내용은 Overview of Linux Capabilities
CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_SETPCAP, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SYS_CHROOT, CAP_MKNOD, CAP_AUDIT_WRITE, CAP_SETFCAP
컨테이너에서 위에 나열된 Docker 커널 기능 중 필요하지 않은 것이 있으면 컨테이너에서 삭제하는 것이 좋습니다. 각 Docker 커널 기능에 대한 자세한 내용은 KernalCapabilities를 참조하세요. 다음을 수행하여 사용 중인 기능을 확인할 수 있습니다.
고객 관리형 키(CMK)를 사용하여 Amazon ECR로 푸시된 이미지 암호화
고객 관리형 키(CMK)를 사용하여 Amazon ECR로 푸시된 이미지를 암호화해야 합니다. Amazon ECR로 푸시된 이미지는 저장 시 AWS Key Management Service(AWS KMS) 관리형 키를 사용하여 자동으로 암호화됩니다. 대신 자체 키를 사용하고 싶은 경우 이제 Amazon ECR에서는 고객 관리형 키(CMK)를 사용한 AWS KMS 암호화를 지원합니다. CMK를 사용하여 서버 측 암호화를 활성화하기 전에 설명서의 저장된 데이터 암호화에 열거된 고려 사항을 검토하세요.