본문 바로가기
개발/AWS

AWS Secrets Manager 개념 및 테스트

by 궁즉변 변즉통 통즉구 2022. 3. 11.
반응형

비밀값 관리

대부분 어플리케이션은 외부에 노출돼서는 안되는 비밀값을 갖고 있음(ex. 데이터베이스 접속정보, 서드파티 서비스 호출을 위한 액세스 키 등)

 

비밀값 관리 원칙

  • 비밀값 유출가능성으로 비밀값은 버전 관리 시스템에 업로드되면 안됨
  • 비밀값은 최소한의 인원만 알고 있어야 함
  • 비밀값과 아닌 값은 분리해서 관리 필요

비밀값 관리 방법

  • 배포 자동화 툴
    - Jenkins, Chef, Ansible 같은 배포 자동화 툴들은 배포 시 서버 내 암호화된 값을 어플리케이션이 사용할 수 있게 저장할 수 있음
  • Vault(오픈소스)
    - 비밀값 암호화, API 접속을 위한 임시 토큰 발급, 키 롤링, 외부서비스(IAM, SSH, DB 등)에서 사용하는 권한 시스템 사용, 기록 감사, 암복호화 API 등 제공
    - 어플리케이션이 HTTP API를 통해 Vault 인증 요청을 하는 방식으로 별도의 서버를 구축하고 관리가 필요

  • AWS Secrets Manager
    - AWS에서 제공하는 비밀 값 관리 서비스
    - 비밀 값들을 AWS Secrets Manager에 저장해두고 어플리케이션에서 AWS API를 호출해서 받아서 사용하는 방식
    - 비밀 값들은 AWS KMS(Key Management Service)를 통해 암호화
    * KMS: 암호화하는데 사용하는 Key를 관리하는 AWS 서비스

  • AWS Systems Manager의 파라미터 스토어
    - Secrets Manager처럼 키/값 저장, KMS를 통한 암호화, IAM설정, 값 변경 이력 저장, AWS CLI/SDK 접근 가능 제공, 무료
    - Secrests Manager는 가능한 RDS 등 DB와 직접 연동, 삭제 후 복원, 여러 키/값을 묶어서 관리 등은 불가

[Secrets Manager 구성]출처: 서비스 운영이 쉬워지는 AWS 인프라 구축 가이드

 

Secrets Manager 생성

- Secrets Manager 서비스에서 '새 보안 암호 저장' 클릭

 

- [다른 유현의 보안 암호] 선택 후 키/값 추가(mytest_key키에 1234!@#$ 값 추가), 암호화 키KMS에서 생성한 키를 사용할 수도 있으나 기본으로 제공되는 'DefaultEncryptionKey' 선택 함

[RDS, DocumentDB, Redshift, 기타데이터베이스]를 선택하면 각 DB의 계정과 비밀번호 관리 가능, 비밀번호 자동 주기적 변경도 가능

 

- [보안 암호 이름]에 "dev/mytest"로 입력하고 다음, 보안 암호 이름 경우 "/"로 구분하여 [환경(개발or운영)/어플리케이션이름]으로 보통 구성함

 

- [자동 교체 구성]은 비활성으로 다음, 활성화 할 경우 Lambda를 이용해 주기적으로 새로운 키를 발급해서 교체 가능

 

- 샘플코드 하단에 '저장' 버튼 클릭

 

- 생성 후 목록에서 상세페이지 들어가서 샘플 코드 확인

 

샘플 어플리케이션 작성(Java)

- 로컬환경에 AWS credentials 설정

$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7XXXXXX
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCXXXXX
Default region name [None]: ap-northeast-2
Default output format [None]: json

 

- 기본 Maven 프로젝트 생성하고 Dependency 선언

<dependencies>
  <dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>secretsmanager</artifactId>
    <version>2.17.146</version>
  </dependency>
</dependencies>

 

- 위에서 확인한 샘플코드 복사해서 Main 클래스 작성

public class SecretsManager {
	public static void main(String[] args) {
		getSecret();
	}
	
	public static void getSecret() {
	    String secretName = "arn:aws:secretsmanager:ap-northeast-2:xxxxxxx:secret:dev/mytest-xxxxxx";
	    Region region = Region.of("ap-northeast-2");

	    // Create a Secrets Manager client
	    SecretsManagerClient client = SecretsManagerClient.builder()
	            .region(region)
	            .build();

	    String secret, decodedBinarySecret;
	    GetSecretValueRequest getSecretValueRequest = GetSecretValueRequest.builder()
	            .secretId(secretName)
	            .build();
	    GetSecretValueResponse getSecretValueResponse = null;

	    try {
	        getSecretValueResponse = client.getSecretValue(getSecretValueRequest);
	    } catch (Exception e) {
	        throw e;
	    } 

	    // Decrypts secret using the associated KMS key.
	    // Depending on whether the secret is a string or binary, one of these fields will be populated.
	    if (getSecretValueResponse.secretString() != null) {
	        secret = getSecretValueResponse.secretString();
	        System.out.println(secret);
	    } else {
	        decodedBinarySecret = new String(Base64.getDecoder().decode(getSecretValueResponse.secretBinary().asByteBuffer()).array());
	    }
	}
	
}

- 실행 후 출력 확인, String이 json형식이라 json객체로 컨버팅해서 사용하면 됨

 

 

반응형

댓글