Secrets management
HashiCorp Vault

Install and configure HashiCorp Vault

22min
the vault hardware security module (hsm) auto unseal and seal wrap features require vault enterprise with the governance & policy module perform the following tasks to install and configure vault download vault install vault configure systemd configure vault configure hsm auto unseal and entropy augmentation start using the vault server enable and test seal wrap feature enable and test entropy augmentation feature download vault you can download precompiled vault binaries at https //releases hashicorp com/vault/ https //releases hashicorp com/vault/ download vault enterprise binaries by following the instructions available to hashicorp vault customers this integration requires the enterprise hsm binary you can use the following link for testing https //releases hashicorp com/vault/ https //releases hashicorp com/vault/ install vault perform the following steps to install vault unzip the downloaded package and move the vault binary to /usr/local/bin/ $ unzip vault ${vault version}+ent hsm linux amd64 zip set the owner of the vault binary $ sudo chown root\ root vault check that vault is available on the system path $ sudo mv vault /usr/local/bin/ verify the vault version $ vault version the vault command features opt in autocompletion for flags, subcommands, and arguments (where supported) $ vault autocomplete install enable autocompletion $ complete c /usr/local/bin/vault vault give vault the ability to use the mlock syscall without running the process as root the mlock syscall prevents memory from being swapped to disk $ sudo setcap cap ipc lock=+ep /usr/local/bin/vault create a unique, non privileged system user to run vault $ sudo useradd system home /etc/vault d shell /bin/bash vault configure systemd systemd uses documented sane defaults ( www freedesktop org/software/systemd/man/systemd directives html http //www freedesktop org/software/systemd/man/systemd directives html ), so you must set only non default values in the configuration file create a vault service file at /etc/systemd/system/vault service $ sudo touch /etc/systemd/system/vault service add the following configuration to the vault service file \[unit] description="hashicorp vault a tool for managing secrets" documentation=https //www vaultproject io/docs/ requires=network online target after=network online target conditionfilenotempty=/etc/vault d/vault hcl startlimitintervalsec=60 startlimitburst=3 \[service] user=vault group=vault protectsystem=full protecthome=read only privatetmp=yes privatedevices=yes securebits=keep caps ambientcapabilities=cap ipc lock capabilities=cap ipc lock+ep capabilityboundingset=cap syslog cap ipc lock nonewprivileges=yes execstart=/usr/local/bin/vault server config=/etc/vault d/vault hcl execreload=/bin/kill signal hup $mainpid killmode=process killsignal=sigint restart=on failure restartsec=5 timeoutstopsec=30 startlimitinterval=60 startlimitintervalsec=60 startlimitburst=3 limitnofile=65536 limitmemlock=infinity \[install] wantedby=multi user target configure vault vault uses documented sane defaults, so you need to set only non default values in the configuration file create /etc/vault d directory $ sudo mkdir parents /etc/vault d create a vault configuration file, vault hcl $ sudo touch /etc/vault d/vault hcl set the ownership of the /etc/vault d directory $ sudo chown recursive vault\ vault /etc/vault d set the file permissions $ sudo chmod 640 /etc/vault d/vault hcl configure hsm auto unseal and entropy augmentation when a vault server is started, it normally starts in a sealed state where a quorum of existing unseal keys is required to unseal it by integrating vault with the {{ch}} , a trusted hsm key provider can automatically unseal the vault server to integrate the vault enterprise server with a {{ch}} , the configuration file must define the pkcs11 seal stanza https //www vaultproject io/docs/configuration/seal/pkcs11 html providing necessary connection information example vault hcl \# provide your futurex hsm connection information seal "pkcs11" { lib = "/usr/local/bin/fxpkcs11/x64/openssl 1 1 x/libfxpkcs11 so" slot = "0" key label = "hsm demo" hmac key label = "hsm hmac demo" generate key = "true" } \# add the entropy stanza entropy "seal" { mode = "augmentation" } \# configure the storage backend for vault storage "file" { path = "/tmp/vault" } \# addresses and ports on which vault will respond to requests listener "tcp" { address = "0 0 0 0 8200" tls disable = "true" } ui = true disable mlock = true this guide sets the storage backend to the local file system ( /tmp/vault ) to make the verification step easy the example configuration defines the following in its seal stanza lib path to the pkcs #11 library on the machine where vault enterprise is installed slot the slot number to use (this should be set to "0" because "0" is the slot that is set by default in the fxpkcs11 config file) key labe l defines the label of the key to use hmac key label defines the label of the key to use for hmacing generate key if no existing key with the label specified by key label can be found at vault initialization time, vault generates a key for this integration, set the generate key parameter to true so that vault automatically creates the encryption keys that it uses for the seal wrap functionality on the {{ch}} the values set for the key label and hmac key label parameters correspond with the special key label defines that must be set in the \<config> section of the fxpkcs11 cfg file for the full list of configuration parameters, refer to the vault documentation www vaultproject io/docs/configuration/seal/pkcs11 html#pkcs11 parameters http //www vaultproject io/docs/configuration/seal/pkcs11 html#pkcs11 parameters start using the vault server perform the following tasks to start using the vault server start the vault server initialize vault access the vault ui start the vault server perform the following steps to start the vault server first, log in with the vault user next, set the pkcs #11 pin for login with the following command (this is the {{ch}} identity password configured inside the \<crypto opr pass> tag in the fxpkcs11 cfg file) $ export vault hsm pin='identity password' the pkcs #11 pin can also be set in the vault configuration file ( vault hcl ) with the pin parameter, but we do not recommend this in a production setting the best practice is to specify the pin with the vault hsm pin environment variable, as shown here this prevents the password from being exposed if the config file is compromised or stored in an unsecured location if set through the environment variable, vault obfuscates the environment variable after reading it the one caveat is that you must reset the vault hsm pin environment variable if you restart vault now, start the vault server with the following command $ vault server config=/etc/vault d/vault hcl if the command succeeded, you should see something similar to the following output ==> vault server configuration hsm pkcs#11 version 2 20 hsm library fxpkcs11 hsm library version 4 23 hsm manufacturer id futurex hsm type pkcs11 cgo enabled go version go1 14 4 listener 1 tcp (addr "0 0 0 0 8200", cluster address "0 0 0 0 8201", max request duration "1m30s", max request size "33554432", tls "disabled") log level info mlock supported true, enabled false recovery mode false storage file version vault v1 5 0+ent hsm \==> vault server started! log data will stream in below open a new terminal window and leave the terminal where you started the vault server running initialize vault perform the following steps to initialize vault in the new terminal, first, set the vault addr environment variable $ export vault addr='http //0 0 0 0 8200' check the vault status $ vault status the output should be similar to the following key value \ recovery seal type pkcs11 initialized false sealed true total recovery shares 0 threshold 0 unseal progress 0/0 unseal nonce n/a version n/a ha enabled false initialize vault $ vault operator init recovery shares=1 recovery threshold=1 the output should be similar to the following recovery key 1 e22hrxufayqy0pvuy+renvpxolz0bsrjwastz64re24= initial root token s mvx8cihrfqmweim9yfnlw9e1 success! vault is initialized recovery key initialized with 1 key shares and a key threshold of 1 please securely distribute the key shares printed above set the vault token environment variable value to the generated root token value displayed in the terminal output $ export vault token="s mvx8cihrfqmweim9yfnlw9e1" to interact with vault, you must provide a valid token setting this environment variable allows interaction with vault through the cli access the vault ui perform the following steps to access the vault ui go to http //localhost 8200 http //localhost 8200 in a web browser copy and paste the initial root token output from the vault initialization command into the token field, and select \[ sign in ] if the login succeeds, you see the vault ui homepage enable and test the seal wrap feature perform the following tasks enable seal wrap test the seal wrap feature enable seal wrap select one of the following methods to enable seal wrap and follow the instructions cli command to compare seal wrapped data against unwrapped data, enable the key/value v1 secrets engine at two different paths kv unwrapped and kv seal wrapped enable k/v v1 without seal wrap at kv unwrapped enable k/v v1 with seal wrap by using the seal wrap flag when you enable the kv workflow to enable seal wrap, pass the seal wrap flag when you enable a secrets engine list the enabled secrets engines with details $ vault secrets list detailed path plugin accessor seal wrap \ cubbyhole/ cubbyhole cubbyhole b36dd7e1 false identity/ identity identity b5650a96 false kv seal wrapped/ kv kv fe02767b true kv unwrapped/ kv kv 36d321c6 false notice that the seal wrap parameter value is true for kv seal wrapped/ web ui open a web browser, launch the vault ui ( http //127 0 0 1 8200/ui http //127 0 0 1 8200/ui ), and then log in select enable new engine select kv from the list, and then select \[ next ] enter kv unwrapped in the path field and select version 1 for kv version return to the secrets engines page and select \[ enable engine ] select kv from the list, and then select \[ next ] enter kv seal wrapped in the path field and select version 1 for kv version select \[ method options ] to expand, and select the check box for seal wrap select \[ enable engine ] test the seal wrap feature select one of the following methods to test seal wrap and follow the instructions cli command perform the following steps to test the seal wrap feature write a secret at kv unwrapped/unwrapped for testing $ vault kv put kv unwrapped/unwrapped password="my long password" read the path to verify $ vault kv get kv unwrapped/unwrapped \====== data ====== key value \ password my long password write the same secret at kv seal wrapped/wrapped for testing $ vault kv put kv seal wrapped/wrapped password="my long password" read the path to verify $ vault kv get kv seal wrapped/wrapped \====== data ====== key value \ password my long password using a valid token, you can write and read secrets the same way, regardless of the seal wrap perform the following steps to view the encrypted secrets remember that you configured the vault server to use the same local file as the system ( /tmp/vault ) as its storage backend in this example # configure the storage backend for vault storage "file" { path = "/tmp/vault" } ssh into the machine where the vault server is running, and check the stored values in the /tmp/vault directory $ cd /tmp/vault/logical the /tmp/vault/logical directory has two sub directories one maps to kv unwrapped/ and another maps to kv seal wrapped/ although you cannot tell by the folder names view the secret at rest one of the directories maps to kv unwrapped/unwrapped example $ cd 2da357cd 55f2 7eed c46e c477b70bed18 view its content the password value is encrypted $ cat unwrapped {"value" "aaaaaqick547prhuhmibxlq2lx8zkmpsb3p+gkhawumhkrzgseqsfevms6yoqtvlbvpu9b4zwpz2hasenz3ymw=="} another directory maps to kv seal wrapped/wrapped $ cd /5bcea44d 28a3 87af 393b c6d398fe41d8 view its content the password value is encrypted $ cat wrapped {"value" "clbag9on7zbbadbzcsildaygkl7sope7vba5+adaduyzo8guhzhb9ufn2nf1h0opkegcikg3jnhcxttzqci6szcunbgf3pwhwgwb4frem3b5criqyk7239q92grgrcbbezd6ghogetsbdmzjbahk7n4liyf3x4ibqmwzghvo4lzwur7rzncgasofciiheneegghoc21fzgvtbyinahntx2htywnfzgvtb3m="} secrets are encrypted regardless however, the seal wrapped value is significantly longer, even though both values are the same ( my long password ) web ui perform the following steps to test the seal wrap feature select kv unwrapped and click \[ create secret ] enter "unwrapped" in the path for this secret field, "password" in the secret key field, and "my long password" in the value field click \[ save ] repeat the same step for kv seal wrapped to write the same secret at the kv seal wrapped/wrapped path click \[ save ] using a valid token, you can write and read secrets the same way, regardless of the seal wrap perform the following steps to view the encrypted secrets remember that you configured the vault server to use the same local file as the system ( /tmp/vault ) as its storage backend in this example # configure the storage backend for vault storage "file" { path = "/tmp/vault" } ssh into the machine where the vault server is running, and check the stored values in the /tmp/vault directory $ cd /tmp/vault/logical the /tmp/vault/logical directory has two sub directories one maps to kv unwrapped/ and another maps to kv seal wrapped/ although you cannot tell by the folder names view the secret at rest one of the directories maps to kv unwrapped/unwrapped example $ cd 2da357cd 55f2 7eed c46e c477b70bed18 view its content the password value is encrypted $ cat unwrapped {"value" "aaaaaqick547prhuhmibxlq2lx8zkmpsb3p+gkhawumhkrzgseqsfevms6yoqtvlbvpu9b4zwpz2hasenz3ymw=="} another directory maps to kv seal wrapped/wrapped $ cd /5bcea44d 28a3 87af 393b c6d398fe41d8 view its content the password value is encrypted $ cat wrapped {"value" "clbag9on7zbbadbzcsildaygkl7sope7vba5+adaduyzo8guhzhb9ufn2nf1h0opkegcikg3jnhcxttzqci6szcunbgf3pwhwgwb4frem3b5criqyk7239q92grgrcbbezd6ghogetsbdmzjbahk7n4liyf3x4ibqmwzghvo4lzwur7rzncgasofciiheneegghoc21fzgvtbyinahntx2htywnfzgvtb3m="} secrets are encrypted regardless however, the seal wrapped value is significantly longer despite both values being the same, my long password enable and test the entropy augmentation feature to leverage an external entropy source, the external entropy access parameter must be set to true when you enable a secrets engine or auth method this step enables the {{ch}} as the external entropy source on a transit secrets engine the entropy augmentation feature must be enabled through the cli currently, we do not support enabling entropy augmentation through the web ui execute the following command to enable transit secrets engine with external entropy source using the external entropy access flag $ vault secrets enable external entropy access transit list the enabled secrets engine with detailed flag $ vault secrets list detailed path plugin accessor external entropy access \ cubbyhole/ cubbyhole cubbyhole a4084622 false identity/ identity identity b5738cb7 false sys/ system system a8b3552e false transit/ transit transit 88cd3066 true notice that the external entropy access is set to true for transit/ you can start using the transit secrets engine to encrypt your sensitive data, which leverages the {{ch}} as its external entropy source regardless, the user experience remains the same as before example 1\ create a new encryption key named orders $ vault write f transit/keys/orders 2 send a base64 encoded string to be encrypted by vault $ vault write transit/encrypt/orders plaintext=$(base64 <<< "4111 1111 1111 1111") key value \ ciphertext vault\ v1\ ay3zf2bwgfwz9djlsztcldppuhkfl/kwaqeritvkgn74bgyymi+n34w1cmo8aeg= 3 now, test to verify that you can decrypt $ vault write transit/decrypt/orders \\ ciphertext="vault\ v1\ ay3zf2bwgfwz9djlsztcldppuhkfl/kwaqeritvkgn74bgyymi+n34w1cmo8aeg=" 4 decode to get the original data $ base64 decode <<< y3jlzgl0lwnhcmqtbnvtymvycg== credit card number when the external entropy access is enabled, you need connectivity to the {{ch}} if the {{ch}} becomes unreachable for any reason, the transit secrets engine fails to generate new keys or rotate the existing keys the error is similar to the following example error writing data to transit/encrypt/orders error making api request url put http //127 0 0 1 8200/v1/transit/encrypt/orders code 400 errors error performing token check failed to read entry error initializing session for decryption error logging in to hsm pkcs11 0xe0 ckr token not present