Instructions inspired from auto unseal with transit guide
Prerequisites
- Docker
vault
CLI
# 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>
# 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
# 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>
# 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
# 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
Now the two vault servers will unseal each-other.
@billimek If I understand correctly due hashicorp/vault#9316 you CANNOT unseal you
autounseale
even with recovery keys.In theory only way recover such "cluster" is export
autounseal
keys as plain key and then setup new emergencyShamir
server and put key to it, change token on unseal key and startup first server and then related. I asked question in related issue about this method. I don't have much time to test solution in practice. It needs to test of course. But, IMPORTANT,autounseal
unseal keys should be exportable at start (as you cannot change these attributes later). I don't know yet howvault
works I.e. ifautounseal
server somehow validate (signing or address) seal provider server.