Skip to main content

Vault 서버 구축하기 2

Vault를 사용하여 모든 secret을 안전한 방식으로 저장할 수 있습니다. secret은 조직의 도메인에 대한 SSL 인증서 및 키, 회사 데이터베이스 서버에 연결하기 위한 자격 증명 등일 수 있습니다. 이러한 민감한 정보를 평문으로 저장하는 것은 바람직하지 않습니다.

다음 상황을 고려합니다.

  • 개발자는 단일 관리자 계정을 사용하여 타사 앱에 액세스하고 사용자 ID와 비밀번호를 아는 사람은 누구나 관리자로 로그인할 수 있습니다.
  • 원격 시스템에 연결하기 위한 SSH 키는 일반 텍스트로 공유 및 저장됩니다.
  • 외부 시스템 API를 호출하기 위한 API 키는 일반 텍스트로 저장됩니다.
  • 앱은 LDAP와 통합되며 해당 구성 정보는 일반 텍스트입니다.

조직은 종종 이 민감한 정보를 안전하게 저장하기 위해 통일된 워크플로우를 추구합니다.


Vault를 중앙 집중식 비밀 저장소로 사용하여 중요한 정보를 보호하고 영구 저장소에 기록하기 전에 무작위로 생성된 nonce와 함께 GCM 모드에서 256비트 AES를 사용하여 secret을 암호화합니다. 또한 저장소 백엔드는 암호화되지 않은 값을 볼 수 없으므로 공격자가 원시 저장소에 액세스하더라도 secret을 읽을 수 없습니다.

caution

루트 토큰을 사용하여 Vault를 작업할 수 있지만 루트 토큰은 충분한 초기 설정 또는 긴급 상황에만 사용하는 것이 좋습니다. 가장 좋은 방법은 조직에서의 역할에 따라 적절한 정책 세트와 함께 토큰을 사용하는 것입니다.


앞서 포스팅한 Vault 서버 구축하기 1과 이어지는 내용입니다. 앞에서 Ubuntu 22.04 이미지의 인스턴스 설치와 vault, nginx를 설치 후 8200번 포트로 실행되는 볼트 서버를 nginx에서 443으로 바인딩 후 사용하려는 도메인의 SSL 인증서 적용을 통해 볼트 웹사이트를 구축했습니다.

먼저 인스턴스에 접속하여 볼트 환경변수 설정이 필요합니다.

vi ~/.bashrc

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

루트 토큰의 경우 export VAULT_TOKEN=""을 통해서 설정할 수 있지만 루트 토큰의 경우 가급적 초기 설정에만 사용할 것이기 때문에 환경변수 설정은 하지 않겠습니다. 또한 환경변수를 설정했다고 하더라도 추후 unset으로 환경변수 설정을 해제해야 합니다.

아래 명령어를 통해 볼트 프로덕션을 실행하고 기본 설정된 unseal 5개와 루트 토큰을 발급 받습니다.

vault operator init

vault는 unseal키로 세 번의 봉인을 해제해야만 토큰 및 userpass로 접근이 가능합니다.

vault operator unseal
vault operator unseal
vault operator unseal

루트 토큰 로그인

vault login

certificate 이름을 가진 키-밸류 저장소 씨크릿 엔진을 생성해주겠습니다.

vault secrets enable -path="certificate" -description="store certificate and rsa private key" kv

생성된 씨크릿 엔진 확인

vault secrets list

씨크릿 엔진에 키와 값을 넣어볼 테스트 인증서를 생성합니다.

openssl genrsa -out test.pem 2048

모든 데이터 형식을 의미하는 골뱅이를 함께 붙여줍니다. 위 명령어는 구버전에서 사용했던 명령어고 아래 명렁어는 최신 버전에서 사용하는 명령어입니다. 공식 문서에서는 mount 대상을 씨크릿 엔진 이름으로 지정하기 때문에 혼동을 피할 수 있다고 설명하는데요. 저는 구버전이 손에 익긴 하네요.

실행을 완료하면 도메인으로 볼트 UI에 접속하여 키 값이 cert인 value로 test.pem의 정보가 잘 기입되어 있는 것을 확인하실 수 있습니다.

vault kv put certificate/2023/test cert=@test.pem # 구버전
vault kv put -mount=certificate 2023/test cert=@test.pem # 현재버전

깔끔하게 value값만 가져오고 싶다면 아래 명령어를 실행하여 가져옵니다.

vault kv get -mount=certificate -field=cert 2023/test

이번에는 정책 설정을 통해 권한 관리를 해볼 건데요. 토큰에 정책을 부여한 후 해당 토큰으로 로그인할 수도 있지만 토큰은 외우기가 쉽지 않기 때문에 어딘가에 다시 기록하게 됩니다. 그래서 정책을 생성하고 아이디/비밀번호 로그인 계정에 이 정책을 연결하겠습니다.

userpass 인증을 활성화합니다.

vault auth enable userpass

hcl 확장자로 끝나는 파일에 계정을 생성할 건데요. 저는 관리자 권한이 필요하므로 관리자 권한을 가진 정책을 생성해 줄겁니다.

path "sys/leases/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Manage auth methods broadly across Vault
path "auth/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Create, update, and delete auth methods
path "sys/auth/*"
{
capabilities = ["create", "update", "delete", "sudo"]
}

# List auth methods
path "sys/auth"
{
capabilities = ["read"]
}

# List existing policies
path "sys/policies/acl"
{
capabilities = ["read","list"]
}

# Create and manage ACL policies
path "sys/policies/acl/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# List, create, update, and delete key/value secrets
path "secret/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Manage secret engines
path "sys/mounts/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# List existing secret engines.
path "sys/mounts"
{
capabilities = ["read"]
}

# Read health checks
path "sys/health"
{
capabilities = ["read", "sudo"]
}

# 생성한 certificate 씨크릿 엔진에 대한 모든 권한
path "certificate/*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

저는 위 내용을 admin.hcl에 저장했어요. 이제 admin이라는 정책을 생성할게요.

vault policy write admin ./admin.hcl

위에서 admin 정책이 잘 생성되었나 확인해보죠.

vault policy read admin

이제 계정을 생성해 줄건데요. 저는 관리자 계정을 생성할 거니까 위에서 만든 정책명을 기입해줄게요!

vault write auth/userpass/users/아이디 \
password=패스워드 \
policies=정책이름

vault write auth/userpass/users/jinhyeok \
password=good \
policies=admin

저처럼 아이디로 생성하기 싫다!고 하시면 토큰으로 생성해보세요 ㅎㅎ.

vault token create -policy=admin

위에서 생성한 계정으로 로그인을 할건데요. 앞서 루트 토큰을 환경변수로 설정하지 않는다고 했는데 만약 그럼에도 불구하고 설정을 하셨다면!? **unset VAULT_TOKEN**을 실행해서 환경변수를 해제해주세요. 그렇지 않으면 이러한 에러가 뜹니다.

caution

WARNING! The VAULT_TOKEN environment variable is set!

The value of this variable will take precedence; if this is unwanted please unset VAULT_TOKEN or update its value accordingly.

이제 생성한 계정으로 로그인해줄게요~ 토큰으로 로그인하시면 루트 토큰으로 로그인할 때 처럼 vault login으로 로그인하세요.

vault login -method=userpass username=jinhyeok

로그인하면 token_policies와 policies의 값으로 정책이 연결된 것을 확인하실 수 있으실텐데요. 지금까지 잘 따라와주셨다면 admin과 default가 설정되어 있으실 거에요. default 정책은 볼트가 생성한 기본 정책이며 토큰이 관리할 수 있는 기능을 활성화하는 공통 기능 집합을 정의하고 있어요. default 정책이 궁금하다면 vault policy read default로 어떤 권한들이 적용되어 있는지 확인해보세요.

그 밖에도 다른 정책을 생성 및 적용하여 정책들이 올바르게 적용되고 있나 테스트해보세요. 저는 add라는 정책을 생성하고 admin 정책을 제거하고 add 정책만 연결할 거에요.

vault write auth/userpass/users/jinhyeok/policies policies="add"

정책을 생성하지 않고 기존 연결한 admin 정책을 new-policy.hcl에 정의된 권한으로 변경해주고 싶다면 아래처럼 실행해보세요.

vault write sys/policy/admin policy=@new-policy.hcl

볼트를 내부에서 인증 및 인가 과정으로도 사용할 수 있고 제 3자 인증 프록시를 볼트로 지정하여 사용할 수도 있습니다. 저장소 또한 파일시스템인 raft를 사용했지만 etcd, consul등 다양하게 활용이 가능하며 가용성을 중요하게 생각하신다면 consul을 통해 active-standby로 구축하실 수도 있습니다.

정책으로 계정 및 토큰의 권한을 관리할 수도 있지만 네임스페이스로 논리적으로 분리할 수도 있습니다. 저도 만약 다른 고객사와 볼트를 공유한다면 네임스페이스로 분리하는 것이 더 좋지만 네임스페이스 기능을 사용하려면 Vault Enterprise Standard 라이선스가 필요하거나 HCP Vault를 실행해야 한다고 하네요. 아쉽지만 이번 볼트 구축기에서는 네임스페이스는 다루지 못할 것 같네요 😭😭😭.

첨언이 길었네요. 자, 지금까지 인스턴스에 접속하여 실행해보았는데요. 기본 설정은 인스턴스 접속을 통해 진행하고 볼트를 본격적으로 사용할 때는 로컬에서 명령어를 실행할거에요 ! 먼저 로컬에서도 볼트 명령어를 실행해야 하니깐 볼트를 설치해주세요.

로컬에서는 아래 처럼 볼트 도메인을 입력해주세요.

export VAULT_ADDR="https://"

그럼 이제 SSH로 인스턴스에 접속하지 않고도 볼트 명령어를 사용하여 로그인 후 사용할 수 있습니다.

이상으로 볼트 기본 사용을 위한 구축기를 마치겠습니다.