공부하기싫어
article thumbnail

#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 - 데이터 키의 캐시가 얼마나 커야 하는지 나타냄

 

대칭 키 api

 

 

 

397. 암호화 SDK CLI 실습

보기만 했다

 

https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/python.html

 

AWS Encryption SDK for Python - AWS Encryption SDK

AWS Encryption SDK for Python This topic explains how to install and use the AWS Encryption SDK for Python. For details about programming with the AWS Encryption SDK for Python, see the aws-encryption-sdk-python repository on GitHub. For API documentation,

docs.aws.amazon.com

 

 

 

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 유형으로 만들어준다고 한다

ssm

키 id 는 aws 에서 제공해주는 ssm 키로 설정했는데 CMK 를 사용할 수도 있다고 한다

 

securestring

세부정보로 들어가면 값이 암호화되어있지만

표시를 누르면 바로 해독해준다

 

같은 방식으로 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 로 파라미터들을 불러와서 출력하는 간단한 코드이다

 

이후 권한에 인라인 정책을 추가해줬다

system manager

getparameters 와 getparametersbypath 를 추가해줬다

arn 을 추가해서 my-app 안의 리소스에만 접근할 수 있도록 특정했

이름은 SSMAccessForMyApp 로 하고 생성

테스트 해보면

 

test log

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 - 실습

aws 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 의 암호를 참조하게끔 구성

 

codebuild - environment