Skip to content

Instantly share code, notes, and snippets.

@billimek
Last active November 3, 2023 14:25
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save billimek/2f2d1ef23e38442daef4b3bafc400fef to your computer and use it in GitHub Desktop.
Save billimek/2f2d1ef23e38442daef4b3bafc400fef to your computer and use it in GitHub Desktop.
vault transit auto-unseal

Dual vault servers that unseal each-other with transit seal type

Instructions inspired from auto unseal with transit guide

Prerequisites

  • Docker
  • vault CLI

1. Bootstrap first vault server

# make persistent directories and set permissions
mkdir -p vault/config
mkdir -p vault/data
sudo chown 100:100 vault/data

# make initial config file
tee vault/config/config.hcl <<EOF
storage "file" {
    path = "/vault/data"
}

listener "tcp" {
  tls_disable = 1
  address = "[::]:8200"
  cluster_address = "[::]:8201"
}
EOF

# run vault server
docker run -d --name vault --cap-add=IPC_LOCK -p 8200:8200 -v $(pwd)/vault/config:/vault/config -v $(pwd)/vault/data:/vault/data vault server

# initialize vault & make note of root token and unseal key
VAULT_ADDR=http://127.0.0.1:8200 vault operator init -n 1 -t 1

# unseal the vault server
VAULT_ADDR=http://127.0.0.1:8200 vault operator unseal <unseal key from above>

2. Configure first vault server to act as a transit server

# login to the vault server with the root token
VAULT_ADDR=http://127.0.0.1:8200 vault login <root token from above>

# Enable the transit secrets engine
VAULT_ADDR=http://127.0.0.1:8200 vault secrets enable transit

# Create a key named 'autounseal'
VAULT_ADDR=http://127.0.0.1:8200 vault write -f transit/keys/autounseal

# Create a policy file
tee autounseal.hcl <<EOF
path "transit/encrypt/autounseal" {
   capabilities = [ "update" ]
}

path "transit/decrypt/autounseal" {
   capabilities = [ "update" ]
}
EOF

# Create an 'autounseal' policy
VAULT_ADDR=http://127.0.0.1:8200 vault policy write autounseal autounseal.hcl

# Create a client token with autounseal policy attached and response wrap it with TTL of 600 seconds.
VAULT_ADDR=http://127.0.0.1:8200 vault token create -policy="autounseal" -wrap-ttl=600

# make note of the "wrapping_token" from the output above

# unwrap the autounseal token and capture the client token
VAULT_ADDR=http://127.0.0.1:8200 VAULT_TOKEN=<wrapping_token> vault unwrap

# make note of the "token" - this will be the client token used for vault instance #2

3. Bootstrap second vault server

# make persistent directories and set permissions
mkdir -p vault2/config
mkdir -p vault2/data
sudo chown 100:100 vault2/data

# make initial config file
tee vault2/config/config.hcl <<EOF
storage "file" {
    path = "/vault/data"
}

listener "tcp" {
  tls_disable = 1
  address = "[::]:8200"
  cluster_address = "[::]:8201"
}

seal "transit" {
  address = "http://<ip adress of the host where the first vault server is running>:8200"
  disable_renewal = "false"
  key_name = "autounseal"
  mount_path = "transit/"
  tls_skip_verify = "true"
}
EOF

# run vault server
docker run -d --name vault2 --cap-add=IPC_LOCK -p 8100:8200 -e VAULT_TOKEN="<client token obtained from vault server 1 above>" -v $(pwd)/vault2/config:/vault/config -v $(pwd)/vault2/data:/vault/data vault server

# initialize vault & make note of root token and unseal key
VAULT_ADDR=http://127.0.0.1:8100 vault operator init -recovery-shares=1 -recovery-threshold=1

# unseal the vault server
VAULT_ADDR=http://127.0.0.1:8100 vault operator unseal <unseal key from above>

4. Configure second vault server to act as a transit server

# login to the second vault server with the root token
VAULT_ADDR=http://127.0.0.1:8100 vault login <root token from above>

# Enable the transit secrets engine
VAULT_ADDR=http://127.0.0.1:8100 vault secrets enable transit

# Create a key named 'autounseal'
VAULT_ADDR=http://127.0.0.1:8100 vault write -f transit/keys/autounseal

# Create a policy file
tee autounseal.hcl <<EOF
path "transit/encrypt/autounseal" {
   capabilities = [ "update" ]
}

path "transit/decrypt/autounseal" {
   capabilities = [ "update" ]
}
EOF

# Create an 'autounseal' policy
VAULT_ADDR=http://127.0.0.1:8100 vault policy write autounseal autounseal.hcl

# Create a client token with autounseal policy attached and response wrap it with TTL of 600 seconds.
VAULT_ADDR=http://127.0.0.1:8100 vault token create -policy="autounseal" -wrap-ttl=600

# make note of the "wrapping_token" from the output above

# unwrap the autounseal token and capture the client token
VAULT_ADDR=http://127.0.0.1:8100 VAULT_TOKEN=<wrapping_token> vault unwrap

# make note of the "token" - this will be the client token used for vault instance #2

5. Add transit seal type to first vault server

# append transit seal type to first vault server config file
tee -a vault/config/config.hcl <<EOF

seal "transit" {
  address = "http://<ip adress of the host where the second vault server is running>:8200"
  disable_renewal = "false"
  key_name = "autounseal"
  mount_path = "transit/"
  tls_skip_verify = "true"
}
EOF

# shut-down first vault server
docker rm -f vault

# restart first vault server with the client token obtained from the previous step
docker run -d --name vault --cap-add=IPC_LOCK -p 8200:8200 -e VAULT_TOKEN="<client token obtained from vault server 2 above>" -v $(pwd)/vault/config:/vault/config -v $(pwd)/vault/data:/vault/data vault server

# unseal the first vault server again
VAULT_ADDR=http://127.0.0.1:8200 vault operator unseal <unseal key for first vault server>

# login to the first vault server with the root token
VAULT_ADDR=http://127.0.0.1:8200 vault login <root token for first vault server>

# migrate the unseal type from shamir to the transit type this was just configured for
VAULT_ADDR=http://127.0.0.1:8200 vault operator unseal -migrate

6. Profit!

Now the two vault servers will unseal each-other.

@patsevanton
Copy link

Corrected in the config 'vault/config/config.hcl`:

seal "transit" {
  address = "http://192.168.10.8:8100"
}

192.168.10.8:8100 - second vault.
Now another issue:

VAULT_ADDR=http://127.0.0.1:8200 vault operator unseal 4I9eiVZidyHnFiIxbsGLCRFAH0hsIr7QuXouuaxPMls=
Error unsealing: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/sys/unseal
Code: 500. Errors:

* migrate option not provided and seal migration is pending

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment