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_ip과 lab_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만 접근할 수 있도록 보안 설정을 구성하여 통신 구간의 암호화를 처리합니다.


