Home
home

섹션 10 - Amazon S3 보안 구성

1. 기본 환경 구성

이번 실습은 IAM 사용자 계정을 통해 관리 콘솔에 접근하고 액세스 키를 활용해 awscli 도구를 사용합니다.
해당 작업을 수행하지 않았다면 아래 토글을 확장해 작업을 선행하고 본격적인 실습에 들어갑니다.
IAM 사용자 생성 및 액세스 키 생성

1.1. Terraform을 통한 기본 인프라 배포

Terraform을 통한 기본 인프라 배포에 앞서 SSH 키 페어, IAM User Access Key ID, IAM User Secret Access Key를 미리 확인하고 메모해 둡니다.
Terraform으로 기본 인프라 배포
cd cnasg_class_tf/Section10
Bash
복사
# 실습 코드 경로 진입
export TF_VAR_KeyName=[각자 ssh keypair] export TF_VAR_NickName=[각자 닉네임] export TF_VAR_MyIamUserAccessKeyID=[각자 iam 사용자의 access key id] export TF_VAR_MyIamUserSecretAccessKey=[각자 iam 사용자의 secret access key] export TF_VAR_SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32
Bash
복사
# Terraform 환경 변수 저장
terraform init terraform plan
Bash
복사
# Terraform 배포
nohup sh -c "terraform apply -auto-approve" > create.log 2>&1 &
Bash
복사
Note:  Terraform 배포가 완료되면(약 5분 정도 대기) 정상적으로 자원 생성이 되었는지 확인을 합니다.(cat create.log)

1.2. 기본 정보 확인 및 설정

Terraform 배포가 완료 후 출력되는 Outputs 정보에서 lab_admin_iplab_user_ip의 퍼블릭 IP를 확인합니다.
대상 IP로 인스턴스에 SSH로 접속하고 아래 명령어를 통해 정보를 확인합니다.
LAB-ADMIN & LAB-USER
echo ${AWS_DEFAULT_REGION} echo ${NICKNAME} echo ${ACCOUNT_ID}
Bash
복사
# 변수 확인
aws sts get-caller-identity
Bash
복사
# caller id 확인
Note:  인스턴스가 생성되고 너무 빠르게 접속하면 aws 자격 증명이 완료되지 않을 수 있습니다.
그럴 경우에는 약간의 대기 후 다시 접속해 주세요.

2. Amazon S3 보안 구성 - 접근 통제와 보안 탐지

2.1. IAM 정책과 버킷 정책 확인

Amazon S3 서비스에 대한 IAM 정책과 버킷 정책을 생성하고 차이를 이해합니다.
LAB-ADMIN
실습용 버킷 생성 및 ACL 확인
aws s3api create-bucket \ --bucket cnasg-${NICKNAME}-access \ --create-bucket-configuration LocationConstraint=${AWS_DEFAULT_REGION} | jq
Bash
복사
# S3 버킷 생성
aws s3api get-bucket-ownership-controls \ --bucket cnasg-${NICKNAME}-access | jq
Bash
복사
# ACL 설정 확인
echo "hello cnasg" > hello.txt aws s3api put-object \ --bucket cnasg-${NICKNAME}-access \ --key hello.txt \ --body hello.txt
Bash
복사
# 테스트 버킷에 객체 업로드
aws s3api list-objects-v2 \ --bucket cnasg-${NICKNAME}-access | jq
Bash
복사
# 업로드된 객체 확인
aws s3api put-object-acl \ --bucket cnasg-${NICKNAME}-access \ --key hello.txt \ --acl private
Bash
복사
# private라는 ACL 적용 (객체 소유자만 Full Control)
실습용 IAM 사용자 생성
aws iam create-user \ --user-name lab-s3-user aws iam create-access-key \ --user-name lab-s3-user
Bash
복사
# 실습용 IAM 사용자 생성 및 액세스 키 생성
LAB-USER
자격 증명 설정
aws sts get-caller-identity
Bash
복사
# caller id 확인
aws configure
Bash
복사
# lab-s3-user에 대한 자격 증명 설정
aws sts get-caller-identity
Bash
복사
# caller id 확인
aws s3api list-objects-v2 \ --bucket cnasg-${NICKNAME}-access
Bash
복사
# 실습용 버킷 정보 조회
LAB-ADMIN
IAM 정책 생성 및 부여
cat > iam-s3-allow.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowListBucket", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::cnasg-${NICKNAME}-access" }, { "Sid": "AllowGetObject", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::cnasg-${NICKNAME}-access/*" } ] } EOF
Bash
복사
# IAM 정책 파일 생성
aws iam put-user-policy \ --user-name lab-s3-user \ --policy-name AllowS3Read-Test1 \ --policy-document file://iam-s3-allow.json
Bash
복사
# 실습용 IAM 사용자에 IAM 정책 연결
aws s3api get-bucket-policy \ --bucket cnasg-${NICKNAME}-access | jq
Bash
복사
# 버킷 정책 확인
LAB-USER
S3 접근 확인
aws s3api list-objects-v2 \ --bucket cnasg-${NICKNAME}-access | jq
Bash
복사
# 테스트 버킷에서 객체조회
aws s3api get-object \ --bucket cnasg-${NICKNAME}-access \ --key hello.txt \ /tmp/hello.txt cat /tmp/hello.txt
Bash
복사
# 테스트 버킷에 객체 파일 다운로드
echo "hello2 cnasg" > hello2.txt aws s3api put-object \ --bucket cnasg-${NICKNAME}-access \ --key hello2.txt \ --body hello2.txt
Bash
복사
# 테스트 버킷에 객체 업로드
LAB-ADMIN
버킷 정책 생성 및 부여
cat > bucket-policy-deny-get.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowListBucket", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::${ACCOUNT_ID}:user/lab-s3-user" }, "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::cnasg-${NICKNAME}-access" }, { "Sid": "DenyGetObject", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::${ACCOUNT_ID}:user/lab-s3-user" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::cnasg-${NICKNAME}-access/*" } ] } EOF
Bash
복사
# 버킷 정책 파일 생성
aws s3api put-bucket-policy \ --bucket cnasg-${NICKNAME}-access \ --policy file://bucket-policy-deny-get.json
Bash
복사
# 버킷 정책을 테스트 버킷에 연결
aws s3api get-bucket-policy \ --bucket cnasg-${NICKNAME}-access \ | jq -r '.Policy | fromjson'
Bash
복사
# 테스트 버킷의 버킷 정책 확인 (JSON 형태 파싱)
LAB-USER
S3 접근 확인
aws s3api list-objects-v2 \ --bucket cnasg-${NICKNAME}-access | jq
Bash
복사
# 테스트 버킷 조회
aws s3api get-object \ --bucket cnasg-${NICKNAME}-access \ --key hello.txt \ /tmp/hello.txt
Bash
복사
# 테스트 버킷에 객체 파일 다운로드

2.2. PrivateLink for S3 - 통신 경로 확인

Amazon S3 서비스와 통신을 위한 PrivateLink를 구성하고 통신 흐름을 이해합니다.
LAB-ADMIN
S3 버킷 대상 주소의 IP 확인
dig +short cnasg-${NICKNAME}-access.s3.ap-northeast-2.amazonaws.com
Bash
복사
# S3 버킷의 도메인에 대한 IP 주소 확인 (dig)
대상 S3 버킷에 접근하기 위한 주소를 사전에 정의된 범위 내에서 사용합니다.
curl -O https://ip-ranges.amazonaws.com/ip-ranges.json
Bash
복사
# AWS 서비스 용도의 IP 대역을 정의한 파일 다운로드
jq '.prefixes[0:2]' ip-ranges.json
Bash
복사
# 샘플 구조 확인 (2개만)
jq '.prefixes | map(select(.service=="S3")) | .[0:2]' ip-ranges.json
Bash
복사
jq -r '.prefixes[] | select(.region=="ap-northeast-2" and .service=="S3") | .ip_prefix' ip-ranges.json
Bash
복사
# 서울 리전의 S3 서비스만 필터링
[PrivateLink 구성 전] 라우팅 테이블 확인
VPC_ID=$(aws ec2 describe-vpcs \ --filters "Name=tag:Name,Values=cnasg-VPC" \ --query 'Vpcs[0].VpcId' --output text) RTB_ID=$(aws ec2 describe-route-tables \ --filters "Name=tag:Name,Values=cnasg-VPC-public" \ --query 'RouteTables[0].RouteTableId' \ --output text)
Bash
복사
# 변수 선언
echo "export VPC_ID=${VPC_ID}" >> /etc/profile echo "export RTB_ID=${RTB_ID}" >> /etc/profile echo "VPC_ID=${VPC_ID}" echo "RTB_ID=${RTB_ID}"
Bash
복사
# 전역 변수 선언 및 확인
aws ec2 describe-route-tables \ --route-table-ids $RTB_ID \ --query 'RouteTables[0].Routes' \ --output table
Bash
복사
# 라우팅 테이블 확인
[PrivateLink 구성] VPC Gateway Endpoint for S3 생성
aws ec2 create-vpc-endpoint \ --vpc-id $VPC_ID \ --service-name com.amazonaws.ap-northeast-2.s3 \ --route-table-ids $RTB_ID \ --vpc-endpoint-type Gateway
Bash
복사
# S3 용 VPC Gateway Endpoint 생성
aws ec2 describe-vpc-endpoints \ --filters "Name=vpc-id,Values=$VPC_ID" \ --query 'VpcEndpoints[].{ID:VpcEndpointId,Service:ServiceName,State:State}' \ --output table
Bash
복사
# VPCE 생성 확인
[PrivateLink 구성 후] 라우팅 테이블 확인
aws ec2 describe-route-tables \ --route-table-ids $RTB_ID \ --query 'RouteTables[0].Routes' \ --output table
Bash
복사
# 라우팅 테이블 확인
aws ec2 describe-managed-prefix-lists \ --query 'PrefixLists[?PrefixListName==`com.amazonaws.ap-northeast-2.s3`].[PrefixListId,PrefixListName]' \ --output table PL_S3_ID=$(aws ec2 describe-managed-prefix-lists \ --query 'PrefixLists[?PrefixListName==`com.amazonaws.ap-northeast-2.s3`].PrefixListId' \ --output text) echo ${PL_S3_ID}
Bash
복사
# 대상 Prefix-Lists 확인하고 이름을 변수 선언
aws ec2 get-managed-prefix-list-entries \ --prefix-list-id ${PL_S3_ID} \ --query 'Entries[].Cidr' \ --output table
Bash
복사
# 대상 Prefix-Lists에 연결된 CIDR 확인

2.3. Pre-signed URL for S3 - 임시 접근

Amazon S3 버킷 내 객체 접근을 위한 Pre-signed URL을 생성해서 임시적인 접근 권한을 실습합니다.
LAB-ADMIN
버킷 정책 생성 및 객체 업로드
aws s3api create-bucket \ --bucket cnasg-${NICKNAME}-presign \ --create-bucket-configuration LocationConstraint=${AWS_DEFAULT_REGION} | jq
Bash
복사
# S3 버킷 생성
aws s3api head-bucket \ --bucket cnasg-${NICKNAME}-presign | jq
Bash
복사
# S3 버킷 생성 확인
echo "cnasg presign test" > presign-test.txt aws s3api put-object \ --bucket cnasg-${NICKNAME}-presign \ --key presign-test.txt \ --body presign-test.txt \ --content-type text/plain
Bash
복사
# 테스트 파일 생성 + 객체 업로드
aws s3api list-objects-v2 \ --bucket cnasg-${NICKNAME}-presign | jq
Bash
복사
# 객체 업로드 확인
LAB-USER
S3 버킷에 직접 접근
curl -I https://cnasg-${NICKNAME}-presign.s3.ap-northeast-2.amazonaws.com/presign-test.txt
Bash
복사
# 대상 S3 버킷의 객체로 직접 접근 (curl & lynx)
lynx --dump https://cnasg-${NICKNAME}-presign.s3.ap-northeast-2.amazonaws.com/presign-test.txt
Bash
복사
사용자 PC의 브라우저에서도 접근을 시도합니다.
echo "https://cnasg-${NICKNAME}-presign.s3.ap-northeast-2.amazonaws.com/presign-test.txt"
Bash
복사
LAB-ADMIN
Pre-signed URL 생성 (5분)
aws s3 presign s3://cnasg-${NICKNAME}-presign/presign-test.txt \ --expires-in 300
Bash
복사
# 대상 객체에 대한 Pre-signed URL 생성 (5분)
LAB-USER
S3 버킷에 Pre-signed URL로 접근
URL='<출력된 presigned URL 붙여넣기>'
Bash
복사
# Pre-signed URL을 변수에 선언 및 확인
echo $URL
Bash
복사
lynx --dump $URL
Bash
복사
# Pre-signed URL 접근 확인
사용자 PC의 브라우저에서도 Pre-signed URL로 접근을 시도합니다.
Pre-signed URL에 정의한 만료 시간 5분이 지난 후 다시 접근을 해 봅니다.

2.4. AWS Config - S3 퍼블릭 접근 설정 탐지

AWS Config를 통해 리소스를 기록하고 S3 퍼블릭 버킷 규칙에 따라 위반 대상을 탐지합니다.
LAB-ADMIN
퍼블릭 버킷 생성 및 객체 업로드
aws s3api create-bucket \ --bucket cnasg-${NICKNAME}-public \ --create-bucket-configuration LocationConstraint=${AWS_DEFAULT_REGION}
Bash
복사
# S3 버킷 생성
aws s3api get-public-access-block \ --bucket cnasg-${NICKNAME}-public | jq
Bash
복사
# 대상 버킷에 퍼블릭 접근 확인
aws s3api put-public-access-block \ --bucket cnasg-${NICKNAME}-public \ --public-access-block-configuration \ 'BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false' aws s3api get-public-access-block \ --bucket cnasg-${NICKNAME}-public | jq
Bash
복사
# 대상 버킷에 퍼블릭 접근 차단을 해제(퍼블릭 접근 가능)
echo "cnasg public test" > public-test.txt aws s3api put-object \ --bucket cnasg-${NICKNAME}-public \ --key public-test.txt \ --body public-test.txt \ --content-type text/plain
Bash
복사
# 테스트 파일 생성 + 객체 업로드
aws s3api list-objects-v2 \ --bucket cnasg-${NICKNAME}-public | jq
Bash
복사
# 객체 업로드 확인
cat << EOF > bucket-policy-public-read.json { "Version":"2012-10-17", "Statement":[ { "Sid":"AllowPublicReadObject", "Effect":"Allow", "Principal":"*", "Action":["s3:GetObject"], "Resource":["arn:aws:s3:::cnasg-${NICKNAME}-public/*"] } ] } EOF aws s3api put-bucket-policy \ --bucket cnasg-${NICKNAME}-public \ --policy file://bucket-policy-public-read.json
Bash
복사
# 버킷 정책에서 익명의 GetObject 허용
LAB-USER
S3 객체 주소로 접근 확인
curl -I -s https://cnasg-${NICKNAME}-public.s3.ap-northeast-2.amazonaws.com/public-test.txt | head
Bash
복사
# 대상 S3 버킷의 객체로 직접 접근 (curl & lynx)
lynx --dump https://cnasg-${NICKNAME}-public.s3.ap-northeast-2.amazonaws.com/public-test.txt
Bash
복사
사용자 PC의 브라우저에서도 접근을 시도합니다.
echo "https://cnasg-${NICKNAME}-public.s3.ap-northeast-2.amazonaws.com/public-test.txt"
Bash
복사
LAB-ADMIN
[AWS Config] Config 용도의 버킷 생성
aws s3api create-bucket \ --bucket cnasg-${NICKNAME}-config \ --create-bucket-configuration LocationConstraint=ap-northeast-2 | jq
Bash
복사
# Config 용도 버킷 생성
cat > cnasg-config-bucket-policy.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AWSConfigBucketPermissionsCheck", "Effect": "Allow", "Principal": { "Service": "config.amazonaws.com" }, "Action": [ "s3:GetBucketAcl", "s3:ListBucket" ], "Resource": "arn:aws:s3:::cnasg-${NICKNAME}-config" }, { "Sid": "AWSConfigBucketDelivery", "Effect": "Allow", "Principal": { "Service": "config.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::cnasg-${NICKNAME}-config/AWSLogs/${ACCOUNT_ID}/Config/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } } ] } EOF aws s3api put-bucket-policy \ --bucket cnasg-${NICKNAME}-config \ --policy file://cnasg-config-bucket-policy.json
Bash
복사
# 버킷 정책에 Delivery Policy 추가
[AWS Config] Config 용도의 IAM 생성
cat > config-trust.json << 'EOF' { "Version":"2012-10-17", "Statement":[ { "Effect":"Allow", "Principal":{"Service":"config.amazonaws.com"}, "Action":"sts:AssumeRole" } ] } EOF aws iam create-role \ --role-name CNASG-ConfigRole \ --assume-role-policy-document file://config-trust.json
Bash
복사
# 신뢰 정책 파일 생성 및 IAM 역할 생성
aws iam attach-role-policy \ --role-name CNASG-ConfigRole \ --policy-arn arn:aws:iam::aws:policy/service-role/AWS_ConfigRole
Bash
복사
# AWS 관리형 IAM 정책을 IAM 역할에 연결
[AWS Config] Recorder 생성
CONFIG_ROLE_ARN=$(aws iam get-role \ --role-name CNASG-ConfigRole \ --query 'Role.Arn' \ --output text) cat > recorder.json <<EOF { "name": "cnasg-recorder", "roleARN": "${CONFIG_ROLE_ARN}", "recordingGroup": { "allSupported": false, "includeGlobalResourceTypes": false, "resourceTypes": ["AWS::S3::Bucket"] } } EOF aws configservice put-configuration-recorder \ --configuration-recorder file://recorder.json
Bash
복사
# IAM 역할의 ARN 값 변수 선언 및 Recorder 생성 (S3 서비스 리소스 기록)
aws configservice describe-configuration-recorder-status | jq
Bash
복사
# Recorder 상태 확인
[AWS Config] Delivery Channel 생성
aws configservice put-delivery-channel \ --delivery-channel \ name=cnasg-channel,s3BucketName=cnasg-${NICKNAME}-config
Bash
복사
# Delivery Channel 생성 (Config 용도의 S3 버킷)
aws configservice describe-delivery-channels | jq
Bash
복사
# Delivery Channel 설정 확인
[AWS Config] Recorder 시작
aws configservice start-configuration-recorder \ --configuration-recorder-name cnasg-recorder
Bash
복사
# Recorder 시작
aws configservice describe-configuration-recorder-status | jq
Bash
복사
# Recorder 상태 확인
[AWS Config] 관리형 규칙 추가 (S3 Bucket - Public Read/Write)
cat > cnasg-s3-public-read-prohibited.json <<'EOF' { "ConfigRuleName": "cnasg-s3-public-read-prohibited", "Source": { "Owner": "AWS", "SourceIdentifier": "S3_BUCKET_PUBLIC_READ_PROHIBITED" } } EOF aws configservice put-config-rule \ --config-rule file://cnasg-s3-public-read-prohibited.json cat > cnasg-s3-public-write-prohibited.json <<'EOF' { "ConfigRuleName": "cnasg-s3-public-write-prohibited", "Source": { "Owner": "AWS", "SourceIdentifier": "S3_BUCKET_PUBLIC_WRITE_PROHIBITED" } } EOF aws configservice put-config-rule \ --config-rule file://cnasg-s3-public-write-prohibited.json
Bash
복사
# 관리형 규칙 2개 생성 (퍼블릭 S3 버킷의 Read/Write 규칙)
aws configservice describe-config-rules \ --config-rule-names cnasg-s3-public-read-prohibited cnasg-s3-public-write-prohibited | jq
Bash
복사
# 생성한 관리형 규칙 상태 확인
[AWS Config] Config 즉시 평가 및 결과 확인
aws configservice start-config-rules-evaluation \ --config-rule-names cnasg-s3-public-read-prohibited cnasg-s3-public-write-prohibited
Bash
복사
# 즉시 평가 트리거
aws configservice describe-compliance-by-config-rule \ --config-rule-names cnasg-s3-public-read-prohibited cnasg-s3-public-write-prohibited | jq
Bash
복사
# S3 버킷 퍼블릭 접근 Read/Write 규칙 결과 확인
S3 버킷 퍼블릭 접근에 대한 Read 규칙만 문제 있음을 확인할 수 있어, 대상 규칙에 대한 상세 정보만 확인합니다.
aws configservice get-compliance-details-by-config-rule \ --config-rule-name cnasg-s3-public-read-prohibited | jq
Bash
복사
# S3 버킷 퍼블릭 접근 Read 규칙 상세 결과 (위: 전체, 아래: NON_COMPLIANT Only)
aws configservice get-compliance-details-by-config-rule \ --config-rule-name cnasg-s3-public-read-prohibited \ | jq '.EvaluationResults[] | select(.ComplianceType=="NON_COMPLIANT")'
Bash
복사
S3 퍼블릭 버킷 감지를 위한 AWS Config가 구성된 상태에서 신규 S3 퍼블릭 버킷이 생성되면, 자동으로 감지합니다. (약간의 대기가 필요)
[OPTIONAL] S3 퍼블릭 버킷 생성이 감지되면 Slack 웹 훅으로 메시지 전달하기
AWS Config 실습 자원 삭제
AWS Config Recording 동작으로 미세하지만 과금이 발생할 수 있어, 이번 단위 실습에 대한 자원만 삭제합니다.
aws configservice delete-config-rule \ --config-rule-name cnasg-s3-public-read-prohibited aws configservice delete-config-rule \ --config-rule-name cnasg-s3-public-write-prohibited
Bash
복사
# Config Rule 삭제
aws configservice stop-configuration-recorder \ --configuration-recorder-name cnasg-recorder
Bash
복사
# Recorder 중지
aws configservice delete-configuration-recorder \ --configuration-recorder-name cnasg-recorder
Bash
복사
# Recorder 삭제
aws configservice delete-delivery-channel \ --delivery-channel-name cnasg-channel
Bash
복사
# Delivery Channel 삭제
aws iam detach-role-policy \ --role-name CNASG-ConfigRole \ --policy-arn arn:aws:iam::aws:policy/service-role/AWS_ConfigRole aws iam delete-role \ --role-name CNASG-ConfigRole
Bash
복사
# AWS Config 용도의 IAM 삭제
aws s3 rb s3://cnasg-${NICKNAME}-public --force aws s3 rb s3://cnasg-${NICKNAME}-config --force
Bash
복사
# 실습용 S3 버킷 삭제

2.5. Amazon Macie - 민감 데이터 노출 탐지

Amazon Macie를 통해 S3 버킷 내 구성된 객체 파일의 민감 데이터를 탐지하고 대응합니다.
LAB-ADMIN
실습 용도의 버킷 생성
aws s3api create-bucket \ --bucket cnasg-${NICKNAME}-customer-data \ --create-bucket-configuration LocationConstraint=${AWS_DEFAULT_REGION}
Bash
복사
# S3 버킷 생성
실습 용도의 파일 생성 및 S3 버킷 업로드
python3 gen-macie-csv.py ls -l *.csv *.env
Bash
복사
# 실습 용도의 파일을 생성하는 스크립트 실행
스크립트를 통해 생성하는 파일은 랜덤하게 생성되는 더미 파일로, FAKE 데이터입니다.
column -s, -t customer-data.csv | head -n 6
Bash
복사
# 생성된 파일 정보 확인
column -s, -t customer-data-safe.csv | head -n 6
Bash
복사
cat config.env
Bash
복사
aws s3 cp customer-data.csv s3://cnasg-${NICKNAME}-customer-data/customer-data.csv aws s3 cp customer-data-safe.csv s3://cnasg-${NICKNAME}-customer-data/customer-data-safe.csv aws s3 cp config.env s3://cnasg-${NICKNAME}-customer-data/config.env
Bash
복사
# 대상 S3 버킷에 객체 파일 업로드
aws s3 ls s3://cnasg-${NICKNAME}-customer-data/
Bash
복사
# 대상 S3 버킷에 객체 정보 확인
[Amazon Macie] Macie 활성화
[관리 콘솔 확인: Amazon Macie→ 시작하기]
aws macie2 get-macie-session
Bash
복사
# Amazon Macie 상태 확인
aws macie2 enable-macie
Bash
복사
# Amazon Macie 활성화
[Amazon Macie] 사용자 지정 데이터 식별자 생성 (주민 등록 번호)
[관리 콘솔 확인: Amazon Macie→ 설정 → 사용자 지정 데이터 식별자]
aws macie2 create-custom-data-identifier \ --name "KoreanResidentNumberLike" \ --description "RRN-like pattern for lab" \ --regex "\\b\\d{6}-[1-4]\\d{6}\\b" \ --maximum-match-distance 50
Bash
복사
# 주민 등록 번호를 검출하는 사용자 지정 데이터 식별자 생성
aws macie2 list-custom-data-identifiers
Bash
복사
# 생성된 사용자 지정 데이터 식별자 확인
RRN_CDI_ID=$(aws macie2 list-custom-data-identifiers \ --query "items[?name=='KoreanResidentNumberLike'].id | [0]" \ --output text) echo "export RRN_CDI_ID=$RRN_CDI_ID" >> /etc/profile echo $RRN_CDI_ID
Bash
복사
# 생성된 사용자 지정 데이터 식별자 ID를 변수로 선언
[Amazon Macie] 일회성 작업 생성 - 민감 데이터 검토
[관리 콘솔 확인: Amazon Macie→ 작업]
cat > s3-job.json <<EOF { "bucketDefinitions": [ { "accountId": "${ACCOUNT_ID}", "buckets": ["cnasg-${NICKNAME}-customer-data"] } ] } EOF
Bash
복사
# 작업을 수행할 S3 버킷 지정
aws macie2 create-classification-job \ --job-type ONE_TIME \ --name "cnasg-macie-lab-job" \ --s3-job-definition file://s3-job.json \ --custom-data-identifier-ids ${RRN_CDI_ID} \ --managed-data-identifier-selector RECOMMENDED \ --sampling-percentage 100
Bash
복사
# 일회성 작업 생성 - S3 버킷 지정, 사용자 지정 데이터 식별자 선택, 관리형 식별자 추천 대상 선택
aws macie2 list-classification-jobs | jq
Bash
복사
# 생성된 작업 확인
JOB_ID=$(aws macie2 list-classification-jobs \ --query "items[?name=='cnasg-macie-lab-job'].jobId" \ --output text) echo "export JOB_ID=$JOB_ID" >> /etc/profile echo $JOB_ID
Bash
복사
# 대상 일회성 작업의 ID를 변수로 선언
aws macie2 describe-classification-job \ --job-id ${JOB_ID} \ --query jobStatus \ --output text
Bash
복사
# 일회성 작업의 상태 확인
watch -d "aws macie2 describe-classification-job \ --job-id ${JOB_ID} \ --query jobStatus \ --output text"
Bash
복사
# 일회성 작업의 상태 모니터링
RUNNING 상태는 활성(실행 중) 상태로 민감 데이터 검토 작업을 수행 중인 상태입니다. 약 12분 정도 시간이 지나면 COMPLETE 상태로 완료되니 이후에 결과를 확인합니다.
[Amazon Macie] 일회성 작업 결과 확인 - 민감 데이터 검토
FINDING_IDS=$(aws macie2 list-findings \ --finding-criteria '{"criterion":{"classificationDetails.jobId":{"eq":["'"${JOB_ID}"'"]}}}' \ --query 'findingIds[]' \ --output text) echo "$FINDING_IDS"
Bash
복사
# 결과 ID 변수 선언
aws macie2 get-findings \ --finding-ids ${FINDING_IDS} \ --output json | jq ' .findings[] | { id, type, severity: .severity.description, object: .resourcesAffected.s3Object.key, updatedAt }'
Bash
복사
# 결과 요약 View
aws macie2 get-findings \ --finding-ids ${FINDING_IDS} \ --output json | jq ' .findings[] | select(.type=="SensitiveData:S3Object/Credentials") '
Bash
복사
# 첫 번째 결과 확인
grep -n 'AWS_ACCESS_KEY_ID\|AWS_SECRET_ACCESS_KEY' config.env
Bash
복사
# [신규 터미널] config.env에서 필요한 부분만 확인
grep -n 'BEGIN OPENSSH PRIVATE KEY\|END OPENSSH PRIVATE KEY' -n config.env
Bash
복사
aws macie2 get-findings \ --finding-ids ${FINDING_IDS} \ --output json | jq ' .findings[] | select(.type=="SensitiveData:S3Object/Multiple") '
Bash
복사
# 두 번째 결과 확인
nl -ba customer-data.csv | column -s, -t -n ' '
Bash
복사
# [신규 터미널] customer-data.csv 파일 확인 (라인 넘버링)

3. Amazon S3 보안 구성 - 데이터 보호와 감사 및 로깅 분석

3.1. HTTPS 사용 강제화

Amazon S3 버킷의 객체를 접근할 때 HTTPS만 접근할 수 있도록 보안 설정을 구성하여 통신 구간의 암호화를 처리합니다.