Skip to main content

Hashicorp Vault - Installation 2023

Shen Zhen, China

Vault takes the security burden away from developers by providing a secure, centralized secret store for an application’s sensitive data: credentials, certificates, encryption keys, and more.

Installation

Add PGP for the package signing key (can be skipped if you already installed other Hashicorp products):

sudo apt update && sudo apt install gpg

Add the HashiCorp GPG key (can be skipped if you already installed other Hashicorp products):

wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg >/dev/null

Add the official HashiCorp Linux repository (can be skipped if you already installed other Hashicorp products):

echo "deb [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

Update and install:

sudo apt update && sudo apt install vault

vault -v
Vault v1.12.2 (415e1fe3118eebd5df6cb60d13defdc01aa17b03), built 2022-11-23T12:53:46Z
ls -la /etc/vault.d
-rw-r--r-- 1 vault vault 0 Nov 23 21:55 vault.env
-rw-r--r-- 1 vault vault 975 Nov 23 21:55 vault.hcl
ls -la /opt/vault/tls
-rw------- 1 vault vault 1850 Dec 4 05:37 tls.crt
-rw------- 1 vault vault 3272 Dec 4 05:37 tls.key

Configuring Vault Storage

Vault can either store it's data internally:

/etc/vault.d/vault.hcl

storage "raft" {
path = "./vault/data"
node_id = "node1"
}

storage "file" {
path = "/opt/vault/data"
}

Or use Consul:

/etc/vault.d/vault.hcl

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

If you want to use Consul make sure that the HTTP port is configured in accordingly:

/etc/consul.d/server.hcl

ports {
grpc = 8503
grpc_tls = 8502
dns = -1
http = 8500
https = 8501
serf_lan = 8301
serf_wan = 8302
server = 8300
}

Configuring HTTP Access

/etc/vault.d/vault.hcl

# HTTP listener
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}

One or more listeners determine how Vault listens for API requests. The example above listens on localhost port 8200 without TLS. We can add another listener for the HTTPS connection

/etc/vault.d/vault.hcl

# HTTPS listener
listener "tcp" {
address = "my.server.ip.or.domain:8201"
tls_cert_file = "/opt/vault/tls/tls.crt"
tls_key_file = "/opt/vault/tls/tls.key"
}

Enable the Vault service:

systemctl enable vault
systemctl start vault

Initialize Vault server

Run the following command to initialize Vault server and receive an unseal key and initial root token:

vault operator init

Error Message: http: server gave HTTP response to HTTPS client

In your environment set the Vault address so the Vault client will connect without TLS. Add the following to your shell config:

export VAULT_ADDR=http://127.0.0.1:8200

Now it works:

vault operator init                                                                                                        
Unseal Key 1: 4jYbl2CBIv6SpkKj6Hos9iD32k5RfGkLzlosrrq/JgOm
Unseal Key 2: B05G1DRtfYckFV5BbdBvXq0wkK5HFqB9g2jcDmNfTQiS
Unseal Key 3: Arig0N9rN9ezkTRo7qTB7gsIZDaonOcc53EHo83F5chA
Unseal Key 4: 0cZE0C/gEk3YHaKjIWxhyyfs8REhqkRW/CSXTnmTilv+
Unseal Key 5: fYhZOseRgzxmJCmIqUdxEm9C3jB5Q27AowER9w4FC2Ck

Initial Root Token: s.KkNJYWF5g0pomcCLEmDdOVCW

Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.

Vault does not store the generated root key. Without at least 3 keys to
reconstruct the root key, Vault will remain permanently sealed!

It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See "vault operator rekey" for more information.

Seal/Unseal

Every initialized Vault server starts in the sealed state. From the configuration, Vault can access the physical storage, but it can't read any of it because it doesn't know how to decrypt it. Unsealing has to happen every time Vault starts. It can be done via the API and via the command line. To unseal the Vault, you must have 3 unseal keys. Run the following command 3 times with different keys until the Unseal Progress reaches 3/3:

vault operator unseal                                                                                                      
Unseal Key (will be hidden):
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 5
Threshold 3
Version 1.12.2
Build Date 2022-11-23T12:53:46Z
Storage Type consul
Cluster Name vault-cluster-0ba62cae
Cluster ID 7d49e5fd-a1a4-c1d1-55e2-7962e43006a1
HA Enabled true
HA Cluster n/a
HA Mode standby
Active Node Address <none>

The Storage Type is set to consul and I am able to see the K/V entries in Consul:

Hashicorp Vault - Installation 2023

Vault Login

Use the Initial Root Token: s.KkNJYWF5g0pomcCLEmDdOVCW you were given to log into Vault:

vault login

Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key Value
--- -----
token s.spAZOi7SlpdFTNed50sYYCIU
token_accessor OevFmMXjbmOCQ8rSubY84vVp
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]

The token can also be set as a global variable during development export VAULT_TOKEN="s.KkNJYWF5g0pomcCLEmDdOVCW"

You can check the Vault status and should now see that the service is active and ready for operation:

vault status                                                                                                               
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 5
Threshold 3
Version 1.12.2
Build Date 2022-11-23T12:53:46Z
Storage Type consul
Cluster Name vault-cluster-0ba62cae
Cluster ID 7d49e5fd-a1a4-c1d1-55e2-7962e43006a1
HA Enabled true
HA Cluster https://127.0.0.1:8201
HA Mode active
Active Since 2022-12-04T06:37:54.871984008Z

As a root user, you can reseal the Vault with:

vault operator seal
Success! Vault is sealed.

A single operator is allowed to do this. This lets a single operator lock down the Vault in an emergency without consulting other operators.

vault status                                                                                                               
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed true
Total Shares 5
Threshold 3
Unseal Progress 0/3
Unseal Nonce n/a
Version 1.12.2
Build Date 2022-11-23T12:53:46Z
Storage Type consul
HA Enabled true

Start using Vault

Adding information to the Vault key-value store:

vault kv put -mount=secret hello foo=world

Error making API request.
* preflight capability check returned 403, please ensure client's policies grant access to path "secret/"

Sorting out the missing permissions:

mkdir /etc/vault.d/policies && nano /etc/vault.d/policies/admin-policy.hcl

/etc/vault.d/policies/admin-policy.hcl

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

# Create and manage ACL policies broadly across Vault

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

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

# Enable and manage authentication methods broadly across Vault

# 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"]
}

# Enable and manage the key/value secrets engine at `secret/` path

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

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

# List, create, update, and delete key/value intermediate pki entries
path "pki_int/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

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

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

Create a policy named admin with the policy defined in admin-policy.hcl.

vault policy write admin /etc/vault.d/policies/admin-policy.hcl
Success! Uploaded policy: admin

Hashicorp Vault - Installation 2023

vault policy list
vault policy read admin

Create a token with the admin policy attached and store the token in the variable ADMIN_TOKEN:

ADMIN_TOKEN=$(vault token create -format=json -policy="admin" | jq -r ".auth.client_token")
echo $ADMIN_TOKEN
s.MdNlboI0nff3Xpo97d1TfIxd

Check if we actually have the rights now:

vault token capabilities $ADMIN_TOKEN secret/                                                                              
create, delete, list, read, sudo, update

:thumbsup:

Hmm but I was still running into issues here. It seems that I first had to activate the secrets engine:

vault secrets enable -path=secret/ kv

And now it works!

vault kv put secret/hello val=world
vault kv get -format=json secret/hello
{
"request_id": "e13372c4-9026-44c5-c912-d25469b8d7e8",
"lease_id": "",
"lease_duration": 2764800,
"renewable": false,
"data": {
"val": "world"
},
"warnings": null
}

Hashicorp Vault - Installation 2023

Advanced Use-cases