Vault 설치 및 구성하기

Vault Certificate | Vault 소개
이민석's avatar
Jun 30, 2024
Vault 설치 및 구성하기

많은 분들이 다양한 이유들로 AWS 환경에서 SSM Parameter Store와 Secret Manager를 사용해서 다양한 환경변수를 관리하고 있습니다. 하지만 AWS 외에 GCP, Azure, NCP, OnPremise까지 다양한 환경에서는 어떻게 환경 변수를 관리할 수 있을까요?

그리고 각종 환경 변수들의 다양한 암호화를 어떻게 보장할 수 있을까요?
HashiCorp 사의 Key Management Solution인 Vault라는 도구를 자세하게 공부하며, 동시에 Vault Certificate를 취득하기 위해서 작성된 시리즈 문서입니디.

Vault 설치하기

Vault는 특정한 플랫폼에 구애받지 않고 다양한 플랫폼에서 실행이 가능합니다.

또한 Vault는 다양한 운영체제에서 실행이 가능합니다.

  • Vault is platform agnotic… meaning it can be run on many different underlying platforms

    • Kubernetes

    • Cloud-based Machines (AWS EC2 Instances, Azure Virtual Machiens)

    • VMWare Virtual Machines

    • Physical Servers

    • A Laptop

  • Vault is also available for many operating systems…

    • MacOS

    • Windows

    • Linux

    • FreeBSD

    • NetBSD

    • OpenBSD

    • Solaris

이러한 Vault를 사용하기 위해서는 기본적인 4단계가 존재합니다.

  1. Vault 설치하기

  2. Configuration File 생성하기

  3. Vault 초기화하기

  4. Vault Unseal하기

Vault 설치하기

다음의 2 사이트 중 한 곳에서 Vault를 다운로드 받을 수 있습니다.

  1. vaultproject.io

  2. releases.hashicorp.com/vault

vaultproject (docs) — Installing Vault (MacOS)를 참고하여 설치를 진행하였습니다.

brew tap hashicorp/tap
brew install hashicorp/tap/vault

혹은 다음과 같이 packer를 이용해서 vault를 설치하고 셋팅할 수 있습니다.

Vault Dev Server

별도의 복잡한 환경설정 없이 Vault를 실행할 수 있는 모드를 Dev Server라고 합니다.
Dev Server는 간단하게 킬 수 있는 만큼 다음과 같은 Pros/Cons가 존재합니다.

Pros

Cons

Quickly run vault without configuration

Non-Persistent — Runs in memory

Automatically initialized and unsealed

Insecure — doesn’t use TLS

Enables the UI — available at localhost

Sets the listener to 127.0.0.1:8200

Provides as Unseal Key

Mounts a K/V v2 Secret Engine

Automatically logs in as root

Provide a root token

이런 Dev Server는 주로 어떤 상황에서 사용할 수 있을까요?

  1. PoC

  2. 신규 개발 통합

  3. 신규 기능 테스트

  4. 기능 실험

  1. Proof of Concepts

  2. New Development Integrations

  3. Testing New Features of Vault

  4. Experimenting with Features

아래와 같은 명령어로 Vault Dev Server를 실행할 수 있습니다.

vault server -dev

이후 별도의 터미널을 열어서 아래 명령어를 입력해서 상태를 확인할 수 있습니다.

vault status

하지만 아래와 같은 프로토콜 에러가 발생합니다.

WARNING! VAULT_ADDR and -address unset. Defaulting to https://127.0.0.1:8200.
Error checking seal status: Get "https://127.0.0.1:8200/v1/sys/seal-status": http: server gave HTTP response to HTTPS client

이는 Vault Dev Server가 http에서 실행되기 때문에 발생합니다.
따라서 아래 명령어를 통해서 VAULT_ADDR을 변경하여, 에러를 해결할 수 있습니다.

export VAULT_ADDR='http://127.0.0.1:8200'
vault status

아래와 같은 출력값을 볼 수 있습니다.

Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.17.1
Build Date      2024-06-25T16:33:25Z
Storage Type    inmem
Cluster Name    vault-cluster-c217abcd
Cluster ID      abcdabcd-2a0a-6274-f601-d25c1633508a
HA Enabled      false

그리고 아래와 같은 명령어들을 추가로 입력할 수 있습니다.

vault secrets list

vault kv put secret/vaultcourses/bryan bryan=bryan

특히 vault kv put 부분을 반복적으로 입력하면 version이 점진적으로 증가되는 것을 알 수 있습니다.

USERNAME@USERNAME-DEVICE ~ % vault kv put secret/vaultcourses/bryan bryan=bryan
========= Secret Path =========
secret/data/vaultcourses/bryan

======= Metadata =======
Key                Value
---                -----
created_time       2024-06-30T15:43:15.167994Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            4


USERNAME@USERNAME-DEVICE ~ % vault kv put secret/vaultcourses/bryan bryan=bryan
========= Secret Path =========
secret/data/vaultcourses/bryan

======= Metadata =======
Key                Value
---                -----
created_time       2024-06-30T15:43:15.849787Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            5

Vault 지식 점검 #1

  1. Vault Configuration File은 HCL / Json으로 쓸 수 있습니다.

  2. HCL은 HashiCorp Configuration Language의 약자입니다.

  3. /etc/vault.d/vault.hcl 의 Configuration File에 listener stanza를 추가하는 코드 예제입니다.

    listener "tcp" {
      address = "0.0.0.0:8200"
      cluster_address = "0.0.0.0:8201"
      tls_disable = true
    }
  4. Vault에서 seal/unseal 작업을 처리하는 방법을 생각해봅시다.
    기본으로 존재하는 Root Key를 여러 개의 Sharing Key로 분할하도록 구성하려면, 그 어떤 설정도 하지 않아도 됩니다.

    no configuration
  5. 다음과 같이 UI 활성화를 비롯한 일부 설정을 포함한 /etc/vault.d/vault.hcl 구성을 가져갈 수도 있습니다.

    # UI를 활성화합니다.
    ui = true
    
    # 로그 레벨을 ERROR로 설정합니다.
    log_level = "ERROR"
    
    # 클러스터 이름을 설정합니다.
    cluster_name = "my-vault-cluster"
    
    # 주요 API 주소를 설정합니다.
    api_addr = "https://vault.gswhv.com:8200"
    
    # 클러스터 주소를 설정합니다.
    cluster_addr = "https://vault.gswhv.com:8201"
  6. 이 모든 구성 변경을 다음과 같은 명령어로 테스트할 수 있습니다.

    vault operator diagnose -config=/etc/vault.d/vault.hcl

Vault Production Server

Vault Production Server를 운영하기 위해서 다음의 조건들을 충족하게 서버를 생성합니다.

  1. 구성 파일을 통해 하나 이상의 퍼시스턴트 노드를 배포합니다.

  1. 요구 사항을 충족하는 스토리지 백엔드 사용

  1. 여러 Vault 노드가 클러스터로 구성됩니다.

  1. 애플리케이션에 가까운 곳에 배포

  1. 대부분의 경우 Vault 프로비저닝 자동화

  • Deploy one or more persistent nodes via configuration file

  • Use a storage backend that meets the requirements

  • Multiple Vault nodes will be configured as a cluster

  • Deploy close to your applicatiosn

  • Most likely, you’ll automate the provisioning of Vault

Vault를 생성하기 위해서는 아래 구문을 입력할 수 있습니다.

vault server -config=<file> 

실제로 Production 환경에서는 Vault를 실행하는 서비스 관리자를 따로 가지고 있습니다. (e.g. systemctl, window service manager)
또한 Linux에서는 Vault(or Consul)을 실행하는 경우 systemd 파일도 필요합니다.

In a production environment, you’ll have a service manager executing
and managing the Vault service (systemctl, Windows Service Manager, etc.)

For Linux, you also need a systemd file to manage the service for Vault (and Consul if you’re running Consul)

  1. Systemd for a vault service
    https://github.com/btkrausen/hashicorp/tree/master/vault/config_files

  2. Systemd file for a consul service
    https://github.com/btkrausen/hashicorp/blob/master/consul/consul.service

  3. Systemd for a consul client (that would run on the vault node)

    https://github.com/btkrausen/hashicorp/blob/master/vault/config_files/consul-client.json

Single Node Vault Cluster

Vault를 Single Node로 운영하는 구성은 추천하지 않습니다.

Not a recommended architecture

  • No redundancy

  • No sacalability

Multi Node Vault Cluster

연결된 네트워크를 통해서 스토리지 복제 환경에서 Multi Node로 Vault로 구성하는 것을 추천합니다.

Vault Node A, B, C

  • Integrated storage replication (with network)

Manual Instll to run vault server

아래 과정을 통해서 vault serve를 실행할 수 있습니다.

  1. Download vault from HashiCorp

  2. Unpackage vault to a Directory

  3. Set path to executable

  4. Add configuration file & customize

  5. Create systemd service file

  6. Download consul from HashiCorp

  7. Configure and join consul cluster

  8. Launch vault service

Vault 지식 점검 #2

  1. /etc/vault.d/vault.hcl 에 storage 작성하기

    storage "raft" {
      path    = "/opt/vault/data"
      node_id = "vault-node-a"
    }
  2. /etc/vault.d/vault.hcl 에 listener 작성하기

    listener "tcp" {
      address         = "0.0.0.0:8200"
      cluster_address = "0.0.0.0:8201"
      tls_disable     = 1
    }
  3. /etc/vault.d/vault.hcl 에 seal 작성하기

    ui           = true
    log_level    = "ERROR"
    cluster_name = "my-vault-cluster"
    api_addr     = "https://vault.gswhv.com:8200"
    cluster_addr = "https://vault.gswhv.com:8201"

Vault / Consul Storage Backend 설정하기

Vault + Consul Storage Backend 는 다음과 같은 특징이 있습니다.

Provides Durable K/V Storage For Vault

Supports High Availability

Can Independently Scale Backend

Distributed System

Easy to Automate

Built-in Snapshots for Data Retention

Built-in Integration Between Consul/Vault

HashiCorp Supported

세부적으로 다음과 같은 아키텍쳐 측면의 특징을 가지게 됩니다.

  1. Consul은 여러 노드를 사용하여 클러스터 형식으로 배포됩니다.

  2. Consul Cluster는 홀수로 배포됩니다.

  3. 모든 데이터는 클러스터의 모든 노드 간에 복제됩니다.

  4. 리더 선거는 단일 Consul Node가 리더로 승격됩니다.

  5. 리더는 새 로그 항목을 수락하고 다른 모든 노드에 복제합니다.

  6. Vault Storage Backend 용 Consul Cluster는 Production 환경의 Consul 기능에 사용해서는 안됩니다.

  • Consul is deployed using multiple nodes and configured as a cluster

  • Clusters are deployed in odd numbers (for voting members)

  • All data is replicated among all nodes in the cluster

  • A leader election promotes a single Consul node as the ledaer

  • The leader accepts new logs entries and replicates to all other nodes

  • Consul cluster for Vault storage backend shouldn’t be used for Consul functions in a production setting.

AWS 환경에서 Consul Storage Backend를 선택해서 배포하면 다음과 같습니다.

  • Region

  • VPC

  • Availability Zone 1, 2, 3

    • Private Subnet 1, 2, 3

      • Vault Server 1, 2, 3

        • Consul Backend 1a/1b, 2a/2b, 3a/3b

실제 Vault ←→ Consul, Consul ←→ Consul 간의 작업은 다음과 같이 이루어집니다.

  • Vault ← → Consul
    Vault communicates with local consul agent

  • Local Consul Agent joinss the Consul cluster as client

아래 코드를 통해서 그 구조를 살펴볼 수 있습니다.

storage "consul" {
  address = "127.0.0.1:8500"
  path = "vault/"
  token = "..."
}

listener "tcp" {
  address = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"

  tls_disable = 0
  tls_cert_file = "/etc/vault.d/client.pem"
  tls_key_file = "/etc/vault.d/cert.key"
  tls_disable_client_certs = "true"
}

seal "awskms" {
  region = "us-east-1"
  kms_key_id = "12345678-abcd-1234-abcd-1234567891-1"
  endpoint = "example.kms.us-east-1.vpce.example.com"
}

api_addr = "https://vault-us-east-1.example.com:8200"
cluster_addr = "https://vault-us-east-1.example.com:8201"
cluster_name = "vault-prod-us-east-1"
ui = true

Vault / Integrated Storage Backend 설정하기

Vault + Integrated Storage Backend 는 다음과 같은 특징이 있습니다.

Vault Internal Storage Option

Supports high availability

Leverages Raft Consensus Protocol

Only need to troubleshoot vault

All Vault nodes have copy of vault’s data

Built-in Snapshots for data retenstion

Eliminates network hop to consul

HashiCorp Supported

세부적으로 다음과 같은 아키텍쳐 측면의 특징을 가지게 됩니다.

  1. 통합 스토리지를 사용하여, Vault가 Cluster 하위의 Vault Node 전체에 자체 복제된 스토리지를 제공할 수 있습니다.

  2. 복제된 데이터를 저장할 Local Path를 정의합니다.

  3. 모든 데이터는 Cluster 하위의 Vault Node 간에 복제됩니다.

  4. Consul Cluster를 실행하고 관리할 필요가 없습니다.

  • Integrated Storage (e.g. Raft) allows Vault nodes to provide its own replicated storage across the Vault nodes within a cluster.

  • Define a local path to store replicated data.

  • All data is replicated among all nodes in the cluster.

  • Eliminates the need to also run a consul cluster and manage it.

AWS 환경에서 Integrated Storage Backend를 선택해서 배포하면 다음과 같습니다.

  • Region

  • VPC

  • Availability Zone 1, 2, 3

    • Private Subnet 1, 2, 3

      • Vault Node 1, 2, 3

실제로 각 Vault Node 1, 2, 3은 서로 tcp/8201 포트를 통해서 스토리지 복제 동기화를 진행합니다.

아래 코드를 통해서 그 구조를 살펴볼 수 있습니다.

storage "raft" {
  path = "/opt/vault/data"
  node_id = "node-a-us-east-1.example.com"
  retry_join {
    auto_join = "provider=aws region=us-east-1 tag_key=vault tag_value=us-east-1"
  }
}

listener "tcp" {
  address = "0.0.0.0:8200"
  cluster_address = "0.0.0.0:8201"

  tls_disable = 0
  tls_cert_file = "/etc/vault.d/client.pem"
  tls_key_file = "/etc/vault.d/cert.key"
  tls_disable_client_certs = "true"
}

seal "awskms" {
  region = "us-east-1"
  kms_key_id = "12345678-abcd-1234-abcd-1234567891-1"
  endpoint = "example.kms.us-east-1.vpce.example.com"
}

api_addr = "https://vault-us-east-1.example.com:8200"
cluster_addr = "https://vault-us-east-1.example.com:8201"
cluster_name = "vault-prod-us-east-1"
ui = true

CLI를 사용하여 Standby Node를 Cluster에 수동으로 결합하기

vault operator raft join https://active_node.example.com:8200
  • Manually join standby nodes to the cluster using the CLI

    vault operator raft join https://active_node.example.com:8200

HA Cluster를 통해서 Vault 1, 2, 3을 구성하면 그 중 1개가 Leader가 됩니다.
나머지 2개가 Follower가 되어서 작동합니다. 이후 아래 코드로 Cluster Member를 조회할 수 있습니다.

vault operator raft list-peers
Node      Address          State    Voter
--------  ---------------- -----    ------
vault_1   10.0.101.22:8201 leader   true
vault_2   10.0.101.23:8201 follower true
vault_3   10.0.101.24:8201 follower true
vault_4   10.0.101.25:8201 follower true
vault_5   10.0.101.26:8201 follower true

Share article

Unchaptered