AWS S3 보안
Amazon S3(Simple Storage Service)는 클라우드 기반의 데이터 스토리지 서비스로,
AWS를 사용하는 수많은 기업에서 중요한 데이터를 저장하고 관리하는 데 사용하고 있다.
데이터 보관소가 S3인 것을 기본으로 한 파생 서비스들도 상당히 많기 때문에 S3의 사용 사례는 굉장히 많고 다양한데,
이처럼 많이 사용하고 편리한 만큼 다양한 보안 사고도 발생한다.
S3 데이터 유출 사례
https://m.boannews.com/html/detail.html?mtype=1&idx=112737
미국의 대형 교육 플랫폼에서 22TB 데이터 유출돼
보안 외신 핵리드에 의하면 미국 내에서 세 손가락에 꼽히는 교육 출판사이자 플랫폼인 맥그로힐(McGraw Hill)에서 22TB의 데이터가 유출됐다고 한다. AWS S3 버킷 두 개를 잘못 설정해서 벌어진 일이
m.boannews.com
https://m.boannews.com/html/detail.html?mtype=1&idx=108196
또 클라우드 설정 오류 사건! 이번엔 4개 공항 3TB 데이터 유출돼
아마존 S3 버킷의 설정 오류 때문에 3TB의 공항 관련 데이터가 외부로 노출되는 일이 발생했다. 무려 150만 개 이상의 파일들이라고 한다. 문제의 데이터베이스는 보안 업체 스카이하이 시큐리티(S
m.boannews.com
이와 같은 여러가지 S3 보안 사고는 조사 결과 대부분 S3 정책과 설정 실수로 인해서 발생했다고 한다.
S3 보안을 위한 정책은 어떤 종류가 있고, 어떤 식으로 적용하는지 한번 더 실습해보았다.
S3 권한 제어 종류
설정 및 권한 | IAM 정책 | 버킷 정책 | ACL |
사용자/그룹/역할별 세밀한 액세스 설정 | O | X | X |
버킷 수준에서의 액세스 제어 | X | O | X |
개별 객체 수준에서의 액세스 제어 | X | X | O |
특정 IP 주소 또는 범위 제한 | O | X | X |
특정 기간 동안 액세스 제한 | O | X | X |
다른 AWS 계정과의 공유 설정 | O | O | X |
IAM 정책을 통한 접근 권한 설정
AWS IAM을 사용해 S3 자원에 대한 통제를 수행한다.
아래는 특정 AWS Account만 임의의 버킷에 접근가능하도록 하는 IAM 정책 예시이다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3AccessOtherAccount",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectAcl"
],
"Resource":"arn:aws:s3:::<bucket-name>/*"
"Condition": {
"StringEquals": {
"aws:ResourceAccount": [
"<Account-ID-1>",
"<Account-ID-2>"
]
}
}
}
]
}
S3 Bucket 정책을 통한 접근 권한 설정
S3 Bucket에 할당된 정책을 통해서 S3 자원에 대한 통제를 수행한다.
https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html?icmpid=docs_amazons3_console
Bucket policy examples - Amazon Simple Storage Service
Before using this policy, replace the 192.0.2.0/24 IP address range in this example with an appropriate value for your use case. Otherwise, you will lose the ability to access your bucket.
docs.aws.amazon.com
아래는 특정 IP 대역만 특정 S3 Bucket에 접근이 가능하도록하는 정책 예시이다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "IpAddrS3ReadOnly",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::<bucket-name1>/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"<ip-address-cidr-1>"
]
}
}
}
]
}
S3 ACL(Access Control List)을 통한 접근 권한 설정
ACL은 개별 객체 또는 버킷에 대한 액세스를 관리하는 복잡성을 높일 수 있으며, 잘못 사용할 가능성도 있다.
AWS에서도 ACL 비활성화를 권장으로 해놓았기 때문에, 일반적인 상황에서는 ACL 대신 IAM 정책과 버킷 정책을 주로 사용하는 것이 권장된다.
Pre-Signed URL을 통한 접근 권한 설정
권한이 없는 PC에서 해당 객체에 대해 임시 접근 권한을 부여한 URL을 제공한다.
// 권한이 있는 IAM에서는 정상적으로 접근이 가능
[root@My-EC2 ~]# aws s3 ls s3://ersia-test --human-readable
2023-09-02 17:09:28 5.1 MiB jameswebb.jpg
// 객체에 대한 Direct URL도 직접 사용 가능하다.
[root@My-EC2 ~]# curl -OL https://ersia-test.s3.ap-northeast-2.amazonaws.com/jameswebb.jpg
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 243 0 243 0 0 7748 0 --:--:-- --:--:-- --:--:-- 7838
[root@My-EC2 ~]# ls
jameswebb.jpg
// S3 객체에 대한 서명된 URL 생성
// aws s3 presign --endpoint-url https://s3.{region}.amazonaws.com s3://{bucketname}/{object} --region {region} --expires-in {seconds}
[root@My-EC2 ~]# aws s3 presign --endpoint-url https://s3.ap-northeast-2.amazonaws.com s3://ersia-test/jameswebb.jpg --expires-in 600
https://s3.ap-northeast-2.amazonaws.com/ersia-test/jameswebb.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=600&X-Amz-Credential=AKIAV7OXXODFYVOIPKHL%2F20230902%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Date=20230902T174531Z&X-Amz-Signature=80525b37ac4fdc097d67e158036da9806729096dd7b512b75185dac447c966ca
aws s3 presign s3://{bucketname}/{object} --expires-in {seconds} 이렇게만 수행할 때 에러가 날 경우 end-point를 별도로 지정해주면 정상적으로 접근 가능한 URL이 생성된다.
정책 평가 로직
위와 같은 접근 권한이 여러 종류가 섞여서 설정 되어있을 경우, 권한 중 Deny가 있다면 Deny 되는 것이 기본이다.
(단, Pre-Signed URL은 보안 자격 증명이나 권한 설정과 별개로 동작한다.)
https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/reference_policies_evaluation-logic.html
정책 평가 로직 - AWS Identity and Access Management
정책 평가 로직 보안 주체가 AWS Management Console, AWS API 또는 AWS CLI를 사용하려고 시도하면 해당 보안 주체가 요청을 AWS에 전송합니다. AWS 서비스가 요청을 받으면 AWS는 여러 단계를 완료하여 요청
docs.aws.amazon.com
S3 보안을 위한 권장사항
- ACL을 가능한 한 사용하지 말고, IAM 정책과 Bucket 정책을 조합해 접근을 통제한다.
- ACL은 정책의 복잡성이 너무 커지고 관리가 어려워진다.
- S3는 거부 설정을 기본 토대로하고 필요한 경우에만 접근을 허용하는 식으로 통제한다.
- 보안은 최소 권한 원칙을 준수하도록 한다.
- 기본 정책을 허용으로 할 경우, 거부 정책 적용 여부를 탐지하고 모니터링하기 더 어려워진다.
- 반드시 외부에 노출이 되어야하는 S3 객체가 있다면, Cloudfront를 통해 노출하고, 만약 구성 상 S3 버킷을 외부에 노출시켜야한다면 계정을 분리해 관리한다.
- Cloudfront를 통해 노출할 경우 접근 허용을 Cloudfront만 접근하도록 제한한다.
- 부득이하게 S3를 노출시킬 경우 파일 다운로드를 위해 Direct URL이 노출되면, Bucket에 대한 정보나 Region 정보 등을 추측할 수 있기 때문에 별도의 다운로드 방법을 제공하는 편이 보안에 유리하다.
- S3에 민감데이터를 저장하고 관리할 경우 객체를 암호화 하도록 한다.
- AWS S3 관리형 키(SSE-S3)를 사용해도 좋으며, AWS KMS 키(SSE-KMS)를 사용해도 좋다.
- KMS 키를 사용할 경우는 사용자 전용 키(암호화 알고리즘 등)를 생성할 수 있으나, 키 관리에 추가 유지보수 비용이 발생한다.
- KMS 키를 사용할 경우 일정 호출 건 당 비용이 발생하므로, 비용절감을 위해 키 캐싱 설정도 고려한다.
- https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-key.html
- S3 접근에 대한 모니터링과 감사 로깅(CloudTrail 등)을 수행한다.
- 일상적으로 발생하는 이벤트 외 이상 이벤트(평소에 접근이 없던 지역, 국가 등에서 접근이 발생하는 등)가 발생할 경우 인지할 수 있는 시스템 구축이 필요하다.
- 자동화된 시스템을 통해 S3 권한을 주기적으로 검토한다
- AWS에서 제공하는 SecurityHub나 IAM Access Analyzer 등을 통해 수행할 수도 있으며, prowler 같은 오픈소스를 활용해 점검을 시스템적으로 자동화 한다. (사람이 정기적으로 검사하는 것은 실수가 발생할 수 있음)
- IAM Access Analyzer : https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-analyzer.html
- prowler github : https://github.com/prowler-cloud/prowler
참고자료
- IAM Policies and Bucket Policies and ACLs! Oh, My! (Controlling Access to S3 Resources) : https://aws.amazon.com/ko/blogs/security/iam-policies-and-bucket-policies-and-acls-oh-my-controlling-access-to-s3-resources/
- [우아한테크세미나] 사례별로 알아보는 안전한 S3 보안 가이드 : https://www.youtube.com/live/vgYfAndrpPU?si=ts1f2aSSXLK67I7h
- 특정 VPC 엔드포인트나 IP 주소를 사용하여 Amazon S3 버킷에 대한 액세스를 제한하려면 어떻게 해야 하나요? : https://repost.aws/ko/knowledge-center/block-s3-traffic-vpc-ip
- AWS CLI s3와 s3api의 차이점 : https://dev.classmethod.jp/articles/cli-command-s3-s3-and-s3api-i-tried-to-find-out-what-i-can-do/