#AWS Certified Developer Associate
392. AWS 보안 - 섹션소개
실제로 KMS 를 주로 사용할꺼고, 보안은 주로 DB password 같은 경우 secrets manager 를 사용하거나 SSM 파라미터 스토어를 이용할 것이기 때문에 보안쪽은 이론은 빠르게 넘어가고 실습은 SSM 파라미터 스토어와 Secrets Manager 를 주로 해볼 예정이다
393. 암호화 101
암호화 매커니즘의 개요
전송중 암호화 - Encryption in flight (SSL)
데이터는 전송 전에 암호화되고 서버에서는 수신 후에 암호화를 해독함
SSL 인증서로 암호화 - HTTPS 로 복호화
HTTPS 엔드포인트를 활성화하면 중간자 공격으로부터 안전할 수 있음
서버측 미사용 데이터 암호화
서버에서 데이터를 수신한 후에 암호화 하는 것
데이터는 클라이언트로 다시 전송되기 전에 암호화 됨
데이터 키를 통해 암호화 - 데이터는 암호화된 형식으로 저장
암호화 키와 해독 키는 key management service (KMS) 로 반드시 어디선가 관리해야 함
서버는 해당 KMS 와 통신하는 권한이 있어야 함
많은 AWS 서비스들이 서버측 미사용 데이터 암호화 방식을 사용하고 있음
클라이언트 측 암호화
클라이언트에 의해 암호화되므로 서버는 절대로 데이터를 해독할 수 없음
데이터는 서버에 저장되지만 해독은 클라이언트의 몫
봉투 암호화(Envelope Encryption) 사용
394. KMS 개요
보통 AWS 에서 암호화를 이야기 하면 KMS 를 뜻함
AWS 가 모든 암호 키를 관리해줌
KMS 는 IAM 과 완전히 통합되어 권한을 관리함
KMS - Customer Master Key (CMK) Types
대칭 키 (Symmetric) - AES-256 keys
- 데이터를 암호화하거나 해독할 때 단일 암호화 키를 사용할 때 제공됨
- AWS 서비스는 KMS 와 통합되면서 이 대칭 CMK 를 사용함
- 봉투 암호화에도 사용됨
- KMS 로 대칭키를 생성하려고 하면 암호화되지 않은 키에 액세스 할 수 없기 때문에 키를 사용하기 위해 KMS API 를 사용해야 함
비 대칭 키 (Asymmetric) - RSA & ECC key pairs
- 암호를 위한 퍼블릭 키 + 해독을 위한 개인 키 구조
- 공용키로 암호화를 하고 개인키로 해독을 함
- KMS 에서 서명/검증 작업에 사용되기도 함
- KMS API 를 호출할 수 없는 사용자가 AWS 외부에서 암호화 하는 경우 비대칭키를 생성해서 사용함
AWS KMS (Key Management Service)
키와 정책을 완전히 관리할 수 있음
- 키 생성, 교체 정책 정의, 활성화/비활성화
CloudTrail 통합을 통해 키 사용량 감사 가능
3가지 타입의 고객 마스터 키 (customer master key - cmk) :
- aws 가 관리하는 기본 고객 마스터키 - 무료
- 전용키 생성 - $1 / month
- 전용키를 kms 외부에서 생성(must be 256-bit symmetric key) 후 삽입 - $1 / month
KMS API 를 호출할 때마다 요금 부과
- 호출 1만회당 3센트 ($0.03)
AWS KMS 101
민감한 정보를 주고받을 때 KMS 사용
- db password
- credentails to external service
- private key of SSL certificates
KMS 장점
데이터를 암호화하거나 해독할 때 암호를 볼 수 없고 보안이 AWS 에 의해 관리된다는 점
KMS 는 추가 보안으로 키들을 교체할 수 있음
절대 db password 등의 중요한 정보들을 평문으로 저장하지 않는 것 - especially in your code
중요한 정보는 암호화한 상태로 코드나 환경변수에 저장해야함
호출 당 4KB 의 데이터만 암호화 가능
- 더 많은 양의 데이터를 암호화할땐 봉투 암호화(envelope encryption) 사용
KMS 접근 권한을 누군가에게 주려면 :
- 키 정책이 사용자를 키에 액세스하도록 허용하는지 확인해야 함
- IAM 정책도 API 호출을 허용 해야함
Copying Snapshots across regions
KMS 키는 특정 리전에 묶이게 됨
볼륨에 대한 스냅샷을 만듬
암호화된 볼륨에서 만들어진 스냅샷은 동일한 KMS 와 동일한 키로 암호화 됨
그 스냅샷을 새 리전에 복사할 때 데이터를 재 암호화할 새 KMS 키를 특정해야 함
스냅샷으로부터 볼륨을 재생성하면 볼륨은 새 KMS 키로 암호화 됨
KMS Key Policies
IAM 정책과 Key 정책
키 정책은 s3 버킷 정책과 비슷함
- 이들 없이는 액세스를 제어할 수 없음
- 키 정책을 지정하지 않으면 키에 액세스 불가
Default KMS Key Policy :
- 기본이기 때문에 정책이 관대함
- kms 키 정책을 지정하지 않으면 제공되어 루트 사용자에게 접근 권한을 부여함
- AWS 계정이 IAM 정책이 가능할 때에만 KMS 키를 사용할 수 있음
- IAM 정책을 만들어서 사용자와 연결해 KMS key 로의 액세스 허용
Custom KMS Key Policy :
- 사용자와 역할을 지정해서 이 KMS 키에 액세스 할 수 있게 함
- 키를 관리하는 사람 정의
- KMS 키의 계정 간 액세스를 해두면 편리하다고 함
(3.10 끝)
(3.11 시작)
395. CLI 를 통한 KMS 실습
AWS 관리형 키
- 무료
- 접근 불가 / 간단한 정보만 얻을 수 있음
고객 관리형 키 에서 전용 키를 생성할 수 있다
생성할 경우 한달에 1달러의 사용료
고객 관리형 키 구성
이후 별칭 생생 (레이블 추가)
단계 3 키관리 권한 정의
아무것도 설정하지 않으면 기본 키 정책을 따르게 됨
단계 4 키 사용 권한 정의
키를 사용할 수 있는 사용자 혹은 역할을 정의하는 단계
이후 키를 생성하지는 않음
주로 AWS 관리형 키를 사용하기 때문에 이후 실습은 그냥 보기만 함
kms-demo-sli.sh
# 1) encryption
aws kms encrypt --key-id alias/tutorial --plaintext fileb://ExampleSecretFile.txt --output text --query CiphertextBlob --region eu-west-2 > ExampleSecretFileEncrypted.base64
# base64 decode for Linux or Mac OS
cat ExampleSecretFileEncrypted.base64 | base64 --decode > ExampleSecretFileEncrypted
# base64 decode for Windows
certutil -decode .\ExampleSecretFileEncrypted.base64 .\ExampleSecretFileEncrypted
# 2) decryption
aws kms decrypt --ciphertext-blob fileb://ExampleSecretFileEncrypted --output text --query Plaintext > ExampleFileDecrypted.base64 --region eu-west-2
# base64 decode for Linux or Mac OS
cat ExampleFileDecrypted.base64 | base64 --decode > ExampleFileDecrypted.txt
# base64 decode for Windows
certutil -decode .\ExampleFileDecrypted.base64 .\ExampleFileDecrypted.txt
예시로 KMS 호출을 암호화하고 해독하는 법을 실습한다고 함
396. KMS 암호화 패턴 및 봉투 암호화
KMS 가 어떻게 API 를 암호화, 해독하는지 / 봉투 암호화에서는 어떻게 작동하는지
암호화할 파일이 4KB 이하일때
암호화할 파일이 4KB 이상일때 - 봉투 암호화
- 4KB 가 넘어가는 데이터는 봉투 암호화 기술을 사용해 암호화 되어야 함 = GenerateDataKey API
10MB 크기의 파일을 암호화 한다고 할 때
1. SDK 로 GenerateDataKey API 를 호출 , CMK 를 특정함
2. KMS 는 다시 IAM 에 권한을 확인함
3. 권한이 확인되면 KMS 가 데이터 키를 작동시킴, 평문으로 다시 보내줌
4. 평문의 데이터 키 암호화를 가지게 되고 데이터 암호화 키는 DEK 라고 함
5. 클라이언트 측에서 CPU 와 DEK 로 큰 파일을 암호화 할 수 있게 됨
6. 이후 봉투를 만들어 암호화한 파일과 암호화된 형태의 DEK 를 넣음
봉투 암호화로 암호화된 큰 파일을 해독할 때
1. KMS 에 해독 API 를 호출, DEK 를 해독함
2. KMS 는 다시 IAM 에 권한을 확인함
3. 권한이 확인되면 KMS 는 DEK 를 평문 DEK로 해독해줌
4. 평문 DEK 를 통해 암호화된 파일과 평문 DEK 를 볼 수 있음
봉투 암호화 기술의 목적은 KMS 를 원래 장점 대로 키를 생성하는데 쓰고, 암호화나 해독은 클라이언트 측에서 하는 데에 있음
Encryption SDK
aws encryption sdk 에 봉투 암호화 기능이 있음
CLI 툴로도 설치할 수 있음
java, python, c, javascript 로 구현되어있음
Data Key Caching :
- 데이터 키를 매번 오브젝트를 암호화할 때마다 다시 생성하는게 아니라 재사용하는 것
- KMS 에 호출을 적게 한다는 뜻
- 비용 절감 효과 - 같은 데이터 키로 암호화를 하기 때문에 많은 파일에 같은 키가 적용되는 보안상 단점
- LocalCryptoMasterialsCache - 데이터 키의 캐시가 얼마나 커야 하는지 나타냄
397. 암호화 SDK CLI 실습
보기만 했다
https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/python.html
398. KMS 한도
KMS 는 AWS 서비스이기 때문에 요청 할당량이 정해져 있다고 함
암호화나 해독에 있어 KMS 의 요청 할당량을 초과하게 될 때 - ThrottlingException
예외에 대처하는 방법 :
- 지수 백오프 전략(exponential backoff) 사용 - 백오프해서 재시도하는 방법 - 호출 사이의 지수 시간을 이용
각 암호화 작업마다 할당량을 공유함
- 요청을 보내는 모든 서비스들이 할당량에 해당됨
- 암호화 작업에 대해서 계정간, 리전간 할당량을 공유함
키를 너무 자주 사용하면 ThrottlingException 이 나올 수 있음
GenerateDataKey API 를 사용하고 있다면 DEK caching 사용
- 데이터 암호화 키를 로컬에 캐시해서 aws 로 가는 api 호출의 수를 줄이는 방식
제한 할당량 증가 요청
- 제한을 여러번 초과할 경우 대비
- api 호출이나 aws 고객센터 문의를 통해 가능
모든 작업들이 암호화 작업으로 전부 할당량을 공유함
399. KMS 및 AWS Lambda 실습
이 실습은 해봤다
먼저 람다 함수를 새로 만든다고 함
이름은 lambda-kms, 런타임으로 파이썬 최신, 생성
람다 내에서 환경변수를 암호화한다고 함
여기에는 이전에 생성했던 CMK 를 사용한다고 하는데 나는 CMK 를 생성하지 않았으니 그 직전까지만 실습해보려고 한다
lambda 함수를 사용할 때 코드에 password 를 직접 기입하는것은 최악의 방법이다
환경변수로 password 를 등록하는게 차선인데
최선의 방법은 환경변수를 암호화 하는것이다.
aws management key 를 사용하거나 CMK 를 사용할 수 있는것 같은데
강의 실습에서는 CMK 를 사용했다
환경변수 옆의 암호화를 눌러서 위 화면을 띄우고
KMS 키를 선택하면 암호화가 된다
그러면 아래 '보안 암호 코드 조각 해독'(decrpt secrets snippet) 이라는 탭을 열면 복호화 코드를 확인할 수 있는데
이 코드를 복사해서 붙여넣으면 암호화된 환경변수를 람다로 불러내서 해독한 후 사용할 수 있게 된다.
람다함수는 KMS 환경변수에 해독 호출을 실행하는데 이에 대해서 권한을 부여할 IAM 역할을 생성하지 않으면 AccessDeniedException 이 발생한다
- 람다함수 구성 - 권한 - 실행 역할 - 인라인 정책 추가
이후 리소스 탭을 열어 key 리소스 arn 을 지정해 주는게 모범 사례이다
400. S3 보안 고급
Amazon S3 에서 객체를 암호화하는 4가지 방법
- SSE-S3
- SSE-KMS
- SSE-C
- Client Side Encryption
SSE-KMS
S3 내에서 서버측 암호화 가능, 암호화 키는 KMS 가 관리함
키 정책과 IAM 을 통해 누가 키를 사용할 수 있는지에 대한 제어 가능, CloudTrail 에 감사 기록 가능
객체는 서버 측에서 암호화
s3로 HTTPS 요청을 보낼때 "x-amz-server-side-encrptption":"aws:kms" 헤더 포함 필요
4KB 이상의 파일 암호화 시 SSE-KMS 방식 사용시 내부적으로 GenerateDataKey 와 Decrypt API 를 호출함
이 2개의 KMS API 는 CloudTrail 에서 찾아볼 수 있다
- 해당 키를 사용할 권한을 부여하는 KMS 키 정책 필요
- KMS 로의 액세스를 승인하는 IAM 정책이 필요
매번 S3 버킷에 객체 업로드 시 객체를 암호화 혹은 해독하려 할때마다 KMS 제한이 하나씩 소모됨
- SSE-KMS 사용시 수만개의 객체를 업로드 한다면 빠른시간 내에 KMS 제한에 도달하게 됨
- 스로틀링이 일어나면 지수 백오프를 사용 가능
- KMS 제한 증가 요청 가능
S3 Bucket Policies - Force SSL
버킷 보안
S3 버킷으로 SSL 연결을 강제하는 정책
- aws:SecureTransport==false 라는 거부 조건 사용
- aws:SecureTransport==true 라는 허용 조건 사용 - 익명의 GetObject SSL 요청도 허용할 수 있음
Force Encryption of SSE-KMS
버킷 정책으로 SSE-KMS 가 암호화하도록 강제
올바르지 않은 암호화 헤더는 모두 거부
암호화 헤더가 없는 경우 거부
암호화되지 않은 객체를 SSE-KMS 기본 암호화가 되도록 설정할 수 있음
401. S3 버킷 키
신규 기능
S3 Bucket key for SSE-KMS encryption
SSE-KMS 유형 암호화를 사용해 amazon S3 로 부터 KMS 로 보내지는 API 호출의 양을 99% 감소시킬 수 있음
데이터 키와 S3 버킷 키 사용
고객 마스터 키와 KMS 가 Amazon S3 버킷을 위한 데이터 키를 생성하는데 사용됨 - S3 버킷 키
KMS 암호화를 통해 Amazon S3 버킷 내의 객체를 암호화하는데 이 키가 사용됨
이 s3 버킷 키는 봉투 암호화를 이용해 많은 수의 데이터 키를 생성하게 됨
그리고 이 데이터 키가 s3 버킷 내에서 암호화를 하게 됨
즉 직접 KMS 로 API 를 호출하지 않고 생성된 s3 버킷키로 인해 생성된 데이터키로 암호화하기 때문에 KMS API 호출을 줄일 수 있음
402. SSM 파라미터 스토어 개요
aws 의 설정과 기밀 사항을 저장할 수 있는 안전한 저장소
KMS 를 이용해 선택적으로 암호화 가능
서버리스, 스케일링 가능, 좋은 내구성, 쉬운 SDK 사용
설정과 기밀 사항의 버저닝 가능
설정 관리의 모든 보안은 경로와 IAM 정책을 통해 이루어짐
CloudWatch Events 로 알림 받기 가능
cloudformation 과 통합 가능
파일시스템 폴더 구조와 비슷한 체계를 가짐
Secrets Manager 로부터 암호를 참조할 수 있음
aws 로부터 직접 파라미터를 참조할 수 있음
SSM 파라미터 스토어 tiers
파라미터 정책 (advanced)
파라미터에 TTL 적용 - 효과적으로 유효 기간을 생성
파라미터 스토어 내의 민감한 데이터인 비밀번호 등을 업데이트하거나 삭제하도록 강제해줌
403. SSM 파라미터 스토어 실습 (CLI)
표준과 고급 유형을 선택할 수 있고
값 유형도 문자열, 문자열 list, 보안 문자열을 선택할 수 있다
값은 임의로 넣어줬다
생성된 파라미터를 보면 버전과 마지막 수정한 사용자를 확인할 수 있어서 추적에 용이하다
history 와 tag 도 확인할 수 있다
password 파라미터를 새로 만드는데 SecureString 유형으로 만들어준다고 한다
키 id 는 aws 에서 제공해주는 ssm 키로 설정했는데 CMK 를 사용할 수도 있다고 한다
세부정보로 들어가면 값이 암호화되어있지만
표시를 누르면 바로 해독해준다
같은 방식으로 prod 안의 db-url 과 db-password 파라미터를 만들어줬다
이제 파라미터에 액세스 하기 위해 CLI 를 사용한다고 한다
[cloudshell-user@ip-10-4-77-163 ~]$ aws ssm get-parameters --names /my-app/dev/db-url /my-app/dev/db-password
{
"Parameters": [
{
"Name": "/my-app/dev/db-password",
"Type": "SecureString",
"Value": "AQICAHhAHLa3sxsfNFbdshFcEOv5LAuTDKyIRfonfLcI8MefSAGqiKjh9S/2mCPPYirM7k0HAAAAbzBtBgkqhkiG9w0BBwagYDBeAgEAMFkGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM/jVtDLdmekpilk8NAgEQgCzdBsyJiAosqUpcY3g0zWPnZSfPWvlV192KYFgqBzUbFsU/tOsVBLqUb3Q2Nw==",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:10:42.326000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/dev/db-password",
"DataType": "text"
},
{
"Name": "/my-app/dev/db-url",
"Type": "String",
"Value": "dev.yeonwoo.database.com",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:07:28.138000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/dev/db-url",
"DataType": "text"
}
],
"InvalidParameters": []
}
[cloudshell-user@ip-10-4-77-163 ~]$
aws ssm 의 get-parameters 옵션을 써서 파라미터를 불러왔다
db-url 은 암호화되지 않았기때문에 값을 바로 확인할 수 있다
db-password 는 securestring 유형이기때문에 값이 암호화되어 출력된다
해독을 위해서는 명령문에 --with-decryption 을 추가해준다
[cloudshell-user@ip-10-4-77-163 ~]$ aws ssm get-parameters --names /my-app/dev/db-url /my-app/dev/db-password --with-decryption
{
"Parameters": [
{
"Name": "/my-app/dev/db-password",
"Type": "SecureString",
"Value": "myprivatepassword",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:10:42.326000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/dev/db-password",
"DataType": "text"
},
{
"Name": "/my-app/dev/db-url",
"Type": "String",
"Value": "dev.yeonwoo.database.com",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:07:28.138000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/dev/db-url",
"DataType": "text"
}
],
"InvalidParameters": []
}
[cloudshell-user@ip-10-4-77-163 ~]$
get-parameters-by-path 로 경로 내의 모든 파라미터를 불러올 수도 있다
[cloudshell-user@ip-10-4-77-163 ~]$ aws ssm get-parameters-by-path --path /my-app/prod/
{
"Parameters": [
{
"Name": "/my-app/prod/db-password",
"Type": "SecureString",
"Value": "AQICAHhAHLa3sxsfNFbdshFcEOv5LAuTDKyIRfonfLcI8MefSAEZ5hWI/RakpTWFg0P3EshgAAAAbDBqBgkqhkiG9w0BBwagXTBbAgEAMFYGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMg04+3vqQCwUB8stOAgEQgCkwDwLKbmKl3lGJIR5rom7peggXsEG6uqaThIkc0I3TRfPqUb/1a7F4sA==",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:14:25.784000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/prod/db-password",
"DataType": "text"
},
{
"Name": "/my-app/prod/db-url",
"Type": "String",
"Value": "prod.yeonwoo.database.com:3306",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:13:58.582000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/prod/db-url",
"DataType": "text"
}
]
}
[cloudshell-user@ip-10-4-77-163 ~]$
만약 상위 디렉토리에서 하위 디렉토리 내 파라미터까지 전부 불러오려면 재귀적으로 호출해줘야 한다
[cloudshell-user@ip-10-4-77-163 ~]$ aws ssm get-parameters-by-path --path /my-app/ --recursive
{
"Parameters": [
{
"Name": "/my-app/dev/db-password",
"Type": "SecureString",
"Value": "AQICAHhAHLa3sxsfNFbdshFcEOv5LAuTDKyIRfonfLcI8MefSAGqiKjh9S/2mCPPYirM7k0HAAAAbzBtBgkqhkiG9w0BBwagYDBeAgEAMFkGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM/jVtDLdmekpilk8NAgEQgCzdBsyJiAosqUpcY3g0zWPnZSfPWvlV192KYFgqBzUbFsU/tOsVBLqUb3Q2Nw==",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:10:42.326000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/dev/db-password",
"DataType": "text"
},
{
"Name": "/my-app/dev/db-url",
"Type": "String",
"Value": "dev.yeonwoo.database.com",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:07:28.138000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/dev/db-url",
"DataType": "text"
},
{
"Name": "/my-app/prod/db-password",
"Type": "SecureString",
"Value": "AQICAHhAHLa3sxsfNFbdshFcEOv5LAuTDKyIRfonfLcI8MefSAEZ5hWI/RakpTWFg0P3EshgAAAAbDBqBgkqhkiG9w0BBwagXTBbAgEAMFYGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMg04+3vqQCwUB8stOAgEQgCkwDwLKbmKl3lGJIR5rom7peggXsEG6uqaThIkc0I3TRfPqUb/1a7F4sA==",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:14:25.784000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/prod/db-password",
"DataType": "text"
},
{
"Name": "/my-app/prod/db-url",
"Type": "String",
"Value": "prod.yeonwoo.database.com:3306",
"Version": 1,
"LastModifiedDate": "2023-03-11T17:13:58.582000+00:00",
"ARN": "arn:aws:ssm:ap-northeast-1:662307199274:parameter/my-app/prod/db-url",
"DataType": "text"
}
]
}
[cloudshell-user@ip-10-4-77-163 ~]$
그러면 상위 디렉토리 내 모든 파라미터를 가져올 수 있다
파라미터들을 구조화할 수 있고 한꺼번에 불러올 수 있어 간편하다
404. SSM 파라미터 스토어 실습 (AWS Lambda)
함수를 새로 생성했다
이름은 hello-world-SSM, 런타임은 파이썬 최신
이후 ssm 파라미터 스토어에 접근해 읽기/쓰기를 하기 위해 권한을 줄것이라고 한다
함수 코드를 수정했다
import json
import boto3
ssm=boto.client('ssm', region_name='ap-northeast-1')
def lambda_handler(event, context):
db_url = ssm.get_parameters(Names=['/my-app/dev/db-url'])
db_password = ssm.get_parameters(Names=['/my-app/dev/db-password'])
print(db_url)
print(db_password)
return "worked!"
aws sdk 를 위해 boto 를 import 해주고 ssm api 로 파라미터들을 불러와서 출력하는 간단한 코드이다
이후 권한에 인라인 정책을 추가해줬다
getparameters 와 getparametersbypath 를 추가해줬다
arn 을 추가해서 my-app 안의 리소스에만 접근할 수 있도록 특정했
이름은 SSMAccessForMyApp 로 하고 생성
테스트 해보면
url 은 값이 잘 나오고 비밀번호는 암호화된 채 출력되는 것을 확인할 수 있다
해독을 위해 코드에 구문을 추가해본다고 한다
import json
import boto3
ssm=boto3.client('ssm', region_name='ap-northeast-1')
def lambda_handler(event, context):
db_url = ssm.get_parameters(Names=['/my-app/dev/db-url'])
db_password = ssm.get_parameters(Names=['/my-app/dev/db-password'], WithDecryption=True)
print(db_url)
print(db_password)
return "worked!"
WithDecryption=True 를 추가해주고 테스트해보면
이렇게 password 가 해독되서 출력되는것을 확인할 수 있다
파라미터를 암호화할 때 사용한 키가 aws 관리 키 이기 때문에 바로 접근에 성공했다
aws 계정 및 리전의 모든 사용자는 aws 관리 키로 암호화된 파라미터에 액세스 할 수 있기 때문이다
파라미터에 대한 액세스를 제한하려면 CMK 를 사용해야 한다고 한다
그리고 당연히 해당 람다 함수에 kms 접근 권한을 부여해야 암호를 해독할 수 있을 것이다.
환경변수를 활용해서 ssm 파라미터를 이용할 수 있다
import json
import boto3
import os
ssm=boto3.client('ssm', region_name='ap-northeast-1')
dev_or_prod = os.environ['DEV_OR_PROD']
def lambda_handler(event, context):
db_url = ssm.get_parameters(Names=['/my-app/'+dev_or_prod+'/db-url'])
db_password = ssm.get_parameters(Names=['/my-app/'+dev_or_prod+'/db-password'], WithDecryption=True)
print(db_url)
print(db_password)
return "worked!"
환경변수로 경로를 받아서 파라미터를 가져올 수 있었다
405. Secrets Manager - 개요
최신 서비스
Secrets Manager 는 암호 위주의 서비스이며 매 X일 마다 암호가 순환하도록 강제할 수 있음
순환시에 암호의 생성을 자동화 할 수 있음 - lambda 사용
Secrets manager 와 db(amazon rds) 사이에서 암호를 동기화 할 수도 있음
암호는 당연히 암호화되며 암호화에는 KMS 의 사용이 가능함
406. Secrets Manager - 실습
비용은 메인 화면에 나와있듯 암호당 월 $0.4
api 호출 1만건당 $0.05 이다
암호를 안전하게 교체할 수 있고
세분화된 권한(IAM) 으로 액세스 관리 가능
중앙에서 보안암호를 보호하고 감사 시행
사용량에 따라 지불
AWS 의 다른 서비스들과의 통합으로 옵션이 점점 늘어날 것이라고 함
다른 유형의 보안 암호 옵션은 키-값 pair 로 지정할 수 있는데 행을 추가해서 여러 쌍을 등록할 수도 있다
- 파라미터 스토어와의 차이점
자동 교체 구성을 활성화하면 람다함수와 연결해서 정해진 시간 단위에 람다함수를 통해 암호를 교체할 수 있다
생성 검토시에 마지막에 코드 샘플을 안내해준다
# Use this code snippet in your app.
# If you need more information about configurations
# or implementing the sample code, visit the AWS docs:
# https://aws.amazon.com/developer/language/python/
import boto3
from botocore.exceptions import ClientError
def get_secret():
secret_name = "prod/my-secret-api"
region_name = "ap-northeast-1"
# Create a Secrets Manager client
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name=region_name
)
try:
get_secret_value_response = client.get_secret_value(
SecretId=secret_name
)
except ClientError as e:
# For a list of exceptions thrown, see
# https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
raise e
# Decrypts secret using the associated KMS key.
secret = get_secret_value_response['SecretString']
# Your code goes here.
407. SSM 파라미터 스토어 vs Secrets Manager
ssm 파라미터 스토어와 secrets manager 차이점
Secrets Manager :
더 비쌈
람다함수를 이용해서 암호의 순환을 자동화 할 수 있음
일부 람다 함수는 예를들어 RDS, 레드시프트, DocumentDB 와 통합 기능을 제공함
KMS 암호화가 필수
CloudFormation 과 통합 가능
SSM Parameter Store :
저렴함
다용도로 사용 가능
단순 api
암호의 순환은 없음, CloudWatch 이벤트에 의해 트리거되는 람다 함수를 이용해 순환 가능
KMS 암호화는 선택사항
CloudFormation 통합 가능
SSM 파라미터 스토어 API 를 사용해 Screts Manager 의 암호를 풀링할 수 있음
408. CloudWatch 로그 암호화
KMS 키를 사용해 CloudWatch 로그를 암호화 할 수 있음
암호화는 로그스트림이 아닌 로그 그룹 레벨에서 이루어짐
- CMK 를 기존의 로그 그룹과 연결할 수 있음
- CMK 로 새 로그 그룹을 생성할 수 있음
CloudWatch 콘솔을 사용해서는 CMK 를 로그 그룹과 연결할 수는 없음
- CLI 와 SDK 를 위해서는 CloudWatch 로그 API 를 사용해야 함
- associate-kms-key : kms 키를 기존의 로그 그룹과 연결하는 명령
- create-log-group : 아직 존재하지 않는 로그 그룹을 생성해 KMS 키와 바로 연결할 수 있음
키 정책에 로그 그룹을 허용하는 정책을 추가해줘야 한다
실습은 따로 안하고 보기만 함
409. CodeBuild 보안
CodeBuild 는 VPC 밖에 있지만 VPC 리소스로의 액세스를 위해 내부에서 실행할 수 있다
암호를 CodeBuild 환경변수 내에서 평문으로 저장 x
- 환경변수가 파라미터 스토어의 파라미터를 참조하게끔 구성
- 환경 변수가 Secrets Manager 의 암호를 참조하게끔 구성
'AWS > AWS Certified Developer Associate' 카테고리의 다른 글
[Udemy][day-64] Section31 : AWS : 최종 정리 (0) | 2023.03.12 |
---|---|
[Udemy][day-64] Section30 : 기타 서비스 (0) | 2023.03.12 |
[Udemy][day-61] Section28 : 고급 자격 증명 (0) | 2023.03.07 |
[Udemy][day-60,61] Section27 : 기타 서버리스 : Step Functions 및 AppSync (0) | 2023.03.05 |
[Udemy][day-59,60] Section26 : Cognito (0) | 2023.03.02 |