상세 컨텐츠

본문 제목

[AHSS1기]S3 사용 사례별 보안 가이드

카테고리 없음

by jongil 2023. 9. 2. 20:13

본문

1. 들어가며 

본자료는 [우아한테크세미나] 사례별로 알아보는 안전한 S3 보안 가이드에서 발췌하였습니다.

https://techblog.woowahan.com/6217/ 

https://www.youtube.com/watch?v=vgYfAndrpPU

 

S3는 보안사고로 이어지는 경우가 많은데, 대부분 잘못된 설정에 의한 사고니다. 그리고 S3의 침해사고는 보안 담당자 입장에서 로그를 자세히 분석하지 않는 이상 탐지하기도 어렵습니다. 그러므로 미리미리 취약하지 않도록 잘못된 설정은 관리가 될 수 있도록 조치하여 예방하는 것이 중요합니다. 이러한 위험을 해소하기 위해 가이드를 만들고 가이드를 적절하게 따르고 있는지 모니터링하는 것이 필요하다고 생각합니다. 하지만 S3 가이드를 만들고 정책을 수립하는 것은 어려운 일입니다. 왜냐하면 실제 사용 사례를 들여다보면 개발 등 다양한 목적으로 S3를 사용하고 있는 게 현실이고 잠재적인 위협이 될 수 있는 S3를 식별하는 것은 많은 고민과 경험이 필요하기 때문입니다.

 

보안팀에서 먼저 모범 사례에 대한 고민과 사용자 입장을 염두에 두며 보안 업무를 수행한다면 다양한 직무의 구성원이 자연스럽게 ‘보안이 반드시 불편한 것은 아니구나’ 하며 보안을 준수하려 노력하는 문화를 형성할 것으로 믿고 있습니다.


예를 들어 S3 보안 가이드에서 S3의 퍼블릭 공개 설정은 취약하다고 무작정 IAM user의 S3의 퍼블릭 공개 설정 권한을 제거하거나 S3 > 퍼블릭 액세스 차단 설정정보 기능을 이용하여 퍼블릭 공개 상태로 운영 중인 S3 버킷을 퍼블릭 비공개 제한으로 변경하게 된다면 이는 또 다른 사고로 이어질 수 있습니다.

 

A.버킷의 사용 목적별로 분리하자

B.퍼블릭 엑세스 차단을 하자

C.사용 방법은 심플하게

 

2.S3 사용 사례별 보안 가이드

S3는 데이터 저장이라는 기술을 기반으로 한 서비스이지만 단순 데이터 저장 외에도 다양한 목적으로 사용할 수 있습니다. 가장 대표적인 예는 정적(static) 웹 호스팅(web hosting) 기능입니다. 이 기능은 서버 측 동적 처리가 불필요한 간단한 정적 웹 페이지로만 구성된 웹을 쉽게 구성하여 호스팅할 수 있는 기능입니다. 이 사례에도 물론 보안을 위해 챙겨야 하는 부분들이 있습니다. 모든 사례를 전부 다룰 수 없기에 정적 웹 호스팅 기능을 포함한 다음 네 가지 사례를 살펴보고 S3 사용 목적별로 챙겨야 하는 보안 설정은 무엇이 있는지 정리하고자 합니다.

 

2-1.정적 웹 호스팅 버킷

- 데이터베이스, 벡엔드가 필요한 동적인 액션이 필요없는 웹사이트

- 프론트엔드 페이지로만 서비스가 가능한 정적데이터로만 만들어진 사이트

아래 그림처럼 S3의 정적 웹 호스팅 기능을 활성화하면 S3 버킷의 웹 사이트 엔드포인트 주소를 할당받게 됩니다. 이후 버킷의 모든 퍼블릭 액세스 차단을 비활성화한 다음 버킷 정책에서 모든 접속을 허용 할 수 있도록 아래 정책을 설정하면 웹 호스팅처럼 이용할 수 있습니다.

 

[S3 버킷 생성 후 속성 > 정적 웹 사이트 호스팅 기능]
[any access 버킷 정책 예시]

하지만 이렇게 S3 버킷만으로 정적 웹을 호스팅으로 서비스하기에는 아래와 같이 몇 가지 문제가 있습니다.

 

A.https가 아닌 http 통신을 해야 한다는 점 

B.버킷이 퍼블릭 공개라는 점

C.AWS S3의 엔드포인트 주소를 그대로 사용해야 한다는 점

 

정확히는 위 잠재적 위험성을 제거할 목적으로 추가 설정이 필요하다고 이해하면 좋습니다. 그럼 위 문제들을 해결하기 위해 어떤 설정 들을 하여야 하는지 알아보겠습니다.

 

2-1-1.Cloudfront 연결하기

정적 웹 호스팅을 구성하는 데 있어 위의 3가지  문제들을 해결하기 위해 S3 버킷에 연결할 AWS Cloudfront 서비스가 필요합니다. Cloudfront는 AWS Global Edge Server를 통해 CDN(Content Delivery Network) 역할을 해주는 AWS 서비스입니다. CDN은 컨텐츠를 조금더 빠르게 더 글로벌 엣지 서버에서 캐싱해주고 서빙해주는 서비스 입니다.

                               

[Cloudfront 배포하기]

위 그림처럼 정적 웹 호스팅으로 만든 S3 버킷(ji.s3.s3.ap-northeast-2.amazonaws.com)과 Cloudfront를 연결 후 OAI 설정으로 연결한 Cloudfront를 통해서만 접근할 수 있도록 하겠습니다.

[OAI 개념도]

 

이 OAI 설정은 S3를 퍼블릭으로 공개하지 않고도 Cloudfront를 통해서 S3에 퍼블릭하게 접근할 수 있음과 동시에 Cloudfront를 우회하여 S3에 직접 액세스할 수 없음(중요)을 의미합니다. 특별한 사유가 없다면 Cloudfront를 배포함과 동시에 OAI가 버킷 정책에 업데이트되도록 선택합니다.

 

통신암호를 위해 HTTP 대신 HTTPS를 사용이 필요한데 근데 HTTP로 들어오거나 링크가 HTTP로 공유되는경우가 있을 수 있으니  Cloudfront에서 기본 캐시 동작에서 Redirect HTTP to HTTPS를 설정해줌으로써 http://를 이용하여 접근하는 사용자도 https://로 redirect 될 수 있도록 해줍니다.

[Redirect HTTP to HTTPS]

 

User2입장에서 테스트 해봤을때 S3 에드포인트 주소를 직접 접근을 하더라도 403  에러가 표시되면서 차단이 된다는것을 확인 할 수 있습니다.

 

 

[ji.s3 버킷의 OAI 정책]
[OAI 설정 후 S3 앤드포인트 주소 접근 테스트 결과 – 403 Forbidden]

 

Cloudfront 배포과정에서 설정할 부분은 전부 완료되었으니 이대로 진행 완료하면 됩니다.

업데이트된 S3 버킷의 버킷 정책을 확인해 보면 배포한 Cloudfront의 OAI 설정값이 업데이트된 것을 확인할 수 있습니다.

 

2-1-2. Route53으로 도메인 연결하기

※ 도메인 생성이 안되어 실습은 향후 진행 예정

[Route53 도메인 연결]

Cloudfront의 엔드포인트 주소는 가독성 등의 문제로 서비스에 사용하기 적절하지 않습니다. 

도메인을 연결하기 위해 Route53에서 test-ljh.beta.baemin.com in CNAME 레코드를 지정하였습니다.

[Cloudfront SSL 인증서 설정]

 

Route53 설정 이후 위 그림처럼 Cloudfront에서도 CNAME 설정과 ACM(AWS Certificate Manager)을 이용하여 발급한 beta.baemin.com의 SSL 인증서를 적용합니다.

Cloudfront를 S3에 연결함과 동시에 여러 설정으로 위에서 제시한 세 가지 문제(A, B, C)를 해결했습니다. 

 

https가 아닌 http 통신을 해야 한다는 점 : Cloudfront에 ACM(인증서)을 적용하여 해결

버킷이 퍼블릭 공개라는 점 : Cloudfront를 S3에 연결하여 S3는 Cloudfront 뒤에 숨기고 Cloudfront를 통해서만 접근이 가능하도록 설정후 해결

AWS S3의 엔드포인트 주소를 그대로 이용해야 한다는 점 : Cloudfront의 엔드포인트 주소를 Route53과 연결하여 적절한 서비스 도메인 주소 값을 할당하여 해결

 

2-1-3.AWS WAF 사용하기(선택사항)

※ WAF 사용시 비용 발생 이슈로 실습 생략

정적 웹 호스팅 서비스가 특정 대상에게만 제공할 서비스라면 IP 제어가 필요합니다. 물론, S3 버킷 정책에서도 직접 IP 제어가

가능합니다.

[버킷 정책 IP 제어 예시 – IP 123.123.123.123/32 외에는 버킷에 접근 불가]

정적웹 호스팅 버킷을 서비스 할때 어떤 대상에게만 제한이 되는 경우가 있을수 있을수있다.

모두에게 공개하는것이 아니라 특정대상에게만 공개하는 경우 예를들면 우리가 API 개발 명세서 같은것을

프론트엔드 페이지로 올려서 서비스를 구성했다고 했을때 이는 실제로는 내부구성원들 내부 개발자들

더 나가가서 파트너사 개발자분들 정도에게만 공유돼야 되는 케이스입니다. 이런 경우에도 대부분 네트워크 환경에서 제어가 가능하다. 사내구성원들은 VPN이나 오피스IP 정도로 접근제어가 가능합니다. 위그림처럼 이런 경우에도 S3버킷 정책에서도 직접 IP 제어가 가능합니다. 그러나 오리진 버킷을 숨기고Cloudfront로 연결해서 안전하게 제공하는것이 좋다고 설명한것처럼 그럼 실제로 OAI 설정이 적용되어 있어 버킷 정책으로 컨트롤 하는게 맞지 않을수 있다.

IP 기반의 접근 통제를 S3 버킷 정책에서 관리하게 되면 S3 버킷 정책 수정 권한(PutBucketPolicy)이 있는 IAM User는 모두

버킷 정책을 수정할 수 있으므로 정책이 수정되는 것을 방지할 수 없게 됩니다. 그렇다고 PutBucketPolicy 권한을 IAM user에게서 제거하는 것은 S3 관련 업무 효율성을 떨어뜨릴 수 있습니다PutBucketPolicy Action을 감시하기 위해 Cloudwatch 혹은 Cloudtrail 로그를 이용하여 모니터링할 수는 있으나 PutBucketPolicy 이벤트가 발생할 때마다 변경된 버킷 정책을 보안 담당자가 직접 확인하고 대응해야 하여 비효율적입니다.

[CloudFront에 WAF 연동]

 

제안하는 방법은  Cloudfront 단에  AWS WAF서비스를 이용하여 IP 기반의 접근 통제 정책을 관리하는 것입니다. 일반적으로 AWS WAF는 보안(Security Role)팀에서 관리하므로 임의대로 변경되는 것을 모니터링하기 위한 리소스를 아낄 수 있고 일관된 허용 리스트(allow list) IP 관리가 가능합니다. 그리고 허용 리스트 IP는 등록한 후에는 변경되는 일이 많지 않으므로 보안팀에서 관리한다고 하더라도 크게 비효율적이지도 않습니다.

 

[IP Set 룰 만들기]


AWS WAF는 Cloudfront에 연결할 수 있습니다. 앞서 살펴본Cloudfront 연결하기 장에서 Cloudfront를 버킷에 연결해두었으니 해당 Cloudfront에 WAF를 연결하고 IP Set을 만들어 특정 IP에서만 접속할 수 있도록 제어하도록 하겠습니다.

 

먼저, 허용할 IP를 정한 뒤 IP Set(Woowa-UD-Rule-Allow-OFFICE-IP)으로 규칙을 생성해줍니다. AWS 콘솔에서 AWS WAF > IP Set > Create IP set 에서 생성 가능합니다. 이때 Region은 Global (Cloudfront)을 선택하여 생성해 주어야 합니다.

 

[AWS WAF 특정 IP 허용 룰 예시 – 123.123.123.123/32 IP외 에는 AWS WAF를 통과할 수 없음]

생성 완료 후 AWS WAF > Web ACLs > Create web ACL 에서 S3와 연결된 Cloudfront를 선택하고 Rule builder에서 규칙을 적용하여 룰을 만들 수 있습니다. 위 예시처럼 룰(Json)을 만들어 Woowa-UD-Rule-Allow-OFFICE-IP 규칙에 속한 IP(123.123.123.123/32)가 아니면 모든 트래픽이 Block 되도록 설정할 수 있습니다.

 

이번 장에서 제안하는 보안 설정을 모두 적용한 S3 정적 웹 호스팅 구성도는 위 그림과 같습니다.

[안전한 S3 정적 웹 호스팅을 위한 보안 구성도]

 

2-2.정적 리소스 파일 서빙용 버킷

[동적 서비스 리소스와 정적 리소스 도메인 분리 구성]

위 구성은 정적 웹 사이트호스팅 구성과 비슷해 보일수 있지만 조금 다른케이스입니다

이 그림을 보면 실제 동적인 사이트는 EC2, ALB, IGW, ROUTE53을 통해서 서비스를 하고 있습니다. 그리고 정적인 서비스 같은 경우에는 CloudFront, S3로 서비스를 하고 있습니다. 이경우에는 CloudFront와 연동되어 있는 S3 같은 경우에는 정적 웹사이트 호스팅으로 열 필요가 없습니다. 애가 만약에 없는 경우에는 S3를 퍼블릭으로 열고 S3 엔드포인트 주소를 그대로 프론트앤드에다가 박아서 CSS 나 JPG 같은 경우를 불러옵니다.  

S3 버킷을 정적 리소스 데이터인 css, js, jpg 등을 서빙하기 위한 웹 리소스 저장소로 사용하는 경우입니다. 이 경우에는 S3 버킷 자체를 정적 웹 사이트로 만드는 것이 아니라 서빙이 필요한 정적 파일을 S3 버킷에 담고 버킷을 퍼블릭 공개 설정하여 GetObject를 any access로 허용하고 사용하여 운영하는 경우입니다.

간략하게 정적 리소스 파일 서빙용 버킷 구성 사례를 그림으로 표현하였습니다.이 구성은 MSA 아키텍처(MSA=MicroService Architecture) 방식을 지향하는 구성이라고 볼 수 있습니다. 예를 들어 test-ljh.beta.baemin.com(동적 서비스 리소스)와 test-ljh-cdn.beta.baemin.com(정적 리소스)을 구분하여 동적 서비스 리소스의 서버와 정적 리소스를 서빙하는 대상을 구분하여 사용자가 바라보는 서비스 리소스 간의 의존성 감소, EC2 리소스 낭비 방지, 불필요한 로그 수집 방지, 비용 감소 등 여러 이점을 얻기 위한 구성입니다. 물론, 도메인을 분리하지 않고 test-ljh.beta.baemin.com/cdn/* 은 정적 리소스 S3를 바라보게 하는 방식으로 동적 리소스 대상 서버(EC2)와 정적 리소스 대상 버킷을 Cloudfront 단에서 구분할 수도 있습니다.

 

※ WAF, Shield 서비스까지 고려한다면

하지만 Cloudfront에 AWS WAF를 연결하거나 Cloudfront에 Shield Advanced(DDoS)를 적용할 경우까지 고려한다면 정적 리소스를 요청하는 건도 WAF, Shield Advanced 사용 비용에 추가될 수 있습니다. 따라서 정적 리소스를 서빙하는 S3는 WAF(웹 해킹), Shield Advanced(DDoS) 보호 대상이 아니므로 Cloudfront 단에서 트래픽을 분리하는 것이 아니라 도메인으로 분리하여 실제 보호해야 할 서버와 정적 리소스로 흘러가는 트래픽을 분리하는 것이 여러모로 유리하다고 생각합니다.

 

2-2 정적 리소스 파일 서빙용 버킷에서 발생하는 보안 문제는 2-1 정적 웹 호스팅 버킷 사례에서 다룬 문제들과 크게 다르지 않아 아래처럼 해결하면 됩니다. 

 

https가 아닌 http 통신을 해야 한다는 점 : Cloudfront에 ACM(인증서)을 적용하여 해결

버킷이 퍼블릭 공개라는 점 : Cloudfront를 S3에 연결하여 S3는 Cloudfront 뒤에 숨기고 Cloudfront를 통해서만 접근이 가능하도록 설정후 해결

AWS S3의 엔드포인트 주소를 그대로 이용해야 한다는 점 : Cloudfront의 엔드포인트 주소를 Route53과 연결하여 적절한 서비스 도메인 주소 값을 할당하여 해결

 

2-3.원격 파일 저장용 버킷

※ WAF 사용시 비용 발생 이슈로 실습 생략

원격지에서 S3로 파일을 업로드하거나 공유 목적으로 읽기를 허용해야 하는 경우입니다. 이 경우에 허용 IP를 제어하는 것이 가장 좋지만, 간혹 불가능한 상황도 있습니다. 좀 더 이해하기 위해서 다음 예시를 준비하였습니다.

예시 : 우리는 고객 PC에 설치된 프로그램을 통해 발생하는 로그 파일을 put 하고 있어요.

 예시는 버킷에 접근하는 대상을 특정할 수 없어 불특정 다수에게 열려야 하는 상황입니다. 만약, 대상을 지정할 수 있었다면 2-1-3 AWS WAF 사용하기 작업을 참고하여 IP로 대상을 제어하는 것이 모범사례입니다.
하지만 이 경우에는 불특정 다수에게 열려야 하므로 위 방법처럼 IP 제어가 불가능하고 퍼블릭한 상황에서 버킷명을 알고 있다면 누구나 S3에 접근할 수 있는 위험을 갖게 됩니다. 이때 완벽한 보안 방법은 아니지만, 차선책으로 사전에 약속된 웹 헤더 문자열 값을 검사하도록 하여 그 헤더에 문자열이 없는 경우는 비정상 접근으로 판단하고 차단하는 방법을 사용할 수 있습니다.

[버킷 정책 Referer 제어 예시 – Referer : https://CheckValue 값을 포함하지 않으면 접근 불가]

위 예시처럼 버킷 정책에서 Condition값을 이용하여 지정한 웹 헤더(Referer)의 문자열 검사를 할 수 있습니다. 하지만 2-1-3 AWS WAF 사용하기 장에서 언급한 ‘버킷에서 제어 정책을 설정하는 것보다 WAF에서 설정하는 게 좋은 이유’와 같이 문자열 검사 및 차단하는 역할은 AWS WAF에서 진행하는 것이 좋습니다.

[AWS WAF 헤더 검사 룰 예시 – check : woowa-check 값을 포함하지 않으면 AWS WAF를 통과할 수 없음]

 

S3와 연결된 Cloudfront에 AWS WAF를 적용하여 문자열 검사 룰을 만들어 적용합니다. AWS 콘솔 AWS WAF > Web ACLs > Rule > Rule builder 에서 위 예시를 참고하여 웹 헤더의 문자열 검사를 수행하는 룰을 생성하여 WAF에 적용합니다.

[WAF를 이용한 특정 헤더의 문자열 검사 구성도]

 

※ WAF 헤더 검사 내용 정리
공격자(Bad User)가 버킷 이름을 알고 있다고 하여도, Cloudfront와 S3는 OAI(Origin Access Identity)설정이 되어 있어 버킷으로 바로 접근하지 못합니다.
S3는 Cloudfront와 연결함과 동시에 퍼블릭 비공개 설정(Private)으로 전환합니다.
공격자가 Cloudfront에 할당된 도메인 주소(그림에서 test-ljh.beta.baemin.com)를 알고 있다 하여도 특정 웹 헤더 검사를 하는 것은 확인하기 어렵습니다.*

따라서, 버킷에 연결된 도메인 주소와 검사하고 있는 임의의 웹 헤더, 웹 헤더 값을 모두 알고 있어야 우회가 가능합니다. 따라서, 버킷에 연결된 도메인 주소와 검사하고 있는 임의의 웹 헤더, 웹 헤더 값을 모두 알고 있어야 우회할 수 있습니다.

다만, 이 방법이 완벽한 방법은 아니라고 표현한 이유는 공격자 입장에서 PC 프로그램을 리버스 엔지니어링 혹은 동적 분석(프록시)을 통해 분석할 역량이 된다면 웹 헤더에 특정 헤더를 추가하여 원격 파일 저장소와 통신하는 것을 아는 것이 가능하기 때문입니다. 하지만 보안 관점에서 이 방법을 적용한 보안 수준은 단순히 버킷 명만 알고 있는 상황에서 공격자가 PUT, GET 메소드 등으로 접근되도록 구성하는 것과 하늘과 땅 차이라고 생각합니다.

 

2-4.민감한 정보 저장용 버킷

※ IAM 공부후 실습 예정

이 사례에서 민감한 정보는 기업 입장에서 보안사고 등에 의해 유출되면 위험이 커지는 정보나 소홀히 관리되지 않아야 하는 중요한 정보를 의미합니다. 예를 들면 고객 개인정보가 포함된 정보인 경우입니다. 물론, 정보보안 최고 책임자 등 판단에 따라서 민감한 정보의 범위는 개인정보 외에도 다양한 정보가 될 수도 있습니다.
이번 민감한 정보 저장용 버킷 사례에서 다뤄볼 예시는 AWS 멀티 계정(Multi Account)환경에서 서비스를 운영하는 상황을 가정하고 다루었습니다.

 

[여러 계정에 방치된 민감 정보 버킷]

위 그림과 같이 서비스 운영 ‘계정 1’, ‘계정 2’에서 서비스에 필요한 S3 버킷들이 만들어진 상태라고 가정해 보겠습니다. 이 상황에서 버킷 운영 및 관리에서 다음과 같은 문제가 생길 수 있습니다.

  1. 운영 버킷 중에서는 보안사고에 민감하지 않은 파일들이 저장된 버킷들도 있겠지만 일부는 민감한 정보를 담고 있거나 민감 정보와 비 민감 정보를 함께 담은 버킷도 존재할 것입니다. 이 경우에는 하나의 버킷에 하위 경로(PATH)를 구분하여 사용하는데, 장기적으로 관리의 부재에 의해 방치되거나 구성상 취약하게 설정되어 위험이 높아질 수 있습니다.
  2. 버킷에 태그(Tag) 정보가 누락되었을 수 있습니다. 물론, 기업 내 태그 정책이 강제화되어있다면 문제없겠지만 버킷 관리만을 위한 태그 정책 기준이 뚜렷하지 않다면 추후 식별이 어려워지거나 관리가 어려울 수 있습니다.
  3. 버킷의 태그 기준 정보가 확실하다면 버킷의 이름은 크게 문제 되지 않지만 그렇지 않은 경우에는 버킷의 이름에 일관성이 없어 추후 식별이 어렵거나 관리에 어려움이 생길 수 있습니다.
  4. 버킷의 문서화 혹은 태그가 제대로 되어 있지 않은 상태에서 버킷 안에 민감 정보가 저장되어 있는지 아닌지 버킷 관련 담당자가 아니라면 알기 어렵습니다. 담당자가 퇴사하거나 조직 이동이 발생하면 추적 관리가 어려워질 수 있습니다.
  5. 서비스 계정에는 다양한 직무(IAM Role)의 IAM user가 접근할 수 있습니다. 이때 내부 사용자의 실수 등에 의해 민감 버킷 내 정보가 삭제되거나 탈취될 수 있습니다.
  6. 많은 IAM 권한을 가진 EC2(Server) 혹은 Accesskey 등이 해킹되었을 때 같은 계정 내에 있는 버킷들이 탈취될 수 있습니다. 이때 민감한 버킷들에 담긴 정보가 공격자에 의해 유출될 수 있습니다.

3-1.민감한 정보 저장용 버킷

[제안하는 민감 버킷 관리 구성]

위 문제를 해결하기 위해 제안하는 방법은 제한된 계정(보안 계정)으로 민감 정보를 담는 버킷(이하, 민감 버킷)을 분리하여 관리하는 방법입니다. 이때 제한된 계정은 IAM User 중 Security Role이 할당된 사용자만 접근이 가능한 계정이어야 하며 대외 서비스 목적으로 운영되는 리소스는 없어야 합니다. 

 

제안하는 방법대로 분리할 때 다음과 같은 이점이 있습니다.

  1. 서비스 팀에서 민감한 정보를 다룰 때 보안팀 담당자가 직접 보안 계정에 버킷을 생성합니다. 민감 버킷 담당자가 직접 이름 규칙, 태그 규칙, 버킷 정보 문서를 관리하게 되므로 일관성 있게 버킷을 관리할 수 있습니다.
  2. 컴플라이언스 이슈로 인해 어떤 정보들은 2년 이상 보관을 해야 하거나 짧게 보관하고 파기해야 하는 경우가 있을 수 있습니다. 이러한 경우 보안팀 주관으로 분리된 계정에서 관리하고 있으므로 일괄적인 관리에 용이합니다.
  3. 서비스 계정 콘솔로 접근할 수 있는 IAM User가 제한된 보안 계정에 접근할 수 없으므로 버킷이 내부 사용자의 실수 등에 의해 삭제되거나 탈취되는 경우를 예방할 수 있습니다.
  4. 서비스 계정의 서버나 Accesskey가 해킹된 상황이어도 분리된 계정에 접근할 권한이 없는 경우 민감한 정보를 담고 있는 버킷까지는 접근이 불가합니다.

 

여기서 한 가지 고민해야 할 부분이 있습니다. 민감 버킷을 보안 계정에 분리하더라도 서비스 계정에 있는 서버에서 민감 버킷에 접근해야 하는 경우입니다. 제한된 계정인 만큼 다른 계정과의 연결은 지양하는 게 좋으나 서비스 목적으로 연결이 불가피하다면 민감 버킷과 각 서비스 계정의 서버 간의 교차 계정(cross account/multi account) 접근 시 최소 권한을 제공하여 필요한 서버에서만 제한적으로 접근이 되도록 할 수 있습니다.

 

계정 1의 ‘ec2-baemin’ 서버가 보안 계정의 ‘best-ljh-test-bucket’ 버킷에 접근하는 상황을 가정해 보겠습니다. 교차 계정 환경에서 타 계정에 있는 리소스가 접근할 수 있도록 하는 방법은 여러 가지가 있지만, 그중 IAM Role 기반의 버킷 허용 정책을 이용하여 작업을 진행하도록 하겠습니다.

IAM Role 이름 : woowa-iam-ec2-baemin-role

inline policy 이름 : iam-01-to-security-s3-policy

[보안 계정의 대상 버킷에서 ec2-baemin이 접근할 수 있는 허용 정책]

먼저, 계정 1의 ‘ec2-baemin’ 서버가 사용할 IAM Role(woowa-iam-ec2-baemin-role)과 Inline Policy(iam-01-to-security-s3-policy)를 위와 같이 만듭니다. 이제 ‘ec2-baemin’이 사용할 IAM Role을 지정해 주기 위해 ec2 콘솔로 이동하여 ‘ec2-baemin’에서 ec2 > 보안 > IAM 역할 수정 에서 위 IAM Role(woowa-iam-ec2-baemin-role)을 지정합니다.

 

[보안 계정의 대상 버킷에서 ec2-baemin이 접근할 수 있는 허용 정책]

보안 계정에서 버킷(priavte-baemin)을 생성하고 버킷 정책에서 ‘ec2-baemin’서버가 사용하는 IAM Role(woowa-iam-ec2-baemin-role)이 접근할 수 있도록 버킷 정책을 수정해 줍니다.


테스트를 위해 보안 계정 버킷 best-ljh-test-bucket에 파일 ljh0209.html을 올려두었습니다.

[best-ljh-test-bucket 버킷에 업로드된 ljh0209.html]

계정 1에 있는 ‘ec2-baemin’ 서버에 CLI로 접속하여 IAM Role (woowa-iam-ec2-baemin-role)을 이용하여 보안 계정에 있는 best-ljh-test-bucket의 파일을 조회하였습니다.

> $ aws s3api list-objects –bucket best-ljh0209-test-bucket

[ 계정 1의 서버에서 보안 계정 버킷(best-ljh-test-bucket) 조회 결과]

테스트 결과 보안 계정 best-ljh-test-bucket 버킷에 업로드되어 있는 ljh0209.html 파일의 정보가 반환되는 것을 확인할 수 있습니다.

 

IAM Role 기반 교차 계정에서의 접근 구성을 그림으로 표현하면 위와 같습니다. 이 구성은 반드시 서비스상 분리된 계정에서 보안 계정의 버킷(best-ljh0209-test-bucket)에 접근할 수 있는 IAM Role(woowa-iam-ec2-baemin-role)을 가진 리소스(ec2-baemin)만 보안 계정의 버킷 정책에 의한 허용된 권한에 의해서 접근할 수 있습니다.

[IAM Role 기반 교차 계정 버킷 접근 구성]

3-2.침해사고대응 관점에서 바라본 민감 정보 버킷 분리 보관의 이점

침해사고대응 관점에서 민감 정보가 담긴 버킷을 별도 계정에 분리 보관하면 여러 보안사고 상황을 대비할 수 있습니다.

[A 서버 침해사고 시나리오 사례]

 

위 그림처럼 EC2(Server)에 적용된 IAM Role에 최소한의 권한보다 많은 권한이 부여된 경우를 가정해 보겠습니다. A 서버와 B 서버에 할당된 IAM Role (S3:*)은 A 서버가 해킹당한 상황에서 의도하지 않게 민감한 정보를 담은 버킷(Sensitive info bucket)까지 공격자(Hacker)가 도달할 수 있게 하는 도구가 될 수 있습니다. 격자 입장에서 AWS 서버를 해킹할 경우 먼저 해당 계정에 있는 모든 버킷을 목록화한 다음 해당 버킷들의 정보들을 모두 탈취하는 방식으로 개인정보 유출 등을 수행하기 때문입니다.

[A 서버 침해사고 상황에서 보안 계정으로 전이 실패 사례]

민감 정보가 담긴 버킷을 별도 계정에 분리하였다면 이러한 침해사고 상황에서 민감한 정보가 버킷에 의해 유출되는 위험을 감소시킬 수 있습니다. 만약, 서비스 목적으로 계정 1의 A 서버와 보안 계정의 민감 버킷이 IAM Role 기반으로 교차계정 허용 연결이 되어 있더라도 보안 계정의 버킷 정보를 알 수 없다면 접근이 불가합니다.

 

A 서버에 해당 IAM Role의 Policy 정보를 확인(Describe)할 수 있는 권한이 부여되어 있다면 알 수 있겠지만 최소권한 부여 원칙을 지켰다면 서버가 사용할 IAM Role에 Describe IAM Policy이 포함된 IAM Role을 부여할 일은 없습니다.

 

정리하면 계정 1의 A 서버 해킹에 성공한 공격자(Hacker)는 보안 계정의 민감 정보 버킷에 접근하기 위해서는 민감 정보 버킷 정보를 미리 알고 있어야 하므로 단순히 s3 list-bucket으로 같은 계정에서 민감 정보 버킷이 노출되는 상황보다는 훨씬 안전한 상황이라고 할 수 있습니다.

 

[Accesskey 유출에 의한 버킷 침해사고 시나리오]

위 그림처럼 Accesskey에 의한 버킷 침해사고 시나리오로 예를 들어보겠습니다. 개발자 A 님이 소유한 계정 1의 ‘S3:*’ 권한이 부여된 IAM user의 Accesskey를 공개된 개인 블로그에 그대로 올리게 되어 키는 불특정 다수에게 유출된 상황입니다. 이 Accesskey를 획득한 공격자는 나쁜 마음을 먹고 돈이 될만한 정보를 찾거나 추가 해킹을 시도하기 위해 여러 명령어를 수행하게 됩니다. 그중에서도 가장 쉽고 효과가 좋은 Accesskey가 발급된 계정에서의 S3 버킷 정보들을 먼저 확인해 볼 것입니다.

하지 민감 정보가 담긴 버킷(공격자 입장에서 돈이 될만한, 흥미로운)은 전부 별도 보안 계정에서 보관하고 있으므로 개발자 A님의 Accesskey로는 접근이 불가합니다. Accesskey가 접근할 수 있는 계정 1에서는 Garbage data, Test data뿐인 버킷밖에 없습니다. 기업 입장에서는 침해사고 상황이 발생하였지만 개인정보가 유출되었거나 기업의 이미지가 크게 실추되는 상황은 발생하지 않았습니다.

 

3-3.실무적인 질문 

정리중