Sometimes, in an emergency (or, more likely in my case, I forgot something important) I'll need to generate a Vault Root Token, as a sort of "break glass" procedure.
Both https://www.vaultproject.io/docs/commands/operator/generate-root.html and https://learn.hashicorp.com/vault/operations/ops-generate-root seem to either be missing steps or doubling steps, respectively.
So, to add to the confusion, I've decided to write my own "guide", hastily copied from my favorite documentation generation tool,
history | grep vault >> post-this-somewhere.md
.
NOTE: This assumes you already have a test Vault running and unsealed,
and that it uses a single Unseal key. Using a single Unseal key is unsafe and, frankly, a bit embarrassing. Don't let your mother or your lead SysAdmin watch you doing this. If you are the lead SysAdmin, just close your eyes for the entirety of this exercise.
Make a Test Vault if you don't have one already
File Backend with Open Source Vault
Create a test-vault.hcl
config file to work with.
mkdir test
cd test
vi test-vault.hcl
Contents of test-vault.hcl
should be:
storage "file" {
path = "./test-vault/data"
}
disable_mlock = true
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = true
}
ui = true
Run a Test Vault from the above configuration file:
wget 'https://releases.hashicorp.com/vault/1.1.2/vault_1.1.2_linux_amd64.zip'
unzip vault_1.1.2_linux_amd64.zip
./vault server -config-file=test-vault.hcl
cd ../
export VAULT_ADDR=http://127.0.0.1:8200
Get the Vault Help for Generating Vault Root Tokens
generate-root-test1$ vault operator generate-root --help
Usage: vault operator generate-root [options] [KEY]
Generates a new root token by combining a quorum of share holders. One of
the following must be provided to start the root token generation:
- A base64-encoded one-time-password (OTP) provided via the "-otp" flag.
Use the "-generate-otp" flag to generate a usable value. The resulting
token is XORed with this value when it is returned. Use the "-decode"
flag to output the final value.
- A file containing a PGP key or a keybase username in the "-pgp-key"
flag. The resulting token is encrypted with this public key.
An unseal key may be provided directly on the command line as an argument to
the command. If key is specified as "-", the command will read from stdin. If
a TTY is available, the command will prompt for text.
Generate an OTP code for the final token:
$ vault operator generate-root -generate-otp
Start a root token generation:
$ vault operator generate-root -init -otp="..."
$ vault operator generate-root -init -pgp-key="..."
Enter an unseal key to progress root token generation:
$ vault operator generate-root -otp="..."
HTTP Options:
-address=<string>
Address of the Vault server. The default is https://127.0.0.1:8200. This
can also be specified via the VAULT_ADDR environment variable.
-agent-address=<string>
Address of the Agent. This can also be specified via the
VAULT_AGENT_ADDR environment variable.
-ca-cert=<string>
Path on the local disk to a single PEM-encoded CA certificate to verify
the Vault server's SSL certificate. This takes precedence over -ca-path.
This can also be specified via the VAULT_CACERT environment variable.
-ca-path=<string>
Path on the local disk to a directory of PEM-encoded CA certificates to
verify the Vault server's SSL certificate. This can also be specified
via the VAULT_CAPATH environment variable.
-client-cert=<string>
Path on the local disk to a single PEM-encoded CA certificate to use
for TLS authentication to the Vault server. If this flag is specified,
-client-key is also required. This can also be specified via the
VAULT_CLIENT_CERT environment variable.
-client-key=<string>
Path on the local disk to a single PEM-encoded private key matching the
client certificate from -client-cert. This can also be specified via the
VAULT_CLIENT_KEY environment variable.
-mfa=<string>
Supply MFA credentials as part of X-Vault-MFA header. This can also be
specified via the VAULT_MFA environment variable.
-namespace=<string>
The namespace to use for the command. Setting this is not necessary
but allows using relative paths. -ns can be used as shortcut. The
default is (not set). This can also be specified via the VAULT_NAMESPACE
environment variable.
-output-curl-string
Instead of executing the request, print an equivalent cURL command
string and exit. The default is false.
-policy-override
Override a Sentinel policy that has a soft-mandatory enforcement_level
specified The default is false.
-tls-server-name=<string>
Name to use as the SNI host when connecting to the Vault server via TLS.
This can also be specified via the VAULT_TLS_SERVER_NAME environment
variable.
-tls-skip-verify
Disable verification of TLS certificates. Using this option is highly
discouraged as it decreases the security of data transmissions to and
from the Vault server. The default is false. This can also be specified
via the VAULT_SKIP_VERIFY environment variable.
-wrap-ttl=<duration>
Wraps the response in a cubbyhole token with the requested TTL. The
response is available via the "vault unwrap" command. The TTL is
specified as a numeric string with suffix like "30s" or "5m". This can
also be specified via the VAULT_WRAP_TTL environment variable.
Output Options:
-format=<string>
Print the output in the given format. Valid formats are "table", "json",
or "yaml". The default is table. This can also be specified via the
VAULT_FORMAT environment variable.
Command Options:
-cancel
Reset the root token generation progress. This will discard any
submitted unseal keys or configuration. The default is false.
-decode=<string>
The value to decode; setting this triggers a decode operation.
-dr-token
Set this flag to do generate root operations on DR Operational tokens.
The default is false.
-generate-otp
Generate and print a high-entropy one-time-password (OTP) suitable for
use with the "-init" flag. The default is false.
-init
Start a root token generation. This can only be done if there is not
currently one in progress. The default is false.
-nonce=<string>
Nonce value provided at initialization. The same nonce value must be
provided with each unseal key.
-otp=<string>
OTP code to use with "-decode" or "-init".
-pgp-key=<keybase:user>
Path to a file on disk containing a binary or base64-encoded public GPG
key. This can also be specified as a Keybase username using the format
"keybase:<username>". When supplied, the generated root token will be
encrypted and base64-encoded with the given public key.
-status
Print the status of the current attempt without providing an unseal key.
The default is false.
generate-root-test$
Generate a Generic OTP for Root Token Generation
generate-root-test1$ vault operator generate-root -generate-otp > otp.txt
Start the Root Token Geneneration
Yeah, it takes multiple steps. Deal.
generate-root-test1$ vault operator generate-root -init -otp=$(cat otp.txt)
Nonce 8c386f85-ba37-c74b-4ebc-436ec341dbca
Started true
Progress 0/1
Complete false
OTP Length 26
generate-root-test$
Generate Root Token incorrectly
generate-root-test$ vault operator generate-root
Operation nonce: 8c386f85-ba37-c74b-4ebc-436ec341dbca
Unseal Key (will be hidden):
Error posting unseal key: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/sys/generate-root/update
Code: 400. Errors:
* 'key' must be a valid hex or base64 string
NOTE: Turns out I copied the unseal key incorrectly
Get an Encoded Token Correctly this time
generate-root-test1$ vault operator generate-root
Operation nonce: 8c386f85-ba37-c74b-4ebc-436ec341dbca
Unseal Key (will be hidden):
Nonce 8c386f85-ba37-c74b-4ebc-436ec341dbca
Started true
Progress 1/1
Complete true
Encoded Token K3okGaAYO2w4nATeFawgA0T9LQM7zZioNWw
Attempt to Decode the Encoded Token Incorrectly
generate-root-test1$ vault operator generate-root -decode=K3okGaAYO2w4nATeFawgA0T9LQM7zZioNWw ## Forgot to supply OTP
generate-root-test1$ vault operator generate-root -decode=K3okGaAYO2w4nATeFawgA0T9LQM7zZioNWw -otp=8c386f85-ba37-c74b-4ebc-436ec341dbca ## Supplied nonce instead of otp
generate-root-test1$ vault operator generate-root --help
generate-root-test1$ vault operator generate-root --help
Usage: vault operator generate-root [options] [KEY]
Generates a new root token by combining a quorum of share holders. One of
the following must be provided to start the root token generation:
- A base64-encoded one-time-password (OTP) provided via the "-otp" flag.
Use the "-generate-otp" flag to generate a usable value. The resulting
token is XORed with this value when it is returned. Use the "-decode"
flag to output the final value.
- A file containing a PGP key or a keybase username in the "-pgp-key"
flag. The resulting token is encrypted with this public key.
An unseal key may be provided directly on the command line as an argument to
the command. If key is specified as "-", the command will read from stdin. If
a TTY is available, the command will prompt for text.
Generate an OTP code for the final token:
$ vault operator generate-root -generate-otp
Start a root token generation:
$ vault operator generate-root -init -otp="..."
$ vault operator generate-root -init -pgp-key="..."
Enter an unseal key to progress root token generation:
$ vault operator generate-root -otp="..."
HTTP Options:
-address=<string>
Address of the Vault server. The default is https://127.0.0.1:8200. This
can also be specified via the VAULT_ADDR environment variable.
-agent-address=<string>
Address of the Agent. This can also be specified via the
VAULT_AGENT_ADDR environment variable.
-ca-cert=<string>
Path on the local disk to a single PEM-encoded CA certificate to verify
the Vault server's SSL certificate. This takes precedence over -ca-path.
This can also be specified via the VAULT_CACERT environment variable.
-ca-path=<string>
Path on the local disk to a directory of PEM-encoded CA certificates to
verify the Vault server's SSL certificate. This can also be specified
via the VAULT_CAPATH environment variable.
-client-cert=<string>
Path on the local disk to a single PEM-encoded CA certificate to use
for TLS authentication to the Vault server. If this flag is specified,
-client-key is also required. This can also be specified via the
VAULT_CLIENT_CERT environment variable.
-client-key=<string>
Path on the local disk to a single PEM-encoded private key matching the
client certificate from -client-cert. This can also be specified via the
VAULT_CLIENT_KEY environment variable.
-mfa=<string>
Supply MFA credentials as part of X-Vault-MFA header. This can also be
specified via the VAULT_MFA environment variable.
-namespace=<string>
The namespace to use for the command. Setting this is not necessary
but allows using relative paths. -ns can be used as shortcut. The
default is (not set). This can also be specified via the VAULT_NAMESPACE
environment variable.
-output-curl-string
Instead of executing the request, print an equivalent cURL command
string and exit. The default is false.
-policy-override
Override a Sentinel policy that has a soft-mandatory enforcement_level
specified The default is false.
-tls-server-name=<string>
Name to use as the SNI host when connecting to the Vault server via TLS.
This can also be specified via the VAULT_TLS_SERVER_NAME environment
variable.
-tls-skip-verify
Disable verification of TLS certificates. Using this option is highly
discouraged as it decreases the security of data transmissions to and
from the Vault server. The default is false. This can also be specified
via the VAULT_SKIP_VERIFY environment variable.
-wrap-ttl=<duration>
Wraps the response in a cubbyhole token with the requested TTL. The
response is available via the "vault unwrap" command. The TTL is
specified as a numeric string with suffix like "30s" or "5m". This can
also be specified via the VAULT_WRAP_TTL environment variable.
Output Options:
-format=<string>
Print the output in the given format. Valid formats are "table", "json",
or "yaml". The default is table. This can also be specified via the
VAULT_FORMAT environment variable.
Command Options:
-cancel
Reset the root token generation progress. This will discard any
submitted unseal keys or configuration. The default is false.
-decode=<string>
The value to decode; setting this triggers a decode operation.
-dr-token
Set this flag to do generate root operations on DR Operational tokens.
The default is false.
-generate-otp
Generate and print a high-entropy one-time-password (OTP) suitable for
use with the "-init" flag. The default is false.
-init
Start a root token generation. This can only be done if there is not
currently one in progress. The default is false.
-nonce=<string>
Nonce value provided at initialization. The same nonce value must be
provided with each unseal key.
-otp=<string>
OTP code to use with "-decode" or "-init".
-pgp-key=<keybase:user>
Path to a file on disk containing a binary or base64-encoded public GPG
key. This can also be specified as a Keybase username using the format
"keybase:<username>". When supplied, the generated root token will be
encrypted and base64-encoded with the given public key.
-status
Print the status of the current attempt without providing an unseal key.
The default is false.
generate-root-test$
Correctly Decode the Encoded Token
vault operator generate-root -decode=K3okGkAYO2w4BwEPFywJA0M9LQM7DzZNQWw -otp=$(cat otp.txt) ## Finally used it correctly.
s.Tt2ya8Yo56YitsN0tbuTTeRU
And, Finally, We're Done Here
export VAULT_TOKEN=s.Tt2ya8Yo56YitsN0tbuTTeRU ## To be quickly replaced by a token with admin privileges
Now you can Use the Vault Token
curl --header "X-Vault-Token: ${VAULT_TOKEN}" "$VAULT_ADDR/v1/sys/policies/acl" ## Get a list of the names of your Vault Policies
Questions? Hit the comments. This is mostly for my own reference, but if anyone finds it useful I can improve it.
Top comments (0)