Guide_Accessing Vault

Dev.Hammy·2023년 12월 26일
0

Spring Guides

목록 보기
35/46

이 가이드는 Spring Vault를 사용하여 비밀 관리 도구인 HashiCorp Vault에서 비밀을 로드하는 애플리케이션을 구축하는 과정을 안내합니다.

HashiCorp Vault

HashiCorp Vault는 보안을 위한 비밀 관리 도구로, 암호, API 키, 암호화된 데이터 등을 안전하게 보관하고 액세스 관리를 제어하는 데 사용됩니다.

일반적으로 소프트웨어 애플리케이션에서 중요한 보안 정보(비밀 키, 패스워드, API 토큰 등)는 안전하게 저장되어야 합니다. Vault는 이러한 중요한 정보를 안전하게 저장하고 관리하기 위한 솔루션으로 사용됩니다.

Vault는 다양한 보안 시나리오에 대응하기 위해 다음과 같은 기능을 제공합니다:

  1. 보안 저장소(Secure Storage): Vault는 안전한 저장소 역할을 하며, 암호화된 형태로 중요한 데이터를 저장합니다.

  2. 액세스 제어(Access Control): 사용자 및 애플리케이션에 대한 액세스를 엄격하게 제어합니다. 정책을 사용하여 누가 어떤 데이터에 액세스할 수 있는지를 관리합니다.

  3. 다양한 보안 및 암호화 기능: 데이터 암호화, 동적 시크릿 생성, 시크릿 회전 등 다양한 보안 기능을 제공하여 데이터 보호를 강화합니다.

  4. 인증 관리(Authentication Management): 다양한 인증 메커니즘을 지원하고, 인증된 사용자에게만 데이터 액세스 권한을 부여합니다.

  5. 보안 감사(Security Auditing): Vault는 시스템의 보안 상태를 감사하고 모니터링할 수 있도록 로깅과 감사 기능을 제공합니다.

Vault는 클라우드 환경이나 온프레미스에서도 사용 가능하며, 보안 요구사항이 높은 환경에서 데이터 보호와 보안 관리를 강화하기 위해 사용됩니다. 개발자, 운영팀 및 보안 전문가들이 애플리케이션에서 사용하는 중요한 보안 정보를 안전하게 관리할 수 있도록 도와줍니다.

HashiCorp Vault 설치

https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-install

  1. Update the package manager and install GPG and wget.
sudo apt update && sudo apt install gpg wget
  1. Download the keyring
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
  1. Verify the keyring
gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint
  1. Add the HashiCorp repository.
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
  1. Install Vault
sudo apt update && sudo apt install vault
  1. Verifying the Installation
    새 터미널을 열고 아래 명령어를 실행하여 바이너리가 실행되는지 확인하세요
vault

이런 화면이 나온다면 정상적으로 설치된 것입니다.

무엇을 만들 것인가

Vault에 저장된 비밀을 로드하고 전송 암호화 백엔드를 사용합니다.

Starting with Spring Initializr

개발용 vault server 시작

vault server --dev --dev-root-token-id="00000000-0000-0000-0000-000000000000"

이 명령어는 HashiCorp Vault를 개발용(Dev mode)으로 실행하는 데 사용됩니다.

여기서 각 옵션은 다음과 같은 역할을 합니다:

  • vault server: Vault 서버를 시작하는 명령어입니다.
  • --dev: Vault를 개발용 모드로 실행하도록 지시합니다. 개발 모드에서는 데이터를 영속적으로 보관하지 않고, 메모리에 보관하며, 토큰이 고정되어 있습니다.
  • --dev-root-token-id="00000000-0000-0000-0000-000000000000": 개발용 모드에서는 루트 토큰을 설정해야 합니다. 이 옵션은 개발용 모드에서 사용할 루트 토큰의 값을 설정합니다. 여기서는 00000000-0000-0000-0000-000000000000으로 설정되었습니다.

개발용 모드는 보안을 강조하는 것보다는 Vault의 기능과 API를 테스트하고 익히는 데 주로 사용됩니다. 이 모드에서 생성된 데이터는 Vault 서버가 종료되면 사라지므로, 실제 운영 환경에서는 사용되지 않습니다. 보안 요소가 포함되지 않고 단순히 기능 및 API를 테스트할 때 유용합니다.


여러 정보가 포함된 Vault 서버의 시작 로그가 출력됩니다. 로그의 마지막 즈음에 다음과 같은 메세지가 출력되었는지 확인해보세요

[INFO ] core: post-unseal setup complete


Vault은 일종의 보안 상자로, 보안 정보를 안전하게 저장하고 암호화하는데 사용됩니다. Vault이 시작될 때 봉인(sealed)된 상태로 시작되는데, 이는 보안을 유지하기 위해 중요한 단계입니다.

Vault이 봉인된 상태에서는 저장된 데이터에 접근할 수 없습니다. Vault을 사용하려면 봉인 해제(unseal) 과정을 거쳐야 합니다. 봉인을 해제 하면 Vault 내부의 암호화 키를 해독하여 데이터에 액세스할 수 있게 됩니다.

unseal은 일종의 보안 절차로, 특정 조건이나 규칙에 따라 여러 명의 사용자가 복합적으로 작동하여 Vault의 보안을 해제합니다. 이 과정에서 복호화 키를 생성하거나 복원하여 Vault의 데이터에 접근할 수 있게 됩니다. unseal은 Vault의 보안성을 유지하고 민감한 정보를 안전하게 보호하기 위한 중요한 단계 중 하나입니다.

개발 모드(dev mode)에서는 Vault가 메모리 상에만 존재하며, 단일 unseal 키로 이미 봉인 해제 상태로 시작됩니다.


위 명령은 전송 암호화 없이 인메모리 저장소를 사용하여 개발 모드에서 Vault를 시작합니다. 이는 Vault를 로컬에서 평가하는 데 적합합니다. 프로덕션 사용을 위해서는 적절한 SSL 인증서와 안정적인 스토리지 백엔드를 사용해야 합니다. 자세한 내용은 Vault의 프로덕션 강화 가이드를 참조하세요.

Vault에 비밀(secret) 저장

Vault는 미사용 시(at rest) 암호화된 민감한(sensitive) 데이터를 저장할 수 있는 비밀 관리 시스템입니다. 비밀번호, 암호화 키, API 키와 같은 민감한 구성 세부 정보를 저장하는 것이 이상적입니다.

Vault 명령줄을 사용하여 Vault에 응용프로그램 구성을 저장하려면 다른 콘솔 창을 실행하세요.

먼저, Vault CLI가 Vault 엔드포인트를 가리키도록 하고 인증 토큰을 제공하도록 두 가지 환경 변수를 설정해야 합니다.

$ export VAULT_TOKEN="00000000-0000-0000-0000-000000000000"
$ export VAULT_ADDR="http://127.0.0.1:8200"

이제 Vault 내에 구성 키-값 쌍을 저장할 수 있습니다.

$ vault kv put secret/github github.oauth2.key=foobar

configure your application

여기서는 application.properties를 사용하여 애플리케이션을 구성합니다. Spring Cloud Vault는 부트스트랩 컨텍스트로 구성됩니다.src/main/resources/application.properties

spring.cloud.vault.token=00000000-0000-0000-0000-000000000000
spring.cloud.vault.scheme=http

애플리케이션 클래스 생성

여기에서는 모든 구성 요소가 포함된 Application 클래스를 만듭니다.

src/main/java/hello/Application.java

package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.vault.core.VaultKeyValueOperationsSupport;
import org.springframework.vault.core.VaultSysOperations;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultTransitOperations;
import org.springframework.vault.support.VaultMount;
import org.springframework.vault.support.VaultResponse;

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private VaultTemplate vaultTemplate;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... strings) throws Exception {

        //You usually would not print a secret to stdout
        VaultResponse response = vaultTemplate
                .opsForKeyValue("secret", VaultKeyValueOperationsSupport.KeyValueBackend.KV_2).get("github");

        System.out.println("Value of github.oauth2.key");
        System.out.println("-------------------------------");
        System.out.println(response.getData().get("github.oauth2.key"));
        System.out.println("-------------------------------");
        System.out.println();

        //Let's encrypt some data using the Transit backend.
        VaultTransitOperations transitOperations = vaultTemplate.opsForTransit();

        //We need to setup transit first (assuming you didn't set up it yet)
        VaultSysOperations sysOperations = vaultTemplate.opsForSys();

        if (!sysOperations.getMounts().containsKey("transit/")) {
            sysOperations.mount("transit", VaultMount.create("transit"));
            transitOperations.createKey("foo-key");
        }

        //Encrypt a plain-text value
        String ciphertext = transitOperations.encrypt("foo-key", "Secure message");

        System.out.println("Encrypted value");
        System.out.println("-------------------------------");
        System.out.println(ciphertext);
        System.out.println("-------------------------------");
        System.out.println();

        //Decrypt

        String plaintext = transitOperations.decrypt("foo-key", ciphertext);

        System.out.println("Decrypted value");
        System.out.println("-------------------------------");
        System.out.println(plaintext);
        System.out.println("-------------------------------");
        System.out.println();
    }
}

Spring Cloud Vault는 VaultOperations를 사용하여 Vault와 상호작용합니다. 유형이 안전한 액세스를 위해 Vault의 특성이 MyConfiguration에 매핑됩니다. @EnableConfigurationProperties(MyConfiguration.class)는 구성 속성 매핑을 활성화하고 MyConfiguration Bean을 등록합니다.

Application에는 MyConfiguration 인스턴스를 자동 연결하는 main() 메서드가 포함되어 있습니다.


  1. VaultTemplate: Spring에서 Vault와 상호 작용하기 위한 간편한 API를 제공하는 클래스입니다. Vault 서버와 통신하고, 다양한 Vault 기능을 실행할 수 있도록 도와줍니다.

    • VaultResponse: Vault 서버로부터의 응답을 나타내는 클래스입니다. 주로 Vault 서버에서 얻은 데이터를 담고 있습니다.
    • VaultTransitOperations: Vault의 Transit 백엔드와 상호 작용하기 위한 클래스로, 데이터를 암호화하고 복호화하는 등의 작업을 수행합니다.
    • VaultSysOperations: Vault 시스템 작업을 수행하는데 사용되며, Vault 서버의 설정 변경 및 초기화 등을 처리합니다.
  2. VaultKeyValueOperationsSupport: 이는 Vault의 Key-Value 백엔드와 상호 작용하는데 사용되며, Key-Value 데이터를 읽고 쓰는 등의 작업을 수행합니다. 주요 기능으로는 데이터 검색, 쓰기, 수정, 삭제 등이 있습니다.

  3. KeyValueBackend.KV_1KV_2는 Vault의 Key-Value 백엔드 버전을 가리킵니다. KV_1은 오래된 버전의 Key-Value 백엔드이고, KV_2는 더 최신 버전입니다. 이들 간에는 데이터 저장 방식, 기능, 설정 등에서 차이가 있을 수 있습니다.

  4. CommandLineRunner를 구현하고 run을 오버라이드하는 것은 애플리케이션이 실행될 때 특정한 로직을 수행하기 위한 방법 중 하나입니다. 이 코드에서는 Vault와의 연동 작업을 애플리케이션이 시작될 때 수행하고 있습니다. 애플리케이션이 실행될 때 Vault와의 연결 및 설정 초기화를 자동으로 수행하기 위해서 사용되었을 수 있습니다. 이를 통해 Vault와의 초기 설정을 애플리케이션 시작과 함께 자동으로 수행할 수 있습니다.


vault 서버, 백엔드, 클라이언트

Vault 서버는 Vault 애플리케이션 자체를 가리킵니다. 이것은 보안을 위한 중앙 집중식 저장소로 작동하며, 보안 토큰, 비밀 키, 인증 정보 등을 안전하게 저장하고 관리합니다.

Vault 백엔드는 Vault 서버가 실제로 사용하는 데이터 스토리지 엔진입니다. Vault는 여러 종류의 백엔드를 지원하며, 이러한 백엔드는 데이터를 저장하고 보호하기 위해 사용됩니다. 예를 들어, Key-Value 백엔드는 간단한 데이터 저장을 제공하고, Transit 백엔드는 데이터 암호화와 관련된 서비스를 제공합니다.

Vault 클라이언트는 Vault 서버와 상호 작용하는 애플리케이션 또는 도구입니다. Vault 클라이언트는 Vault 서버에 인증하고, 비밀 키를 가져오거나 저장소에서 데이터를 읽거나 쓰는 등의 작업을 수행할 수 있습니다. 클라이언트는 Vault API를 사용하여 서버와 통신하고 보안 데이터를 관리합니다.

이러한 구성요소들은 Vault 시스템에서 보안과 데이터 관리를 위해 함께 작동하여 전체 보안 솔루션을 형성합니다.


vault 백엔드

  • Transit 백엔드 : Vault의 암호화 서비스를 제공하는 백엔드입니다. 이를 통해 데이터를 암호화하고, 암호화된 데이터를 복호화할 수 있습니다. 주로 보안 관련 작업에 사용됩니다.

  • Key-Value 백엔드 간단한 데이터를 저장하고 관리하는 데 사용됩니다. 파일 시스템, 데이터베이스 또는 다른 저장소와 유사한 방식으로 데이터를 저장합니다.

  • AWS 백엔드: AWS와 상호 작용하여 AWS 자격 증명을 관리하고, AWS 리소스에 대한 액세스를 제어합니다.

  • Database 백엔드: 데이터베이스 자격 증명을 동적으로 생성하고 데이터베이스 접근을 제어합니다.

  • Token 백엔드: 다양한 종류의 토큰을 생성하고 관리합니다. 주로 인증 및 권한 부여에 사용됩니다.

이러한 백엔드들은 Vault의 다양한 기능과 서비스를 제공하며, 각각의 백엔드는 특정한 용도에 맞게 설계되어 있습니다.


ApplicationCommandLineRunner를 구현하므로 부팅이 시작될 때 run 메서드가 자동으로 호출됩니다. 다음과 같은 내용이 표시됩니다.

Vault의 비밀(secret) 백엔드는 URI를 사용하여 문서를 식별하는 문서 저장소와 잘 비교됩니다. 문서는 JSON 기반이므로 Vault 데이터의 편리한 객체 매핑이 가능합니다.

0개의 댓글