네 가지 방법을 이용해서 S3 버킷의 객체를 암호화 한다.
- SSE-S3
Amazon S3에서 관리하는 키를 이용한 서버측 암호화. 사용자는 키에 접근할 수 없다.
만들어진 버킷과 객체에 대해 기본값으로 활성화되어 있다. 사용자가 데이터를 업로드하면 S3에서 소유한 키로 객체를 혼합해서 암호화를 한 다음 버킷에 저장된다.
암호화의 보안 유형은 AES-256이다. 이를 위해 헤더에 "x-amz-server-side-encryption":"AES256" 이라고 설정해야 한다.
- SSE KMS
AWS KMS(Key Management Service) 키를 이용해 암호화 키를 관리한다.
KMS를 사용할 경우 사용자가 키를 통제할 수 있다는 장점이 있다.
KMS에서 직접 키를 생성할 수 있고 CloudTrail을 이용해서 키 사용을 검사할 수 있다.
누군가 KMS에서 키를 사용할 때마다 AWS 안에서 일어나는 모든 것을 로깅하는 서비스인 CloudTrail에 로깅될 것이다.
헤더에 "x-amz-server-side-encryption":"aws:kms" 라고 설정해야 한다.
버킷에서 해당 파일을 읽으려면 객체 자체에 엑세스+ KMS 키 엑세스 두 가지가 이뤄져야 한다.
KMS키에는 GenerateDataKey같은 자체 API가 있고, 우리는 DecryptAPI를 사용해서 복호화한다. API 호출을 하게 되면 그 API호출 건은 모두 KMS의 초당 API 호출 쿼터에 합산된다.
리전에 따라 초당 5,000내지 30,000 건의 요청이 가능하다.
만약 S3 버킷의 처리량이 아주 많고 모든 게 KMS키로 암호화되어 있다면 그건 일종의 스로틀링(처리량 제한) 활용사례가 될 수 있다.
기본 aws/s3키를 선택하면 비용이 발생하지 않지만 직접 KMS키를 생성하면 비용발생
요금 참고 :https://aws.amazon.com/ko/kms/pricing/?utm_source=chatgpt.com
- SSE-C
고객이 제공한 키를 사용한다. 키가 AWS 외부에서 관리되지만 키를 AWS로 전송하고(HTTPS 사용) S3는 암호화 키를 저장하지 않고 사용 후에는 폐기한다.
사용자는 파일과 키를 업로드할 건데 사용자가 AWS외부에서 그 키를 관리한다.
S3는 클라이언트가 제공한 키와 객체를 사용해 암호화를 수행하고 암호화된 파일을 S3버킷에 넣는다.
파일을 읽으려면 암호화에 사용한 키가 있어야 한다.
SSE-C를 적용하려면 콘솔이 아닌 CLI에서 다뤄야 한다.
- DSSE-KMS
KMS를 기반으로 한 이중 암호화
클라이언트 측의 모든 걸 암호화한 다음에 S3에 업로드한다.
클라이언트 라이브러리를 활용하면 더 쉽게 구현할 수 있다.
복호화도 S3 외부의 클라이언터측에서 이뤄진다.
클라이언트가 키와 암호화 사이클을 완전하게 관리하는 것이다.
서버측 암호화를 편집하면 업데이트된 세팅으로 새로운 버전의 객체가 생성된다.
여기서 SSE-S3가 아닌 SSE-KMS 혹은 DSSE-KMS 중에 선택할 수 있다.
버킷을 선택 > Properties > Default encryption > edit으로 기본 암호화 방식을 변경할 수 있다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/*",
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
이런 버킷정책 구문을 적용하면 HTTPS를 사용할 경우 SecureTransport는 true이고 암호화 연결을 사용하고 있지 않다면 false라서 HTTPS를 사용하지 않는 경우 오브젝트 열람이 거절된다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::your-bucket-name/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
}
]
}
이 버킷 정책은 kms 헤더가 없으면 PutObject를 거절한다.
버킷 정책은 항상 기본값 암호화 설정 이전에 평가된다. (우선순위가 더 높다)
버킷정책을 기본값 암호화 이전에 선제적으로 적용해 암호화를 강제할 수 있다.
오리진은 체계(프로토콜)와 호스트(도메인)와 포트로 구성된다.
CORS는 웹 브라우저 기반 보안 메커니즘으로 메인 오리진을 방문하는 동안 다른 오리진에 대한 요청을 허용하거나 거부한다.
예 : https://www.example.com
HTTPS의 포트는 443이다. 프로토콜은 HTTPS자체이고 도메인은 WWW.example.com이다.
👉🏻 오리진이 같다는 것은?
체계, 호스트, 포트가 동일할 때!
예시 : https://example.com/app1 , https://example.com/app2
👉🏻 오리진이 다른 예시 : www.example.com , other.example.com
다른 오리진의 웹사이트에 요청을 보낼 때 다른 오리진이 CORS 헤더를 사용해서 요청을 허용하지 않는 한 해당 요청은 이행되지 않는다.
이를 액세스 제어 허용 오리진 헤더(Access-Control-Allow-Origin)라고 한다.
클라이언트가 S3 버킷에서 교차 오리진 요청을 하면 정확한 CORS 헤더를 활성화해야 한다.
이 작업을 빠르게 수행하려면 특정 오리진을 허용하거나 *로 모든 오리진을 허용한다.
만약 정적 웹사이트 호스팅이 활성화된 bucket-web1이 index.html을 클라이언트의 요청에 반환할 때, 사이트에 필요한 이미지가 또다른 웹사이트 호스팅이 활성화된 bucket-web2에서 불러온다면?
bucket-web2에서 CORS요청의 오리진(bucket-web1)을 확인하고, Access-Control-Allow-Origin에서 bucket-web1을 허용하지 않았다면 요청을 거부한다.
요청을 허용한 경우라면 정확한 헤더를 갖고 요청이 처리되어 이미지를 얻을 수 있다.
정적 웹 호스팅 버킷 두개가 있다.
버킷1에서 버킷2의 html파일을 불러와서 innerhtml로 띄울 것이다.
JSON형식으로 정의
아래는 예시
{
"CORSRules": [
{
"AllowedOrigins": ["Authorization"],
"AllowedMethods": ["GET", "POST", "PUT"],
"AllowedHeaders": ["*"],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
}
MFA는 객체 버전을 영구적으로 삭제할 때 필요하다.
영구 삭제에 대한 보호 설정이다.
버킷에서 버전 관리를 중단할 때도 필요하다.
루트 계정만이 MFA Delete를 활성화/비활성화할 수 있다.

루트계정의 MFA를 설정하고 액세스키를 생성해 터미널에서 CLI로 아래 명령어를 입력한다.
프로필을 먼저 생성한다.
aws configure --profile <프로필 이름>
그 다음 엑세스 키ID와 엑세스 키를 입력하고 기본 리전 이름을 입력한다.
아래 내용을 입력해 정상적으로 버킷리스트가 뜨는지 확인한다.
asw s3 ls --profile <프로필 이름>
아래 내용을 입력해 MFA Delete를 활성화한다.
aws s3api put-bucket-versioning \
--bucket <버킷이름> \
--versioning-configuration Status=Enabled,MFADelete=Enabled \
--mfa "<MFA장치의 ARN> <MFA코드>" --profile <프로필 이름>
이렇게 하면 영구 삭제를 하기 위해서는 CLI 명령을 사용하거나 MFA삭제를 비활성화해야 한다.
비활성화 명령어는 위에서 MFADelete=Disabled로 수정하기 다시 받은 MFA코드를 입력하는 것만 수정하면 된다.
aws s3api put-bucket-versioning \
--bucket <버킷이름> \
--versioning-configuration Status=Enabled,MFADelete=Disabled \
--mfa "<MFA장치의 ARN> <MFA코드>" --profile <프로필 이름>
엑세스 로그를 활성화하면 버킷 정책이 수정된다.
로깅 버킷이 현재 버킷에 객체 업로드가 가능하게 바뀐다.
🚗사용사례
프라이빗 S3 버킷이 있다.
AWS 외부의 사용자에게 한 파일에 대한 엑세스 권한을 부여하고 싶다.
하지만 퍼블릭 파일로 설정하고 싶지 않다.
이럴 때 해당 파일을 가지고 미리 서명된 URL을 생성한다.
URL이 자격 증명을 이어받아 해당 파일에 액세스 할 수 있는 권한을 부여한다.
퍼블릭이 아닌 버킷에 있는 객체를 URL을 통해 열지말고 그냥 OPEN을 누르면 그게 미리 서명된 URL이다.
버킷과 객체가 프라이빗이라도 만료될 때까지 누구나 URL로 액세스 할 수 있다.
허용되는 시간을 정해주고 Create prsigned URL을 클릭하면 된다.
🔒 2가지 보존모드(Retention mode)
1) 규정 준수 모드(Compliance):
S3 Glacier 볼트 잠금과 비슷하게 누구도 객체 버전을 덮어쓰거나 삭제하거나 객체 변경을 할 수 없다.
보존 모드 자체 변경도 불가하고 보존 기간 단축도 하지 못함.
규정 준수를 엄격히 적용할 때 사용한다.
2) 거버넌스 보존 모드:
대부분의 사용자는 객체 버전 덮어쓰기, 삭제, 로그설정을 변경할 수 없음.
관리자나 일부 사용자는 IAM을 통해 부여받은 특별 권한으로 보존 기간을 변경하거나 객체를 바로 삭제할 수 있다. 규정 준수 모드 보다 유연함.
두가지 보존 모드 모두 보존 기간을 설정해서 그 기간 동안 객체를 보호할 수 있고 원하는 만큼 기간을 연장할 수 있다.
객체에 '법적 보존' 상태를 설정하면 S3 버킷 내 모든 객체를 무기한으로 보호한다. 보존 기간과는 무관하기 때문에 아주 중요한 (재판에서 사용될 수 있는) 객체에 법적 보존을 설정한다.
s3:PutObjectLegalHold IAM 권한을 가진 사용자는 어떤 객체에든 법적 보존을 설정하거나 제거할 수 있다.