From 9750f4a7727a4e9761a887a4b7ec1e4ec49342b0 Mon Sep 17 00:00:00 2001 From: Yoko Hyakuna Date: Tue, 9 Jan 2018 15:06:00 -0800 Subject: [PATCH 001/178] WIP - New Vault guides --- website/source/guides/architecture.html.md | 28 ++ website/source/guides/generate-root.html.md | 143 +++++++-- website/source/guides/static-secrets.html.md | 318 +++++++++++++++++++ website/source/layouts/guides.erb | 10 + 4 files changed, 473 insertions(+), 26 deletions(-) create mode 100644 website/source/guides/architecture.html.md create mode 100644 website/source/guides/static-secrets.html.md diff --git a/website/source/guides/architecture.html.md b/website/source/guides/architecture.html.md new file mode 100644 index 000000000000..c63feaa92c41 --- /dev/null +++ b/website/source/guides/architecture.html.md @@ -0,0 +1,28 @@ +--- +layout: "guides" +page_title: "Vault Architecture - Guides" +sidebar_current: "guides-vault-architecture" +description: |- + In production environments, the availability of the Vault server is critical + since any downtime may affect the system that is leveraging Vault. Vault is + designed to support a highly available deploy to ensure a machine or process + failure is minimally disruptive. The understanding of the Vault architecture + can help deciding on the Vault backends for your organization's requirements. +--- + +# Vault Architecture + +Vault documentation explained the components. + +This guide demonstrates regenerating a root token using a one-time-password (OTP). + +## Steps to Regenerate Root Tokens + +1. Make sure that the Vault server is unsealed +2. Generate a one-time-password (OTP) to share +3. Each unseal key holder runs `generate-root` with the OTP +4. Decode the generated root token + +### Step 1: Make sure that the Vault server is unsealed + +First, verify the status: diff --git a/website/source/guides/generate-root.html.md b/website/source/guides/generate-root.html.md index 311524d4476e..b83a2fcb9a41 100644 --- a/website/source/guides/generate-root.html.md +++ b/website/source/guides/generate-root.html.md @@ -8,41 +8,132 @@ description: |- # Generate Root Tokens Using Unseal Keys -It is generally considered a best practice to not persist -[root tokens][root-tokens]. Instead a root token should be generated using -Vault's `generate-root` command only when absolutely necessary. This guide -demonstrates regenerating a root token. +In a production Vault installation, the initial [root token][root-tokens] should only be used +for initial configuration. -1. Unseal the vault using the existing quorum of unseal keys. You do not need to - be authenticated. +The following command creates a token for an admin: - ```shell - $ vault unseal - # ... - ``` +```shell +vault token-create -metadata "name=ADMIN_NAME" -display-name="ADMIN_USER_NAME" \ +-orphan -no-default-policy +``` -2. Generate a one-time password: +After a subset of administrators have sudo access, +almost all operations can be performed. However, for some system critical +operations, a root token may still be required. - ```shell - $ vault generate-root -genotp - ``` +It is generally considered a best practice to not persist [root +tokens][root-tokens]. Instead a root token should be generated using Vault's +`generate-root` command only when absolutely necessary. A quorum of unseal key +holders can generate a new root token. This enforces that there +is no single person has complete access to the system. -3. Get the encoded root token: +This guide demonstrates regenerating a root token using a one-time-password (OTP). - ```shell - $ vault generate-root -otp="" - ``` +## Steps to Regenerate Root Tokens - This will require a quorum of unseal keys. This will then output an encoded - root token. +1. Make sure that the Vault server is unsealed +2. Generate a one-time-password (OTP) to share +3. Each unseal key holder runs `generate-root` with the OTP +4. Decode the generated root token -4. Decode the encoded root token: +### Step 1: Make sure that the Vault server is unsealed - ```shell - $ vault generate-root -otp="" -decode="" - ``` +First, verify the status: -Please see `vault generate-root -help` for information on the alternate -technique using a PGP key. +```shell +$ vault status +``` +The output should indicate that the Vault is unsealed (`Sealed: false`). + +If the status indicates that the Vault server is sealed, unseal the vault using +the existing quorum of unseal keys. You do not need to be authenticated. + +```shell +$ vault unseal +# ... +``` + +### Step 2: Generate a one-time-password (OTP) + +Generate a one-time password: + +```shell +$ vault generate-root -genotp +``` + +This generates the OTP to generate a new root token. The output would look like: + +```shell +$ vault generate-root -genotp +OTP: +G07n16yukWxyn7nQbG0aw== +``` + +### Step 3: Each unseal key holder runs generate-root + +Each unseal key holder runs the `generate-root` command with generated OTP: + +```shell +$ vault generate-root -otp="" +``` + +Example: + +```shell +$ vault generate-root -otp="+G07n16yukWxyn7nQbG0aw==" +Root generation operation nonce: abe86476-c6c5-9ca9-426e-bb6eba7fc987 +Key (will be hidden): +Nonce: abe86476-c6c5-9ca9-426e-bb6eba7fc987 +Started: true +Generate Root Progress: 1 +Required Keys: 3 +Complete: false +``` + +When the root key generation completes, an encoded new root token will be +provided. + +The output would look like: + +```shell +$ vault generate-root -otp="+G07n16yukWxyn7nQbG0aw==" +Root generation operation nonce: abe86476-c6c5-9ca9-426e-bb6eba7fc987 +Key (will be hidden): +Nonce: abe86476-c6c5-9ca9-426e-bb6eba7fc987 +Started: true +Generate Root Progress: 3 +Required Keys: 3 +Complete: true + +Encoded root token: O7gIhugL3oHKeVmxpKGcYA== +``` + +### Step 4: Decode the generated root tokens + +Run the `generate-root` command as follow: + +```shell +$ vault generate-root -otp="" -decode="" +``` + +Example: + +```shell +$ vault generate-root -otp="+G07n16yukWxyn7nQbG0aw==" -decode="O7gIhugL3oHKeVmxpKGcYA==" +Root token: c3d53319-b6b9-64c4-7bb3-2756e510280b +``` + +## Additional References + +Instead of using a shared OTP, you can pass a file on a disk containing a public +PGP key. + +Example: + +```shell +$ vault generate-root -pgp-key="keyname.asc" +``` + +Please see `vault generate-root -help` for more information about using PGP. [root-tokens]: /docs/concepts/tokens.html#root-tokens diff --git a/website/source/guides/static-secrets.html.md b/website/source/guides/static-secrets.html.md new file mode 100644 index 000000000000..1eb0f22850d4 --- /dev/null +++ b/website/source/guides/static-secrets.html.md @@ -0,0 +1,318 @@ +--- +layout: "guides" +page_title: "Securing Secrets - Guides" +sidebar_current: "guides-foundation-static-secrets" +description: |- + Vault supports generating new unseal keys as well as rotating the underlying + encryption keys. This guide covers rekeying and rotating Vault's encryption + keys. +--- + +# Securing secrets + +Vault can be used to store any secrets in a secure manner. The secrets may be +SSL certificates and keys for your organization's domain, credentials to connect +to a corporate database server, etc. Storing such sensitive information in a +plaintext is not desirable. This guide demonstrates the use case of Vault as a +Secret Storage. + + +## Reference Material + +- [Key/Value Secret Backend](/docs/secrets/kv/index.html) +- [Key/Value Secret Backend API](/apikey/secret/kv/index.html) +- [Client libraries](/apikey/libraries.html) for Vault API for commonly used languages + +## Estimated Time to Complete + +10 minutes + +## Challenge + +Consider the following situations: + +- Developers use a single admin account to access a third-party app + (e.g. Splunk) and anyone who knows the user ID and password can log in as an + admin +- SSH keys to connect to remote machines are shared and stored as a plaintext +- API keys to invoke external system APIs are stored as a plaintext +- An app integrates with LDAP, and its configuration information is in a + plaintext + +Organizations often seek an uniform solution to store any sensitive information +securely. + +## Solution + +Leverage Vault as a centralized secret storage to secure any sensitive +information. Vault encrypts these secrets prior to writing them to persistent +storage, so gaining access to the raw storage isn't enough to access your +secrets. + +## Prerequisites + +To perform the tasks described in this guide, you need to have a Vault +environment. You can follow the [Getting Started][getting-started] guide to +[install Vault][install-vault]. Alternatively, if you are familiar with +[Vagrant](https://www.vagrantup.com/), you can spin up a +[HashiStack](https://github.com/hashicorp/vault-guides/tree/master/provision/hashistack/vagrant) +virtual machine. + +Make sure that your Vault server has been [initialized and unsealed][initialize]. + +**NOTE:** The Vault server can be running in a [dev +mode](/intro/getting-started/dev-server.html) to perform the tasks described in +this guide. + +[getting-started]: /intro/getting-started/install.html +[install-vault]: /intro/getting-started/install.html +[initialize]: /intro/getting-started/deploy.html + + +## Steps + +This guide demonstrates the basic steps to store secrets using Vault. The +scenario here is to store the following secrets: + +- API key (Google API) +- Root certificate of a production database (MySQL) + +To store your API key within the configured physical storage for Vault, use the +key/value secret backend via **`secret/`** prefixed. + +-> Key/Value secret backend passes through any operation back to the configured +storage backend for Vault. For example, if your Vault server is configured with +Consul as its storage backend, a "read" operation turns into a read from Consul +at the same path. + + + +You will perform the following: + +1. [Store the Google API key](#step1) +2. [Store the root certificate for MySQL](#step2) +3. [Retrieve the secrets](#step3) + +### Step 1: Store the Google API key + +#### CLI command + +```shell +vault write secret/ =VALUE> +``` + +The `` can be anything you want it to be, and your organization should +decide on the naming convention that makes most sense. + +**Example:** + +```shell +vault write secret/eng/apikey/Google key=AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI +Success! Data written to: secret/eng/apikey/Google +``` + +> In this example, the path +> convention is **`secret//apikey/`**. Therefore, `secret/eng/apikey/Googl`. +> The key is "key" and its value is "AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI". +> If you have an API key for New Relic owned by the DevOps team, the path may +> look like `secret/devops/apikey/New_Relic`. + +#### API call using cURL + +To perform the same task using the Vault API, pass the token in the request header. + +**Example:** + +```shell +curl $VAULT_ADDR/v1/secret/eng/apikey/Google -X POST \ + -H "X-Vault-Token: $VAULT_TOKEN" --data '{"key": "AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI"}' +``` + + +### Step 2: Store the root certificate for MySQL + +#### CLI command + +The command is basically the same as the Google API key example. + +**Example:** + +```shell +vault write secret/prod/cert/mysql cert=@root_cert.pem +``` + +**NOTE:** Any value begins with "@" is loaded from a file. + +This example reads the root certificate from a PEM file from the disk, and store it under +`secret/prod/cert/mysql` path. + +> The path convention here is **`secret//cert/`**. This path +> has an environment flag (`prod`) to indicate that this is a root certificate +> for MySQL in production. If there is a root certificate for a PostgreSQL +> running in staging, you may store it in `secret/staging/cert/postgres`. + + +#### API call using cURL + +To perform the same task using the Vault API, pass the token in the request header. + +**Example:** + +```shell +curl $VAULT_ADDR/v1/secret/eng/apikey/Google -X POST \ + -H "X-Vault-Token: $VAULT_TOKEN" --data @root_cert.pem +``` + + + +### Step 3: Retrieve the secrets + +Retrieving the secret from Vault is simple. + +#### CLI command + +```shell +vault read secret/ +``` + +**Example:** + +```shell +vault read secret/eng/apikey/Google +Key Value +--- ----- +refresh_interval 768h0m0s +key AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI +``` + +To return the key value alone, pass `-field=key` as an argument. + +```shell +vault read -field=key secret/eng/apikey/Google +AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI +``` + +#### Root certificate example: + +```shell +vault read -field=cert secret/prod/cert/mysql +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA6E2Uq0XqreZISgVMUu9pnoMsq+OoK1PI54rsA9vtDE6wiRk0GWhf5vD4DGf1 +... +``` + +#### API call using cURL + +**Example:** + +```shell +curl $VAULT_ADDR/v1/secret/eng/apikey/Google -X GET -H "X-Vault-Token: $VAULT_TOKEN" | jq + +{ +"request_id": "5a2005ac-1149-2275-cab3-76cee71bf524", +"lease_id": "", +"renewable": false, +"lease_duration": 2764800, +"data": { + "key": "AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI" +}, +"wrap_info": null, +"warnings": null, +"auth": null +} +``` + +**NOTE:** This example uses `jq` to parse the JSON output. + +Retrieve the key value with `jq`: + +```shell +curl $VAULT_ADDR/v1/secret/eng/apikey/Google -X GET \ + -H "X-Vault-Token: $VAULT_TOKEN" | jq ".data.key" +``` + +#### Root certificate example: + +```shell +curl $VAULT_ADDR/v1/secret/prod/cert/mysql -X GET \ + -H "X-Vault-Token: $VAULT_TOKEN" | jq ".data.cert" +``` + +## Reference Content + +### Q: How do I enter my secrets without appearing in history? + +As a precaution, you may wish to avoid passing your secret as a part of the CLI +command so that the secret won't appear in the history file. Here are a few +techniques you can use. + +#### Option 1: Use a dash "-" + +An easy technique is to use a dash "-" and then press Enter. This allows you to +enter the secret in a new line. After entering the secret, press **`Ctrl+d`** to +end the pipe and write the secret to the Vault. + +```shell +vault write secret/eng/apikey/Google key=- + +AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI + +``` + +#### Option 2: Read the secret from a file + +Using the Google API key example, you can create a file containing the key (apikey.txt): + +```text +{ + "key": "AAaaBBccDDeeOTXzSMT1234BB_Z8JzG7JkSVxI" +} +``` + +The CLI command would look like: + +```shell +vault write secret/eng/apikey/Google @apikey.txt +``` + +#### Option 3: Disable all vault command history + +Sometimes, you may not even want the vault command itself to appear in history +at all. The Option 1 and Option 2 prevents the secret to appear in the history; +however, the vault command, `vault write secret/eng/apikey/Google` will appear +in history. + +In bash: + +```shell +export HISTIGNORE="&:vault" +``` + +**NOTE:** This prevents the use of the Up arrow key for command history as well. + + +### Q: How do I save multiple values? + +The two examples introduced in this guide only had a single key-value pair. You can pass multiple values in the command. + +```shell +vault write secret/dev/config/mongodb url=foo.example.com:35533 db_name=users \ + username=admin password=pa$$w0rd +``` + +Or, read the secret from a file: + +```shell +$ vault write secret/dev/config/mongodb @mongodb.txt + +$ cat mongodb.txt +{ + "url": "foo.example.com:35533", + "db_name": "users", + "username": "admin", + "password": "pa$$w0rd" +} +``` + + +## Next steps diff --git a/website/source/layouts/guides.erb b/website/source/layouts/guides.erb index 0d6834553e92..00ac032dafc5 100644 --- a/website/source/layouts/guides.erb +++ b/website/source/layouts/guides.erb @@ -1,6 +1,16 @@ <% wrap_layout :inner do %> <% content_for :sidebar do %>