AWS Secrets Manager를 사용하여 보안 인증 관리 - AWS 권장 가이드

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

AWS Secrets Manager를 사용하여 보안 인증 관리

작성자: Durga Prasad Cheepuri(AWS)

작성자: AWS

환경: PoC 또는 파일럿

기술: 데이터베이스, 보안, 자격 증명, 규정 준수

AWS 서비스: AWS Secrets Manager

요약

이 패턴은 AWS Secrets Manager를 사용하여 Java Spring 애플리케이션의 데이터베이스 보안 인증을 동적으로 가져오는 방법을 안내합니다.

과거에는 데이터베이스에서 정보를 검색하는 사용자 지정 애플리케이션을 생성하면 일반적으로 데이터에 액세스하기 위한 보안 인증 정보(보안 암호)을 애플리케이션에 직접 포함시켜야 했습니다. 보안 인증 정보를 교체할 때는 시간을 투자하여 새 보안 인증 정보를 사용하도록 애플리케이션을 업데이트한 다음, 업데이트된 애플리케이션을 배포해야 했습니다. 보안 인증 정보를 공유하는 애플리케이션이 여러 개 있는데 이 중 하나를 업데이트하지 못한 경우 해당 애플리케이션이 침해를 당할 수 있었습니다. 이러한 위험 때문에 많은 고객들은 정기적으로 보안 인증 정보를 교체하지 않기로 결정하며, 이 위험 대신 다른 위험에 직면하게 됩니다.

Secrets Manager를 사용하면 코드의 하드 코딩된 보안 인증 정보(암호 포함)를 프로그래밍 방식으로 검색하기 위한 API 호출로 교체할 수 있습니다. 이렇게 하면 보안 암호가 해당 위치에 있지 않기 때문에 여러분의 코드를 검사하는 누군가에 의해 보안 암호가 손상되지 않도록 방지할 수 있습니다. 또한 사용자가 지정한 일정에 따라 Secrets Manager가 자동으로 보안 암호를 교체하도록 구성할 수 있습니다. 따라서 단기 보안 암호로 장기 보안 암호를 교체할 수 있어 손상 위험이 크게 줄어듭니다. 자세한 내용은 AWS Secrets Manager 설명서 섹션을 참조하세요.

사전 조건 및 제한 사항

사전 조건 

  • Secrets Manager에 액세스할 수 있는 AWS 계정

  • Java Spring 애플리케이션

아키텍처

소스 기술 스택

  • application.properties 파일에서 관리되는 DB 보안 인증 정보를 사용하여 데이터베이스에 액세스하는 코드를 포함하는 Java Spring 애플리케이션입니다.

대상 기술 스택

  • Secrets Manager에서 관리되는 DB 보안 인증 정보를 사용하여 데이터베이스에 액세스하는 코드를 포함하는 Java Spring 애플리케이션입니다. application.properties 파일에 Secrets Manager의 비밀이 보관되어 있습니다.

Secrets Manager를 애플리케이션과 통합

Diagram showing AWS Secrets Manager interaction with admin, custom app, and personnel database.

도구

  • Secrets ManagerAWS Secrets Manager는 보안 암호를 더 쉽게 관리할 수 있는 AWS 서비스입니다. 보안 암호는 데이터베이스 보안 인증 정보, 암호, 타사 API 키 및 임의 텍스트일 수 있습니다. Secrets Manager 콘솔, Secrets Manager 명령줄 인터페이스(CLI) 또는 Secrets Manager 및 를 사용하여 이러한 보안 암호에 대한 액세스를 중앙에서 저장API하고 제어할 수 있습니다SDKs.

에픽

작업설명필요한 기술
DB 보안 인증 정보를 Secrets Manager에 암호로 저장합니다.

Secrets Manager 설명서의 보안 암호 생성 단계에 따라 Amazon Relational Database Service(AmazonRDS) 또는 기타 DB 보안 인증을 보안 암호로 Secrets Manager에 저장합니다.

시스템 관리자
Spring 애플리케이션이 Secrets Manager에 액세스할 수 있도록 권한을 설정합니다.

Java Spring 애플리케이션이 Secrets Manager를 사용하는 방식에 따라 적절한 권한을 설정합니다. 보안 암호에 대한 액세스를 제어하려면 Secrets Manager 설명서, 자격 증명 기반 정책 사용(IAM 정책) 및 Secrets ManagerABAC용 섹션Secrets Manager용 리소스 기반 정책 사용 섹션에 제공된 정보를 기반으로 정책을 생성합니다. Secrets Manager 설명서의 암호 값 검색 섹션의 단계를 따르세요.

시스템 관리자
작업설명필요한 기술
Secrets Manager를 사용할 JAR 종속성을 추가합니다.

자세한 내용은 추가 정보 섹션을 참조하세요.

Java 개발자
Spring 애플리케이션에 암호의 세부 정보를 추가합니다.

보안 암호 이름, 엔드포인트 및 AWS 리전으로 application.properties 파일을 업데이트합니다. 예제를 보려면 추가 정보 섹션을 참조하세요.

Java 개발자
Java에서 DB 보안 인증 정보 검색 코드를 업데이트하세요.

애플리케이션에서 DB 보안 인증 정보를 가져오는 Java 코드를 업데이트하여 Secrets Manager에서 해당 세부 정보를 가져옵니다. 예제 코드는 추가 정보 섹션을 참조하세요.

Java 개발자

관련 리소스

추가 정보

Secrets Manager 사용에 대한 JAR 종속성 추가

Maven:

<groupId>com.amazonaws</groupId>     <artifactId>aws-java-sdk-secretsmanager</artifactId>     <version>1.11. 355 </version>

Gradle:

compile group: 'com.amazonaws', name: 'aws-java-sdk-secretsmanager', version: '1.11.355'

application.properties 파일에 암호의 세부 정보 업데이트

spring.aws.secretsmanager.secretName=postgres-local spring.aws.secretsmanager.endpoint=secretsmanager.us-east-1.amazonaws.com spring.aws.secretsmanager.region=us-east-1

Java에서 DB 보안 인증 정보 검색 코드 업데이트

String  secretName  =  env.getProperty("spring.aws.secretsmanager.secretName"); String  endpoints  =  env.getProperty("spring.aws.secretsmanager.endpoint"); String  AWS Region  =  env.getProperty("spring.aws.secretsmanager.region"); AwsClientBuilder.EndpointConfiguration  config  =  new  AwsClientBuilder.EndpointConfiguration(endpoints, AWS Region); AWSSecretsManagerClientBuilder  clientBuilder  =  AWSSecretsManagerClientBuilder.standard(); clientBuilder.setEndpointConfiguration(config); AWSSecretsManager  client  =  clientBuilder.build();        ObjectMapper  objectMapper  =  new  ObjectMapper();   JsonNode  secretsJson  =  null;   ByteBuffer  binarySecretData;   GetSecretValueRequest  getSecretValueRequest  =  new  GetSecretValueRequest().withSecretId(secretName);    GetSecretValueResult  getSecretValueResponse  =  null;   try  {      getSecretValueResponse  =  client.getSecretValue(getSecretValueRequest);     }   catch  (ResourceNotFoundException  e)  {      log.error("The requested secret "  +  secretName  +  " was not found");     }      catch  (InvalidRequestException  e)  {          log.error("The request was invalid due to: "  +  e.getMessage());      }      catch  (InvalidParameterException  e)  {          log.error("The request had invalid params: "  +  e.getMessage());      } if  (getSecretValueResponse  ==  null)  {          return  null;      }  // Decrypted secret using the associated KMS key // Depending on whether the secret was a string or binary, one of these fields will be populated               String secret = getSecretValueResponse.getSecretString();     if (secret != null) {        try {                         secretsJson  =  objectMapper.readTree(secret);                }           catch  (IOException  e)  {                         log.error("Exception while retrieving secret values: "  +  e.getMessage());                } }      else  {          log.error("The Secret String returned is null");          return null;              }      String  host  =  secretsJson.get("host").textValue();      String  port  =  secretsJson.get("port").textValue();      String  dbname  =  secretsJson.get("dbname").textValue();      String  username  =  secretsJson.get("username").textValue();      String  password  =  secretsJson.get("password").textValue(); }