EC2 Image Builder의 보안 모범 사례 - EC2 Image Builder

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

EC2 Image Builder의 보안 모범 사례

EC2 Image Builder는 자체 보안 정책을 개발하고 구현할 때 고려해야 할 여러 보안 기능을 제공합니다. 다음 모범 사례는 일반적인 지침이며 완벽한 보안 솔루션을 나타내지는 않습니다. 이러한 모범 사례는 환경에 적절하지 않거나 충분하지 않을 수 있으므로 참고용으로만 사용합니다.

  • Image Builder 레시피에는 지나치게 허용적인 보안 그룹을 사용하지 않습니다.

  • 신뢰할 수 없는 계정에 있는 이미지는 공유하지 않습니다.

  • 비공개 또는 민감한 데이터가 포함된 이미지는 공개하지 않습니다.

  • 이미지 빌드 중에 사용 가능한 모든 Windows 또는 Linux 보안 패치를 적용합니다.

이미지를 테스트하여 보안 상태 및 해당 보안 규정 준수 수준을 검증하는 것이 좋습니다. Amazon Inspector와 같은 솔루션은 이미지의 보안 및 규정 준수 상태를 검증하는 데 도움이 될 수 있습니다.

Image Builder 파이프라인용 IMDSv2

Image Builder 파이프라인이 실행되면 Image Builder에서 이미지를 빌드하고 테스트하는 데 사용하는 EC2 인스턴스를 시작하기 위한 HTTP 요청을 보냅니다. 파이프라인이 시작 요청에 사용하는 IMDS 버전을 구성하려면 Image Builder 인프라 구성 인스턴스 메타데이터 설정에서 httpTokens 파라미터를 설정합니다.

참고

Image Builder가 파이프라인 빌드에서 시작하는 모든 EC2 인스턴스가 IMDSv2를 사용하도록 구성하여 인스턴스 메타데이터 검색 요청에 서명된 토큰 헤더가 필요하도록 하는 것이 좋습니다.

Image Builder 인프라 구성에 대한 자세한 내용은 EC2 Image Builder 인프라 구성 관리(을)를 참조합니다. Linux 이미지용 EC2 인스턴스 메타데이터 옵션에 대한 자세한 내용은 Linux 인스턴스용 Amazon EC2 사용 설명서의 인스턴스 메타데이터 옵션 구성하기를 참조합니다. Windows 이미지의 경우 Windows 인스턴스용 Amazon EC2 사용 설명서의 인스턴스 메타데이터 옵션 구성하기를 참조합니다.

빌드 후 정리 필요

Image Builder가 사용자 지정 이미지의 모든 빌드 단계를 완료한 후 Image Builder는 테스트 및 이미지 생성을 위해 빌드 인스턴스를 준비합니다. 스냅샷을 생성하기 위해 빌드 인스턴스를 종료하기 전에 Image Builder는 이미지의 보안을 보장하기 위해 다음과 같은 정리 작업을 수행합니다.

Linux

Image Builder 파이프라인은 최종 이미지가 보안 모범 사례를 따르는지 확인하고 스냅샷으로 전달해서는 안 되는 빌드 아티팩트 또는 설정을 제거하는 데 도움이 되는 정리 스크립트를 실행합니다. 하지만 스크립트의 일부 섹션을 건너뛰거나 사용자 데이터를 완전히 오버라이드할 수 있습니다. 따라서 Image Builder 파이프라인에서 생성된 이미지가 특정 규제 기준을 반드시 준수하는 것은 아닙니다.

파이프라인이 빌드 및 테스트 단계를 완료하면 Image Builder는 출력 이미지를 생성하기 직전에 다음 정리 스크립트를 자동으로 실행합니다.

중요

레시피의 사용자 데이터를 오버라이드하면 스크립트가 실행되지 않습니다. 이 경우 perform_cleanup(이)라는 빈 파일을 생성하는 사용자 데이터에 명령을 포함해야 합니다. Image Builder는 이 파일을 탐지하고 새 이미지를 생성하기 전에 정리 스크립트를 실행합니다.

#!/bin/bash if [[ ! -f {{workingDirectory}}/perform_cleanup ]]; then echo "Skipping cleanup" exit 0 else sudo rm -f {{workingDirectory}}/perform_cleanup fi function cleanup() { FILES=("$@") for FILE in "${FILES[@]}"; do if [[ -f "$FILE" ]]; then echo "Deleting $FILE"; sudo shred -zuf $FILE; fi; if [[ -f $FILE ]]; then echo "Failed to delete '$FILE'. Failing." exit 1 fi; done }; # Clean up for cloud-init files CLOUD_INIT_FILES=( "/etc/sudoers.d/90-cloud-init-users" "/etc/locale.conf" "/var/log/cloud-init.log" "/var/log/cloud-init-output.log" ) if [[ -f {{workingDirectory}}/skip_cleanup_cloudinit_files ]]; then echo "Skipping cleanup of cloud init files" else echo "Cleaning up cloud init files" cleanup "${CLOUD_INIT_FILES[@]}" if [[ $( sudo find /var/lib/cloud -type f | sudo wc -l ) -gt 0 ]]; then echo "Deleting files within /var/lib/cloud/*" sudo find /var/lib/cloud -type f -exec shred -zuf {} \; fi; if [[ $( sudo ls /var/lib/cloud | sudo wc -l ) -gt 0 ]]; then echo "Deleting /var/lib/cloud/*" sudo rm -rf /var/lib/cloud/* || true fi; fi; # Clean up for temporary instance files INSTANCE_FILES=( "/etc/.updated" "/etc/aliases.db" "/etc/hostname" "/var/lib/misc/postfix.aliasesdb-stamp" "/var/lib/postfix/master.lock" "/var/spool/postfix/pid/master.pid" "/var/.updated" "/var/cache/yum/x86_64/2/.gpgkeyschecked.yum" ) if [[ -f {{workingDirectory}}/skip_cleanup_instance_files ]]; then echo "Skipping cleanup of instance files" else echo "Cleaning up instance files" cleanup "${INSTANCE_FILES[@]}" fi; # Clean up for ssh files SSH_FILES=( "/etc/ssh/ssh_host_rsa_key" "/etc/ssh/ssh_host_rsa_key.pub" "/etc/ssh/ssh_host_ecdsa_key" "/etc/ssh/ssh_host_ecdsa_key.pub" "/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key.pub" "/root/.ssh/authorized_keys" ) if [[ -f {{workingDirectory}}/skip_cleanup_ssh_files ]]; then echo "Skipping cleanup of ssh files" else echo "Cleaning up ssh files" cleanup "${SSH_FILES[@]}" USERS=$(ls /home/) for user in $USERS; do echo Deleting /home/"$user"/.ssh/authorized_keys; sudo find /home/"$user"/.ssh/authorized_keys -type f -exec shred -zuf {} \; done for user in $USERS; do if [[ -f /home/"$user"/.ssh/authorized_keys ]]; then echo Failed to delete /home/"$user"/.ssh/authorized_keys; exit 1 fi; done; fi; # Clean up for instance log files INSTANCE_LOG_FILES=( "/var/log/audit/audit.log" "/var/log/boot.log" "/var/log/dmesg" "/var/log/cron" ) if [[ -f {{workingDirectory}}/skip_cleanup_instance_log_files ]]; then echo "Skipping cleanup of instance log files" else echo "Cleaning up instance log files" cleanup "${INSTANCE_LOG_FILES[@]}" fi; # Clean up for TOE files if [[ -f {{workingDirectory}}/skip_cleanup_toe_files ]]; then echo "Skipping cleanup of TOE files" else echo "Cleaning TOE files" if [[ $( sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then echo "Deleting files within {{workingDirectory}}/TOE_*" sudo find {{workingDirectory}}/TOE_* -type f -exec shred -zuf {} \; fi if [[ $( sudo find {{workingDirectory}}/TOE_* -type f | sudo wc -l) -gt 0 ]]; then echo "Failed to delete {{workingDirectory}}/TOE_*" exit 1 fi if [[ $( sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then echo "Deleting {{workingDirectory}}/TOE_*" sudo rm -rf {{workingDirectory}}/TOE_* fi if [[ $( sudo find {{workingDirectory}}/TOE_* -type d | sudo wc -l) -gt 0 ]]; then echo "Failed to delete {{workingDirectory}}/TOE_*" exit 1 fi fi # Clean up for ssm log files if [[ -f {{workingDirectory}}/skip_cleanup_ssm_log_files ]]; then echo "Skipping cleanup of ssm log files" else echo "Cleaning up ssm log files" if [[ $( sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then echo "Deleting files within /var/log/amazon/ssm/*" sudo find /var/log/amazon/ssm -type f -exec shred -zuf {} \; fi if [[ $( sudo find /var/log/amazon/ssm -type f | sudo wc -l) -gt 0 ]]; then echo "Failed to delete /var/log/amazon/ssm" exit 1 fi if [[ -d "/var/log/amazon/ssm" ]]; then echo "Deleting /var/log/amazon/ssm/*" sudo rm -rf /var/log/amazon/ssm fi if [[ -d "/var/log/amazon/ssm" ]]; then echo "Failed to delete /var/log/amazon/ssm" exit 1 fi fi if [[ $( sudo find /var/log/sa/sa* -type f | sudo wc -l ) -gt 0 ]]; then echo "Deleting /var/log/sa/sa*" sudo shred -zuf /var/log/sa/sa* fi if [[ $( sudo find /var/log/sa/sa* -type f | sudo wc -l ) -gt 0 ]]; then echo "Failed to delete /var/log/sa/sa*" exit 1 fi if [[ $( sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l ) -gt 0 ]]; then echo "Deleting /var/lib/dhclient/dhclient*.lease" sudo shred -zuf /var/lib/dhclient/dhclient*.lease fi if [[ $( sudo find /var/lib/dhclient/dhclient*.lease -type f | sudo wc -l ) -gt 0 ]]; then echo "Failed to delete /var/lib/dhclient/dhclient*.lease" exit 1 fi if [[ $( sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then echo "Deleting files within /var/tmp/*" sudo find /var/tmp -type f -exec shred -zuf {} \; fi if [[ $( sudo find /var/tmp -type f | sudo wc -l) -gt 0 ]]; then echo "Failed to delete /var/tmp" exit 1 fi if [[ $( sudo ls /var/tmp | sudo wc -l ) -gt 0 ]]; then echo "Deleting /var/tmp/*" sudo rm -rf /var/tmp/* fi # Shredding is not guaranteed to work well on rolling logs if [[ -f "/var/lib/rsyslog/imjournal.state" ]]; then echo "Deleting /var/lib/rsyslog/imjournal.state" sudo shred -zuf /var/lib/rsyslog/imjournal.state sudo rm -f /var/lib/rsyslog/imjournal.state fi if [[ $( sudo ls /var/log/journal/ | sudo wc -l ) -gt 0 ]]; then echo "Deleting /var/log/journal/*" sudo find /var/log/journal/ -type f -exec shred -zuf {} \; sudo rm -rf /var/log/journal/* fi sudo touch /etc/machine-id
Windows

Image Builder 파이프라인은 Windows 이미지를 사용자 지정한 후 Microsoft Sysprep 유틸리티를 실행합니다. 이러한 조치는 이미지 강화 및 정리AWS 모범 사례를 따릅니다.

Linux 정리 스크립트를 오버라이드합니다.

Image Builder는 기본적으로 안전한 이미지를 생성하고 보안 모범 사례를 따릅니다. 하지만 일부 고급 사용 사례에서는 내장된 정리 스크립트의 한 개 이상의 섹션을 건너뛰어야 할 수도 있습니다. 일부 정리 단계를 건너뛰어야 하는 경우 출력 AMI를 테스트하여 이미지의 보안을 확인하는 것이 좋습니다.

중요

정리 스크립트의 섹션을 건너뛰면 소유자 계정 세부 정보 또는 SSH 키와 같은 민감한 정보가 최종 이미지 및 해당 이미지에서 실행되는 인스턴스에 포함될 수 있습니다. 다른 가용 영역, 리전 또는 계정에서 시작하는 데 문제가 발생할 수도 있습니다.

다음 표에는 정리 스크립트의 섹션, 해당 섹션에서 삭제된 파일 및 Image Builder에서 건너뛰어야 하는 섹션에 플래그를 지정하는 데 사용할 수 있는 파일 이름이 요약되어 있습니다. 정리 스크립트의 특정 섹션을 건너뛰려면 CreateFile 구성 요소 작업 모듈이나 사용자 데이터의 명령(오버라이드하는 경우)을 사용하여 건너뛰기 섹션 파일 이름 열에 지정된 이름으로 빈 파일을 생성할 수 있습니다.

참고

정리 스크립트의 한 부분을 건너뛰기 위해 생성하는 파일에는 파일 확장자가 포함되어서는 안 됩니다. 예를 들어, 스크립트의 CLOUD_INIT_FILES 섹션을 건너뛰고 싶지만 skip_cleanup_cloudinit_files.txt(이)라는 파일을 생성하면 Image Builder는 건너뛰기 파일을 인식하지 못합니다.

Input

섹션 정리하기

파일 제거됨

섹션 파일 이름 건너뛰기

CLOUD_INIT_FILES

/etc/sudoers.d/90-cloud-init-users

/etc/locale.conf

/var/log/cloud-init.log

/var/log/cloud-init-output.log

skip_cleanup_cloudinit_files

INSTANCE_FILES

/etc/.updated

/etc/aliases.db

/etc/hostname

/var/lib/misc/postfix.aliasesdb-stamp

/var/lib/postfix/master.lock

/var/spool/postfix/pid/master.pid

/var/.updated

/var/cache/yum/x86_64/2/.gpgkeyschecked.yum

skip_cleanup_instance_files

SSH_FILES

/etc/ssh/ssh_host_rsa_key

/etc/ssh/ssh_host_rsa_key.pub

/etc/ssh/ssh_host_ecdsa_key

/etc/ssh/ssh_host_ecdsa_key.pub

/etc/ssh/ssh_host_ed25519_key

/etc/ssh/ssh_host_ed25519_key.pub

/root/.ssh/authorized_keys

/home/<all users>/.ssh/authorized_keys;

skip_cleanup_ssh_files

INSTANCE_LOG_FILES

/var/log/audit/audit.log

/var/log/boot.log

/var/log/dmesg

/var/log/cron

skip_cleanup_instance_log_files

TOE_FILES

{{workingDirectory}}/TOE_*

skip_cleanup_toe_files

SSM_LOG_FILES

/var/log/amazon/ssm/*

skip_cleanup_ssm_log_files