보안 & 암호화 - SSM 매개변수 저장소

이기태·2024년 8월 16일
0

AWS

목록 보기
53/62

SSM Parameter Store

  • 구성과 암호를 위한 보안 스토리지
    중앙 집중화
  • KMS 서비스를 이용해 구성을 암호화할지 선택 가능
  • 서버리스이며 확장성과 내구성, SDK 사용에 용이하다.
  • 매개변수를 업데이트할 때 구성과 암호의 버전을 추적 가능
  • IAM을 통해 보안이 제공
  • 특정한 경우 Amazon EventBridge로 알림을 받을 수 있다.
  • CloudFormation과 통합 가능
    CloudFormation이 Parameter Store의 매개변수를 스택의 입력 매개변수로 활용 할 수 있다는 뜻

    - 애플리케이션과 SSM이 있을 때 평문 구성을 저장할 때
    - EC2 인스턴스 역할 같은 애플리케이션 IAM 권한이 확인될 것이다.
    아니면 암호화된 구성이 있다 해보면
    - SSM가 KMS로 구성을 암호화한다.
    - KMS 서비스가 암호화/복호화에 사용된다는 뜻이다.
    * 암호화/복호화를 수행하려면 애플리케이션이 기본 KMS 키에 액세스 할 수 있어야한다.

SSM Parameter Store 계층

  • 계층 구조가 있는 Parameter Store에 매개변수를 저장할 수 있다.
    • '/my-department/'를 경로로 정의하면 하위에
      • my-app/
        • dev/
          • db-url
          • db-password
        • prod/
          • db-url
          • db-password
      • other-app/
    • /other-department/
  • 이런 식으로 원하는 방식으로 매개변수를 구조화할 수 있다.

    - 만약 Dev Lambda 함수라는 애플리케이션을 사용한다면 'my-app/' 내 'dev/'의 'db-url'과'db-password'에 액세스를 허용하는 IAM 역할을 할 것이다.
    - 여러 IAM 정책과 일부 환경변수 때문에 Prod Lambda 함수를 사용한다면 다른 경로에 있는 'prod/'의 'db-url'과'db-password'에도 액세스할 수 있다.
  • 구조화를 통해 IAM 정책을 간소화해 애플리케이션이 '/my-department/' 혹은 'my-app/' 전체 경로에 또는 'my-app/', '/my-department/' 환경의 특정 경로에만 액세스할 수 있도록 한다.
  • 또한 화면에 보이는 레퍼런스를 사용해 Parameter Store로 Secrets Manater의 암호에 액세스할 수도 있다.
    ex: /aws/reference/secretsmanager/secret_ID_in_Secrets_Manager
  • AWS에서 발행하는 퍼블릭 매개변수도 사용할 수 있다.
    예를 들어 특정 리전에서 Linux 2의 최신 AMI를 찾으려 할 때 Parameter Store에서 API 호출을 대신해 쓸 수 있다.
    ex: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2(public)

표준 및 고급 매개변수 계층

  • Systems Manager 두 가지 매개변수 티어
  • 주요 차이점
    • 용량
      표준: 4KB
      고급: 8KB
    • 매개변수 정책 적용 여부
      표준: X
      고급: O
    • 비용
      표준: FREE
      고급: 월 0.05$

매개변수 정책(고급 매개변수)

  • 매개변수 정책을 통해 만료 기한을 뜻하는 TTL를 매개변수에 할당할 수 있다.
    사용자가 비밀번호 등의 민감한 정보를 업데이트 또는 삭제하도록 강제할 수 있음.
  • 한 번에 여러 정책을 할당할 수 있다.

    - 매개변수를 삭제하는 만료 정책(왼쪽)
    이 타임스탬프에서는 이 매개변수를 반드시 삭제해야 한다.
    - EventBridge와 통합(중간)
    EventBridge와 통합 함으로써 EventBridge에서 알림을 받을 수 있게 된다.
    이 예시는 매개변수가 만료되기 15일 전에 EventBridge 알림을 받게 된다.
    TTL로 매개변수가 삭제되기 전에 업데이트할 수 있을 만큼 여유가 충분하다.
    - 매개변수를 변경하고 싶을 때(오른쪽)
    EventBridge는 변경이 없다는 알림도 제공하므로
    20일 동안 매개변수에 업데이트가 없으면 알림을 받게 한다.

SSM 매개변수 실습(CLI 이용)

AWS Systems Manager > 왼쪽 바 [파라미터 스토어]
-> 작동 방식
1. 새로운 매개변수를 생성
2. 매개변수의 유형과 값을 명시
3. 코드의 명령 내에서 그 매개변수를 참조


- 위 매개변수를 여러개 생성하고, 이 매개변수에 액세스하려면 CLI를 사용한다.

# AWS CLI
aws ssm get-parameters --names /my-app/dev/db-url

// db-password 같이 SecureString 타입은 뒤에 --with-decryption을 붙여주자(단, KMS에 액세스하지 못하는 계정은 접근할 수 없음)
aws ssm get-parameters --names /my-app/dev/db-password --with-decryption

# 해당 경로의 모든 매개변수 쿼리하기
aws ssm get-parameters-by-path help
aws ssm get-parameters-by-path /my-app/dev/

# my-app에서 매개변수를 반복적으로 가져오기
aws ssm get-parameters-by-path /my-app/ --recursive

SSM 매개변수 실습(Lambda,SDK 사용)

람다 함수에 CloudWatch 로그에 쓰기 권리를 제공해 SSM 파라미터 스토어에 읽기 및 쓰기 하기

### 람다를 사용해 SSM 매개변수 활용
# AWS Lambda 콘솔
Create function > 
이름: hello-world-SSM
럼타임: Pyhtion 3.12
권한: IAM 실행 규칙 생성(기본 Lambda 권한이 있는 새로운 역할 생성 체크)
생성

=============================
import json
import boto3

ssm=boto.client('ssm', region_name='ap-northeast-2')

def lambda_handler(event, context):
    db_url= ssm.get_parameters(Names=["/my-app/dev/db-url"])
    print(db_url)
    db_password= ssm.get_parameters(Names=["/my-app/dev/db-password"])
    print(db_password)
    return "worked"
=============================
> 테스트 클릭 (실패)
=> GetParameter 작업 호출 시 AccessDenied Exception
=> labmda_basic_execution_ssm은 ssm:GetParameters를 실행할 권한이 없음
=> iam 역할을 추가해야 한다.

# iam 역할 추가하기
iam > 역할 > 아까 만든 ssm 역할 > 권한 > 권한 추가 > 인라인 정책 생성 >
서비스: systems manager > 읽기: [v] GetParameters, GetParametersByPath > 리소스 항목: 특정, ARN 추가 클릭 > 리전: 모든 리전, 계정: 모든 계정, 명확한 파라미터이름: my-app/* > 추가
> 이름 설정 후 생성

다시 람다를 실행(실패) -> 바로 적용이 안되는 경우도 있음
5분정도 기다렸다 시도

실행 -> 성공

### db-url은 값이 나오지만 db-password는 SecretString이라 암호화되어있다.

# 복호화 작업
=============================
import json
import boto3

ssm=boto.client('ssm', region_name='ap-northeast-2')

def lambda_handler(event, context):
    db_url= ssm.get_parameters(Names=["/my-app/dev/db-url"])
    print(db_url)
    db_password= ssm.get_parameters(Names=["/my-app/dev/db-password"], **WithDecryption=True**)
    print(db_password)
    return "worked"
=============================
다시 람다 실행 (실패)
=> AccessDeniedException
=> 고객 마스터 키를 사용할 수 없기 떄문에 복호화 불가능
=> IAM 역할에 KMS 액세스를 부여해야 한다.

비밀번호를 보고 싶다면 IAM에 역할 추가
# 역할 추가
IAM > 역할 > 아까 그거 > 수정 > 인라인 정책 > 
서비스: KMS, 쓰기: Decrypt, 리소스: 특정, ARN 추가 > 리전: 모든 리전, 계정: 모든 계정, Key id: kms키 id 넣고 > 추가

이제 람다를 다시 실행하면 값을 볼 수 있다.
### dev와 prod 파라미터가 있을 떄 변경 요령
# 람다 > 환경변수 탭 > 키: DEV_OR_PROD, 값: dev
=============================
import json
import boto3
import os

ssm=boto.client('ssm', region_name='ap-northeast-2')
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"])
    print(db_url)
    db_password= ssm.get_parameters(Names=["/my-app/" + dev_or_prod + "/db-password"], **WithDecryption=True**)
    print(db_password)
    return "worked"
=============================

prod로 변경하고 싶다면 환경 변수에서 하나만 변경하면 됌

AWS Secrets Manager

  • 암호를 저장하는 최신 서비스
    SSM Parameter Stroe와는 다른 서비스이다.
  • Secrets Manager는 x일마다 강제로 암호를 교체하는 기능이 있다.
    => 암호 관리를 더 효율적으로 할 수 있음.
  • AWS Secrets Manager로 교체할 암호를 강제 생성 및 자동화할 수 있다.
    이를 위해 새 암호를 생성할 Lambda 함수를 정의해야 한다.
  • AWS가 제공하는 다양한 서비스와 잘 통합됨
    ex: RDS, MySQL, PostgreSQL, Aurora, AWS 외 여러 서비스와 DB에 즉시 통합 가능.
    DB에 접근하기 위한 사용자 이름과 비밀번호가 AWS Secrets Manager에 바로 저장되고 교체도 가능하다.
  • 암호는 KMS 서비스를 통해 암호화된다.
  • RDS와 Aurora의 통합 또는 암호에 대한 내용 = AWS Secrets Manager

AWS Secrets Manager - 다중 리전 암호

  • 다중 리전에 암호를 복제 가능
    Secrets Manager가 기본 암호와 동기화된 읽기 전용 복제본을 유지하는 개념

    - 두 리전이 있으면 기본 리전에 암호를 하나 만들면 다른 리전에 동일한 암호가 복제됨.
    - 이렇게 하는 이유
  1. 기본 리전에 문제가 발생하면 암호 복제본을 독립 실행형 암호로 승격할 수 있다.
  2. 여러 리전에 암호가 복제되어 다중 리전 앱을 구축하고 재해 복구 전략을 짤 수 있음.


    EX: 한 리전에서 다음 리전으로 복제되는 RDS DB가 있다면 동일한 암호로 동일한 RDS DB에 액세스 가능하다.

AWS Secrets Manager 실습(x)

  • 수명 주기동안 암호를 쉽게 교체, 관리, 검색할 수 있음.
  • 암호 저장 측면에서 SSM과 유사하지만 교체,관리, DB와의 통합도 지원한다.
    MySQL, PostgreSQL, Aurora, RDS 등
  • 30 일 무료 체험판
    암호 당 월 0.4또는10,000API호출당0.05또는 10,000API 호출 당 0.05

AWS Certificate Manager(ACM)

  • ACM은 TLS 인증서를 AWS에서 프로비저닝, 관리 및 배포한다.
  • ACM은 퍼블릭, 프라이빗 TLS 인증서를 모두 지원
    퍼블릭 TLS 인증서 = FREE
  • 인증서 자동 갱신 기능 제공
  • 여러 AWS 서비스와 통합되어 있다.
    • ELB에 TLS인증서 불러오기
    • CloudFront 배포
    • API Gateway의 모든 API에서 불러오기
  • 단, EC2 인스턴스에는 ACM 을 불러올 수 없다.
    퍼블릭 인증서일 경우 추출이 불가능하다.
    즉, ACM을 통해 EC2 인스턴스에 대한 퍼블릭 인증서를 생성할 수 없음.

ACM- 퍼블릭 인증서 요청 과정

  1. 인증서에 포함할 도메인 이름을 나열
    ex: salestore.com과 같은 전체 주소 도메인 이름(FQDN)도 될 수 있고,
    *.com과 같은 와일드카드 도메인도 가능
    + 도메인 수에 제한이 없다.
  2. 유효성 검증 방법: DNS 검증과 이메일 검증 중 선택
    - 자동화를 목적으로 SSL 인증서를 자동 갱신하려면 DNS 검증을 쓰는게 낫다
    - 이메일 검증은 ACM이 도메인에 등록된 연락처로 이메일을 보내 해당 인증서를 요청했는지 여부를 확인
    - DNS 검증은 DNS 구성에서 CNAME 레코드를 생성해 도메인 소유권을 증명해야 한다.
    ex: Route 53이 있다면 ACM과 자동으로 통합해 이 작업을 수행해준다.
  3. 몇 시간 후 유효성 검증이 완료되면 인증서가 발행
  4. 이 퍼블릭 인증서도 자동 갱신 목록에 추가된다.
    - ACM에서 스스로 생성된 모든 인증서를 만료 60일 전에 자동으로 갱신해 준다.

ACM - 퍼블릭 인증서 가져오기

  • ACM 외부에서 가져오는 인증서는 자동 갱신이 불가능하다.
    ACM 서비스가 만료 45일 전부터 메일 만료 이벤트를 EventBridge 서비스에 전송해준다.
  • AWS Config를 사용하는 방법
    acm-certificate-expiration-check라는 관리형 규칙으로
    만료된 인증서를 확인하는 규칙으로 일수를 조정해 EventBridge로 알림 받기

ACM - ALB와 통합되는 방법


- 백엔드에 ASG이 있는 ALB와 ACM으로 프로비저닝 및 유지관리되는 TLS 인증서가 있다 생각해보자
- ALB에서는 HTTP에서 HTTPS로의 리디렉션 규칙을 설정할 수 있음.
- 사용자가 HTTP 프로토콜에서 ALB에 액세스할 때 ALB는 HTTPS로 리디렉션하는 요청을 반환 한다.
- 그 후 사용자는 HTTPS 프로토콜에서 ALB에 액세스하고, 이는 ACM에서 나오는 TLS 인증서를 사용한다.
- 요청이 HTTPS 프로토콜을 통과하면 ASG로 바로 전달된다.

ACM - API Gateway와 통합되는 방법

  • 엔드 포인트 유형

    • 엣지 최적화(edge-optimized) 유형
      • 글로벌 클라이언트를 위한 유형
        먼저 CloudFront 엣지 로케이션으로 요청을 라우팅해 지연을 줄이는 방법
        하나의 리전에만 있는 API Gateway로 보내지는 경우
    • 리전(regional) 엔드 포인트 유형
      • 클라이언트가 API Gateway와 같은 리전에 있을 때
        CloudFront는 사용할 수 없지만 자체 CloudFront 배포를 생성해 캐싱 및 배포 전략을 제어할 수는 있다.
    • Private API Gateway EndPoint
      • 인터페이스 VPC 엔드포인트(ENI)를 통해 VPC 내부에만 액세스 가능
        프라이빗 모드에서는 API Gateway에 대한 액세스를 정의하는 리소스 정책이 필요하다.
  • 정리: ACM은 엣지 최적화와 리전 엔드포인트에 적합하다.

  • ACM을 API Gateway와 통합하려면 API Gateway에 사용자 지정 도메인 이름이라는 리소스를 생성하고 구성해야 한다.

  • 엣지 최적화 엔드포인트

    • 요청이 CloudFront에서 라우팅되고
    • 그런 다음 TLS 인증서가 CloudFront 배포에 연결된다.
    • TLS 인증서가 반드시 CloudFront와 같은 리전이어야 한다.

      - API Gateway가 한 리전에 있고 CloudFront를 통해 배포되는 모든 것과 ACM 인증서는 반드시 같은 리전에 있어야 함.
      - 이 후 Route 53에 CNAME이나 A-Alias 레코드를 설정하면 된다.
  • 리전 엔드 포인트

    • API Gateway와 리전이 같은 클라이언트를 위한 엔드포인트

      - API Gateway만 있으므로 TLS 인증서를 API Gateway에 가져올 때는 같은 리전에 속해 있어야 한다.
      - 이 후 Route 53에 CNAME이나 별칭 레코드가 DNS를 가리키도록 설정하면 된다.

0개의 댓글

관련 채용 정보