AWS S3 보안
Amazon S3(Simple Storage Service)는 클라우드 기반의 데이터 스토리지 서비스로,
AWS를 사용하는 수많은 기업에서 중요한 데이터를 저장하고 관리하는 데 사용하고 있다.
데이터 보관소가 S3인 것을 기본으로 한 파생 서비스들도 상당히 많기 때문에 S3의 사용 사례는 굉장히 많고 다양한데,
이처럼 많이 사용하고 편리한 만큼 다양한 보안 사고도 발생한다.
S3 데이터 유출 사례
https://m.boannews.com/html/detail.html?mtype=1&idx=112737
https://m.boannews.com/html/detail.html?mtype=1&idx=108196
이와 같은 여러가지 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
아래는 특정 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
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/