본문 바로가기

웹 운영/AWS

[CDA] 섹션 14 - Amazon S3 보안

728x90

141강 <S3 암호화>

 

네가지 방법을 사용해서 S3 객체들을 암호화할 수 있다

 

(1) Server Side Encryption (SSE)

1) SSE - S3

> 아마존 S3 가 관리하는 Key 로 서버 사이드 암호화한다 - default 옵션

 

2) SSE - KMS

> AWS Key Management Service 를 활용해서 암호화 키를 관리 

 

3) SSE - C

> 내가 스스로 나의 Key 를 관리한다 (Customer Provided)

 

 

(2) Client Side Encryption (CSE)

> 클라이언트 측에서 암호화를 전담하는 것

 

> 각각 어떤 상황에서 적합한지를 알고 있는 것이 중요

 

----

 

1) SSE -S3 

 

> AWS 로 부터 관리되고 핸들되는 키를 사용해서 암호화된다 - 우리는 절대 access 할 수 없음

> Encryption Type : AES-256

> SSE - S3 로 Amazon S3 객체 암호화를 요청하려면 "x-amz-server-side-encryption":"AES256" 의 헤더를 명시해야 한다

> 새 객체, 새 버킷에는 기본적으로 설정된다

 

SSE S3 과정

 

> Client 는 업로딩을 하면, A-S3 에서 객체와 S3 Owned Key 를 활용해 암호화 후 버킷에 저장한다

 

 

2) SSE - KMS (더 강화된듯?)

 

> 내 키를 KMS 서비스를 활용해서 관리 하는 것

> 스스로 제어할 수 있다는 장점, CloudTrail 을 사용해서 키를 수정할 수 있다는 장점

> "x-amz-server-side-encryption":"aws:kms" 라는 헤더가 필요하다

> 위 그림에서 header 는 다를 것이다.

> 그리고 S3 Owned Key 가 아닌, AWS KMS 서비스를 활용한 Key 를 활용하는 모습임을 확인할 수 있다

 

API 를 지속해서 호출한다

 

> KMS 키는 API 가 있고, S3 가 이를 활용하게 된다

> 업로드를 할 때는 GenerateDataKey KMS API 를 활용하고, 다운로드 할 때는 Decrypt KMS API 를 활용하게 된다

>  KMS quota per seconds 로 측정이 됨. 그리고 이는 limit 가 있음. 지역에 따라 5500, 10000, 30000 req/s 정도

>> 엄청 엄청 높은 req 처리율을 보여줘야 한다면, Service Quotas Console 에서 이를 증가 요청할 수 있다

>> 해결방안 exam 에 나올 수 있음

 

3) SSE - C

 

> AWS 외부에서 키가 관리된다, HTTPS 가 필수로 사용되어야 한다

> AWS S3 는 너가 제공하는 키를 절대 관리하지 않는다. 보관하지도 않는다

> 모든 HTTP 요청 헤더에 Encryption Key 가 전달되어야 한다

외부에서 제공하는 키를 활용한 모습

 

> Read 를 하기 위해선 당연히 Decrypt Key 를 전달해야 한다

 

 

4) Client Side Encryption (아마존이 전혀 관여하지 않는다) 

 

> AWS S3 Client-Side Encryption Library 와 같은 Client 라이브러리를 많이 활용한다

> Client 는 S3 로 객체를 보내기 전에 스스로 Encryption 을 진행 후 보내게 된다

> Decryption 역시 Client 에서 진행한다

> Customer fully manages the key and encryption cycle

 

Client 측에서 암호화 한 이후 전달한다. Decrypt 역시 Client 에서 진행한다

 

 

 

< Encryption in Transit - SSL / TLS >

 

> SSL / TLS - Encryption in Flight(Transit) (이거 이렇게 표현하기도 하나봄) 

> Amazon S3 는 two endpoint 가 있는데, Http, Https 이다. 이 중 http 는 non encrypted 이며, https 는 encryption in flight 라고 한다

> A-S3 를 사용할 때는 필히 HTTPS 사용하는 것을 권장한다

> 참고로 SSE-C 를 사용하는 케이스라면 HTTPS 는 필수이다

> 대부분의 client 는 어차피 HTTPs 를 사용한다

 

 

< Force Encryption in Transit aws : SecureTransport >

 

> Policy 를 사용할 수 있다

{
    "Version" : "2012-10-17",
    "Statement" : [
        {
            "Effect" : "Deny",
            "Principal" : "*",
            "Action" : "s3:GetObject",
            "Resource" : "arn:aws:s3:::my-bucket/*",
            "Condition" : {
                "Bool" : {
                    "aws:SecureTransport" : "false"
                    }
                }
            }
        }
    ]
}

 

> Https 를 사용하면 SecureTransport  가 true 로 설정되므로, 위 policy 를 버킷 policy 에 적용하면 http 는 금지된다. http 로 s3 를 접근하려는 유저를 금지한다는 뜻

 

---------------------------------------------

 

143 강 <S3 암호화 실습>

 

> SSE-S3 옵션을 선택 후 (기본적으로 선택되어 있음)  bucket 생성 후, 파일 업로드를 해보면, 파일에 다음과 같은 항목을 확인 가능

 

> 특정 파일에 대해서 변경할 수도 있음 - 변경하면 new version of the object with updated setting 으로 생성된다.

> SSE - KMS 르 변경해봤다. 

> 그러면 두 가지 옵션이 나옴 (AWS KMS 키 중에서 선택 / AWS KMS 키 ARN 입력)

> 첫번째 옵션 선택하면 기본적으로 하나가 있는데, 이건 default kms key for s3 service 이다. (KMS 키 생성후 보관하면 돈 든다!) 

> 객체의 버전을 확인해보면 두 개인 것을 볼 수 있음 

> 현재 버전은 아래와 같음을 알 수 있음

 

> 버킷 키는 자동으로 활성화 되어 있는데, 내부적으로 AWS KMS API 콜을 줄여서 비용 절감하는 행위이다. (S3 경우 상관없음) 

 

> 클라이언트 사이드 같은 경우에는 별도로 AWS 한테 알려줄 필요 없이, 알아서 Encrypt / Decrypt 하면 됨

 

 

---------------------------------------------

 

144 강 <Default Encryption vs Bucket Policies>

 

> SSE - S3 암호화는 S3 버킷에 저장되는 새 객체에는 항상 자동으로 적용된다

> 선택적으로, bucket policy 를 사용하여 "암호화를 강제" 시킬 수 있고, 이를 통해 encryption 되어 있다는 헤더가 없는 S3 Put Object 요청은 거절할 수 있다 

 

ex) 아까 봤던 Policy 처럼 Condition key 안에 다음과 같은걸 넣는거임

{ // 컨디션 안에 Object 들로 올 수 있는 것들
    "StringNotEquals" : {
        "s3:x-amz-server-side-encryption" : "aws:kms"
        }
    }
    // 혹은
    "Null" : {
        "s3:x-amz-server-side-encryption-customer-algorithm" : "true"
    }
}

 

> put object 요청에 aws:kms 란 헤더가 없으면 거절하라, customer-side-algorithm (SSE-C) 가 없다면 거절하라 이런 정책임.

> Bucket Policy 가 force the way to encrypt 할 수 있음

> 즉, Bucket Policies are evaluated before "Default Encryption" 임을 기억해라

> 솔직히 무슨 소린지 정확하게는 모르겠음

 

---------------------------------------------

 

145 강 < S3 CORS > 

 

> CORS 란? - Cross - Origin Resource Sharing (CORS)

> Origin = protocol + host + port / 클라이언트가 다운받은 웹에서 직접 다른 곳으로 요청 때릴 때 발생하는거임 ㅇㅇ

> CORS 를 허용한다는 건 main origin 을 사용하는 도중 다른 origin 에게 요청을 날리는 것을 허용하겠다는 "웹 브라우저" 정책이다. 

> 이런 요청은  CORS Header 로 허용한다는 헤더가 오기 전까지 금지된다.

 

CORS 허용에 대한 동작 매커니즘

 

> Preflight 로 먼저 이 요청이 되는지 OPTIONS Http 요청 method 를 활용해서 확인하게 된다

> S3 에 적용되는 모습은? 매우 유명한 시험 문제!

> client 가 s3 버킷에 직접적으로 Cross-origin 요청을 날리게 되면, correct CORS 헤더를 명시해줘야 한다. 실제 웹 브라우저에서 특정 이미지를 보여줄 때 발생할 수도 있음. (그런가? image view 할 때도 cors 가 발생하나?)

> 너가 허용하려는 origin (유저 탐색할 main domain 정도, 위 그림에서 www.example.com) & 명시해주거나  * 을 통해 모든 오리진을 허용한다고 명시해줄 수 있다.

> 아래와 같은 예제가 있을 수 있음 (특정 index.html 을 반환한 오리진과 다른 곳에서 이미지를 가져와야 하는 경우) 

CORS 허용시 동작하는 과정

 

 

---------------------------------------------

 

146 강 CORS 실습

 

> coffee.jpg 을 보여주는 <img> 태그가 있는 html 이 있는데, JS 를 포함하고 있는데 이 JS 는 extra-page.html 을 fetch 요청하는 JS 를 포함하고 있다. (새로운 html 페이지를 로딩하는 JS 이다)

> index.html, extra-page.html 을 동시에 업로드를 하고, index.html 을 열어보면, 같은 오리진에 있기 때문에 extra-page.html 도 정상적으로 로딩되는 모습을 확인할 수 있다.

 

-- 이제부터 CORS 를 발생시키기 위한 실습

> extra-page.html 을 다른 오리진의 버킷으로 옮기기 위해 새 버킷 생성. (버킷 만들 때 외부 public access 허용시켜줘야 함) 

 

> 그 버킷에서 속성 맨 아래서 정적 웹 사이트 호스팅을 활성화 시킴 (WS 로서 동작을 지원하라는 뜻인듯?)

> Host website 및 index.html 을 주기로 함

> 이후 Permission 에 가서, 이 버킷 ARN 을 Resource 로 명시해서, GetObject 하는 것을 allow 하겠다는 정책을 세움 (강의 2:47초)

> 여기에 extra-page.html 을 올렸다.

> 기존 버킷의 extra-page.html 을 삭제하고, index.html 을 수정한다 -> 오리진을 바꾸도록 index.html 의 fetch url 을 수정한다

> 이렇게 하고 index.html 을 호출하면 예상하듯이 CORS 를 발생시킨다

 

-- 이제부터 CORS 를 해결하기 위함

> 아까 두번째 버킷에 속성을 가서 CORS 속성이 맨 아래 있음

> 다음과 같은 CORS 설정 정책을 추가한다 (웹 서버 자체가 지금 S3 일 때임 ㅋㅋㅋ 아닐때는 알아서 백엔드 서버 제어하면 됨) 

[
    {
        "AllowedHeaders": [
            "Authorization"
        ],
        "AllowedMethods": [
            "GET"
        ],
        "AllowedOrigins": [
            "<url of first bucket with http:// ~~~ (맨 뒤 slash 없어야 함>"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
]

 

> 이렇게 하면 저 오리진에 대한 GET 방법의 CORS 를 허용시킨다는 의미이다. 적용 결과 CORS 가 발생하지 않는 것을 볼 수 있다. 

> 간단한 것들은 S3 로 호스팅해도 되겠다 싶네 ㅇㅇ

 

 

-----------------------------------------------------

 

147 강 < MFA 삭제 >

 

> MFA : Multi Factor Authentication - 본인의 기기로 code 를 확인하고 S3 에 일을 수행할 수 있도록 하는 것

> 객체 특정 버전을 영구 삭제할 때, 버킷 자체에 버저닝을 중지하려 할 때 -> MFA 활성화시 필수적으로 요구됨

> 버저닝을 다시 킬 때, 삭제된 버전들을 조회할 때(?) > 중요한 작업이 아니므로 MFA 가 필수적이지 않음 

> MFA Delete 를 활성화하려면, 버저닝을 활성화해야 한다. 그리고 오직 root account 만으로 MFA Delete 을 활성화 / 비활성화 할 수 있다.

> 많이 사용하는 건 아니지만, 이런 extra protection 장치가 있음을 알아두기 (S3 객체를 삭제할 때에 대한)

 

148 강 < MFA 삭제 실습 > 

 

> 버저닝 활성화 이후 아무 버킷 하나 생성

> 속성의 버킷 버저닝 탭에 들어가서 확인해보면 MFA Delete 은 비활성화 되어 있고, UI 로 활성화가 불가능하다.

> AWS CLI 로 해야함.

 

 

> IAM 에 들어가서 My Security Credentials 로 들어가고, MFA 에 가서 기기 하나 SU 해야 한다

> Access Key, Secret Key 를 하나 발급 받는다

> 그리고 AWS CLI 를 사용해서 다음과 같이 진행한다

 

$ aws configure --profile root-mfa-delete-demo  ## Generate Profile Using Access Key 

> 위에서 발급받은 Access Key, 시크릿 키를 활용해서 해당 프로파일을 만든다

 

$ aws ls --profile root-mfa-delete-demo ## 해당 프로파일로 접근할 수 있는 내가 가지고 있는 S3 버킷들을 보여준다

 

$ aws s3api put-bucket-versioning --bucket {버킷명:demo-ws-bucket} --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa "{arn-of-mfa-device + mfa-code}" --profile root-mfa-delete-demo

> 내가 원하는 설정 수정 버킷명과, 버저닝 설정 변경하려는 점들을 명시해주고 (Enabled 표기된 것들), 아까 IAM 에서 My Security Credentials 에서 확인할 수 있었던 MFA 기기와 arn 을 {arn-of-mfa-device} 안에 넣어준다. 그리고 현재 기기내에 표시중인 mfa-code 를 띄어쓰기 이후에 같이 표기한다 ex: --mfa "arn:aws:iam::001232..132:mfa/root-account-mfa-device 123456"

 

> 아까 그 버킷에 가면, 버킷 버저닝 항목에 MFA Delete 이 활성화됨으로 표시된걸 확인할 수 있다

> 그리고 Object 를 업로드 하고, 그걸 다시 삭제하려고 해보자. > 그러면 삭제는 되지만, Delete marker 된 버전이 있는거고, 원본 버전은 남아있다. 그럼 그걸 삭제하려고 하면, MFA 활성화 되어 있으니, CLI 를 활용해서 특정 버전을 삭제할 수 있다. (이 명령어는 강의에 안나온 듯) 

 

> MFADelete 를 비활성화하려면 다음 명령어를 사용할 수 있다.

$ aws s3api put-bucket-versioning --bucket {버킷명} --versioning-configuration Status=Enabled,MFADelete=Disabled --mfa "위랑 똑같이" --profile root-mfa-delete-demo

 

> 이번 실습에 사용된 access key / secret key 는 꼭 지우는걸 권장. 목적에 맞게 활용해야함. 

 

-----------------------------------------------------

 

149강 <S3 Access Log>

 

> S3 버킷 로그를 확인하고 싶을 수 있다.

> Authorize, Deny 등에 상관 없이, S3 로 요청된 모든것은 로깅된다 (다른 S3 버킷으로 설정해둘 수 있음)

> Data Analysis tool 을 사용해서 분석될 수 있다

> 저장하려는 버킷은 타겟 버킷과 AWS 지역이 같아야 한다. 로깅 포맷은 AWS 에서 지원된다

> 서로 로깅하면 망함. (기하급수적으로 로그가 증가, 돈 엄청 내게 됨) 

 

150 강 <Access Log 실습>

 

> 굳이 따라하진 않음, 속성으로 가서 Sever Access Logging 으로 가서 Enable 을 함

> Target Bucket 을 지정해야 하는데, Access Log 버킷을 만들어서 지정한다.

> 이 때, 특정 객체를 조회하고, 어떤 다른 파일을 올리고, 여러 활동을 해보자. 

> 그 이후, 이 활동들은 Activity 를 생성하게 되고, 이것들인 access log 버킷에 저장된다

> 근데 액세스 로그 버킷을 지정하다보면, "Bucket Policy Will be updated" 이란 표시를 확인할 수 있는데, 이건 로깅 버킷의 정책을 변경한다는 것이다. AWS 의 S3 로깅 서비스가 만든 객체들을 이 로깅 버킷에 putObject 할 수 있도록 변경된 것이다. 

> 시간이 좀 지났는데, 한 두시간까지 걸리기도 한다. 이렇게 하면 내가 위에서 한 "활동"들이 저장되었다. 

 

-----------------------------------------------------

 

151 강 <Pre Signed URLs>

 

> S3 콘솔, AWS CLI/SDK 를 활용해서 만들 수 있다

> URL 만료기간 존재. Console - 12시간, CLI/SDK - 최대 168시간 등

> pre signed URL 을 사용하는 유저는 이 URL 을 만든 유저와 GET/PUT 에 대하여 동일한 권한을 사용할 수 있게 된다

> 내가 특정 Use Case 를 위해 누군가의 버킷 사용을 허용해줘야 하는데, 그것만을 위해 정책을 바꾸긴 곤란할 때. 

> presignedUrl -> 내 권한과 credential 을 활용해서 만들어 진다.

> Use Case : Temporary access for download/upload of specific file

> Use Case : Allow only logged in users to download a premium video from your s3 bucket

> Use Case : Allow an ever-changing list of users to download files by generating URL dynamically. (?) 뭔소리

 

152 강 실습

 

> 외부에서 접근을 허용하지 않은 bucket 에서 객체 접근 URL 을 확인하면 Access Denied 가 발생한다

> 하지만 콘솔에 Open 버튼을 누르면 접근 가능하도록 설정된 URL 로 이동하는 탭을 만들어서 보여준다. (URL 보면 pre-signed-url 로 형성된 것을 확인할 수 있다) 

> CLI / SDK 를 활용하기도 하지만, 콘솔에서는 object action 에 share presigned URL 을 확인한다.

> 그럼 이 URL 의 유효시간을 설정할 수 있다. (5분 동안 이런식) 

> 이 URL 이 만들어지면, 이 URL을 통해서 다른 사람들도 접근할 수 있다. (보안이 보장된 상태에서 공유도 할 수 있는 매우 유용한 기능!!) 

 

-----------------------------------------------------

 

153 강 <S3 액세스 지점: Access Points> 

 

> 한 S3 버킷에더 다양한 폴더를 관리하고 (finance / sales), 다양한 유저가 목적에 맞게 접근한다

> 이는 버킷 폴리시로 관리하면 되지만, 데이터 기준이 많아질 수록 더더 복잡해질 수밖에 없음

> AccessPoint 를 만들 수 있음 > Finance Access Point 같은걸 만들어서, access point policy 로 분할해서 따로 관리 할 수 있다

 

액세스포인트로 분할된 S3 정책

 

> 버킷을 분할해서, 특정 그룹이 이 일부만 access 할 수 있게 하는 것임. 

> 각 Access Point 들은 각각의 DNS 이름을 가질 수 있다 (Internet Origin or VPC Origin) 

> allow to manage s3 security at scale. 

 

특정 VPC 만의 AccessPoint 접근 허용

 

> 유명한 Use Case 로는, VPC 오리진과 연동하는 방법이다 -> 특정 Access Point 는 특정 VPC 만의 접근을 허용할 수 있다.

> 그러려면 VPC Endpoint 라는 리소스를 활용해야함. VPC Endpoint 는 해당 AccessPoint 의 접근 권한을 가지고 있는 policy 를 가지고 있어야 한다. 

 

 

-----------------------------------------------------

 

154 강 <S3 액세스 지점 Use Case : S3 Object Lambda>

 

 

> 호출하는 앱으로 전달되기 직전에 객체를 가공하고 싶을 때 AWS 람다 함수를 사용할 수 있다

>  단일 S3 버킷에 대하여, S3 Access Point 나 S3 Object Lambda Access Point 를 활용할 수 있는 것.

 

> E-Commerce 앱이 S3 버킷을 직접적으로 송수신할 수 있다

> 분석 앱도 접근을 수행하고 싶은데, Redacted Object (객체 내에서 줘야 하는 정보만을 주도록 수정) 만을  송수신하고 싶음. 

> 이럴 때 Access Point 와 람다 함수를 연동하고, S3 Object Lambda Access Point 를 같이 연동해줄 수 있다 (자동화하는 것)

> 람다 함수로 redact 일을 수행하는 것이며, S3OLAP 에 분석 앱이 접근하는 것임. 분석 앱이 S3OLAP 에 요청을 하면, 이 지점에서 람다 함수를 트리거 한다. 그 과정에 AccessPoint 로부터 S3 버킷 정보 수신이 포함되어 있는 것~!

> 마케팅 앱도 Enrich Object 에 접근하고 싶음. Enrich 화된 객체를 또 다 만드는 것이 아니라 (이게 중요한 부분), Enriching 하는 람다 함수를 만들고, 이를 위한 람다 access point 를 외부 앱에 제공할 수 있는 것이다.

> 전부 다 S3 버킷을 활용할 때의 얘기인건 알고 있으셈

> Use Case : 분석이나 다른 용도를 위해 정보를 redact 하여 보내주는 경우

> Use Case : 데이터 포맷을 변환하여 전달해주고 싶은 경우 (XML / JSON) 

> Use Case : Resize / Watermarking images, 혹은 요청한 자가 누군지 표시해주는 행위를 하고 싶을 때 (동영상에 내 ID 뜨고 이런거) 

 

 

<14강 퀴즈>

1. S3 파일 암호화를 원하지만, 키를 철저히 관리하기 위해 AWS 저장하기 싫어함 - 클라이언트 측 암호화 틀림 (S3 에서 암호화하고 싶기 때문) - 키를 직접 하려면 SSE - C 지! 위에 그림 참고

2. S3 저장된 데이터를 암호화하려 함. 키 저장 관리는 상관 없지만, 키 순환 정책은 관리하고 싶음 - SSE-KMS! (KMS 와 S3 의 차이 확실히..! S3 는 키 순환 정책도 못하는게 맞는지?)

3. AWS 를 신뢰하지 않아서 암호화 자체를 앱에서 하고 싶음 - 클라이언트 측! 

4. CORS 문제 인지 

5. HTTPS 가 필수인 암호화 방법은 SSE- C 이다

6. 실수 영구 삭제 방지 - MFA 삭제 활성화 (이중 보안) 

7. S3 버킷에 있는 모든 파일이 기본적으로 암호화 되었으면 좋겠다. 가장 좋은 방법은? - 그냥 기본 암호화 활성화 .. 이게 강의에 나왔나?

8. 일부 직원이 액세스 권한이 없는 S3 버킷의 파일에 액세스하려고 하는 것 같다. 누가 했는지 어떻게 확인할 수 있는가? > 로깅 ㅎ분석하면 됨. (정답은 로그 활성화 후 Athena 를 사용하여 분석하기 이다) 

9.  Pre Signed URL 을 알고 있는지

 

 

14강 종료

 

 

 

====================================================================================

 

 

교육 출처

 

- AWS Certified Developer Associate 시험 대비 강의 - Udemy

 

https://www.udemy.com/share/105Hxw3@z0Wqme5D9voly52i8MuQYl_c8462GP25Oul4H38G3nVfgD4fMrYPJE5LOB88iDuZ/

728x90