|
| 1 | +--- |
| 2 | +title: Encryption At Rest |
| 3 | +summary: Encryption At Rest encrypts node data on local disk transparently. |
| 4 | +toc: false |
| 5 | +--- |
| 6 | + |
| 7 | +<span class="version-tag">New in v2.1:</span> |
| 8 | +Encryption At Rest provides transparent encryption for node data on local disk. |
| 9 | + |
| 10 | +{% include experimental-warning.md %} |
| 11 | + |
| 12 | +<div id="toc"></div> |
| 13 | + |
| 14 | +## Overview |
| 15 | + |
| 16 | +Encryption at rest allows encryption of all files on disk using AES in counter mode, with all key |
| 17 | +sizes allowed. |
| 18 | + |
| 19 | +Encryption is performed in the [storage layer](architecture/storage-layer.html) and configured per store. |
| 20 | +All files used by the store, regardless of contents, are encrypted with the desired algorithm. |
| 21 | + |
| 22 | +To allow arbitrary rotation schedules and ensure security of the keys, we use two layers of keys: |
| 23 | + |
| 24 | +| Level | Description | |
| 25 | +|-|-| |
| 26 | +| Store keys | Provided by the user in a file. They are used to encrypt the list of data keys (see below).<br><br>This is known as a **key encryption key**: it's only purpose is to encrypt other keys.<br><br>Store keys are never persisted by CockroachDB.<br><br>Since very little data is encrypted using this key, it can have a very long lifetime without risk of reuse. | |
| 27 | +| Data keys | Automatically generated by CockroachDB. They are used to encrypt all files on disk.<br><br> This is known as a **data encryption key**.<br><br>Data keys are persisted in a key registry file, encrypted using the store key.<br><br>The key has a short lifetime to avoid reuse. | |
| 28 | + |
| 29 | +Store keys are specified by passing a path to a locally readable file. The file must contain 32 bytes (the key ID) |
| 30 | +followed by the key (16, 24, or 32 bytes). The size of the key dictates the version of AES to use (AES-128, AES-192, or AES-256). |
| 31 | + |
| 32 | +At startup, CockroachDB uses a data key with the same length as the store key. If encryption has just been enabled, |
| 33 | +the key size has changed, or the data key is too old (default lifetime is one week), CockroachDB generates a new data key. |
| 34 | + |
| 35 | +Any new file created by the store uses the currently-active data key. All data keys (both active and previous) are stored in a key registry file and encrypted with the active store key. |
| 36 | + |
| 37 | +CockroachDB does not currently force re-encryption of older files but instead relies on normal RocksDB churn to slowly rewrite all data with the desired encryption. |
| 38 | + |
| 39 | +## Rotating Keys |
| 40 | + |
| 41 | +Key rotation is necessary for encryption at rest for multiple reasons: |
| 42 | + |
| 43 | +* prevent key reuse with the same encryption parameters (after many files) |
| 44 | +* reduce the risk of key exposure |
| 45 | + |
| 46 | +Store keys are specified by the user and must be rotated by specifying different keys. |
| 47 | +This is done by setting the `key` parameter of the `--enterprise-encryption` flag to the path to the new key, |
| 48 | +and `old-key` to the previously-used key. |
| 49 | + |
| 50 | +Data keys will automatically be rotated at startup if any of the following conditions are met: |
| 51 | + |
| 52 | +* the active store key changed |
| 53 | +* the encryption type changed (different key size, or plaintext to/from encryption) |
| 54 | +* the current data key is `rotation-period` old or more. |
| 55 | + |
| 56 | +Once rotated, an old key cannot be made the active key again. |
| 57 | + |
| 58 | +Upon store key rotation the data keys registry is decrypted using the old key and encrypted with the new |
| 59 | +key. The new data key is used to encrypt all new data from this point on. |
| 60 | + |
| 61 | +## Changing encryption type |
| 62 | + |
| 63 | +The user can change from plaintext to encryption, between encryption algorithms (various key sizes), |
| 64 | +or from encryption to plaintext. |
| 65 | + |
| 66 | +When changing the encryption type to plaintext, the data key registry is no longer encrypted and all previous |
| 67 | +data keys are readable by anyone. All data on the store is effectively readable. |
| 68 | + |
| 69 | +When changing from plaintext to encryption, it will take some time for all data to eventually be re-written |
| 70 | +and encrypted. |
| 71 | + |
| 72 | +## Recommendations |
| 73 | + |
| 74 | +There are a number of considerations to keep in mind when running with encryption. |
| 75 | + |
| 76 | +Key management is the most dangerous aspect of encryption. The following rules should be kept in mind: |
| 77 | + |
| 78 | +* make sure only the unix user running the `cockroach` process has access to the keys |
| 79 | +* do not store the keys on the same partition/drive as the cockroach data. It is best to load keys at run time from a separate system (eg: keywhiz, vault) |
| 80 | +* rotate store keys frequently (every few weeks to months) |
| 81 | +* keep the data key rotation period low (default is one week) |
| 82 | + |
| 83 | +A few other recommendations apply for best security practices: |
| 84 | + |
| 85 | +* do not switch from encrypted to plaintext, this leaks data keys. Once transitioned to plaintext, all data must be considered reachable. |
| 86 | +* do not copy the encrypted files as the data keys are not easily available. |
| 87 | +* if encryption is desired, start a node with it enabled from first run without ever running in plaintext. |
| 88 | + |
| 89 | +Note that backups taken with the [`BACKUP`](backup.html) statement are not encrypted (whether you are using this feature or not). If you want encrypted backups, you will need to encrypt your backup files using your preferred encryption method. |
| 90 | + |
| 91 | +## Example |
| 92 | + |
| 93 | +### Generating key files |
| 94 | + |
| 95 | +Cockroach determines which encryption algorithm to use based on the size of the key file. |
| 96 | +The key file must contain random data making up the key ID (32 bytes) and the actual key (16, 24, or 32 |
| 97 | +bytes depending on the encryption algorithm). |
| 98 | + |
| 99 | +| Algorithm | Key size | Key file size | |
| 100 | +|-|-|-| |
| 101 | +| AES-128 | 128 bits (16 bytes) | 48 bytes | |
| 102 | +| AES-192 | 192 bits (24 bytes) | 56 bytes | |
| 103 | +| AES-256 | 256 bits (32 bytes) | 64 bytes | |
| 104 | + |
| 105 | +Generating a key file can be done using the `cockroach` CLI: |
| 106 | + |
| 107 | +{% include copy-clipboard.html %} |
| 108 | +~~~ shell |
| 109 | +$ cockroach gen encryption-key -s 128 /path/to/my/aes-128.key |
| 110 | +~~~ |
| 111 | + |
| 112 | +Or the equivalent [openssl](https://www.openssl.org/docs/man1.0.2/apps/openssl.html) CLI command: |
| 113 | + |
| 114 | +{% include copy-clipboard.html %} |
| 115 | +~~~ shell |
| 116 | +$ openssl rand -out /path/to/my/aes-128.key 48 |
| 117 | +~~~ |
| 118 | + |
| 119 | +### Starting a node with encryption |
| 120 | + |
| 121 | +Encryption is configured at node start time using the `--enterprise-encryption` command line flag. |
| 122 | +The flag specifies the encryption options for one of the stores on the node. If multiple stores exist, |
| 123 | +the flag must be specified for each store. |
| 124 | + |
| 125 | +The flag takes the form: `--enterprise-encryption=path=<store path>,key=<key file>,old-key=<old key file>,rotation-period=<period>`. |
| 126 | + |
| 127 | +The allowed components in the flag are: |
| 128 | + |
| 129 | +| Component | Requirement | Description | |
| 130 | +|-|-|-| |
| 131 | +| path | required | Path of the store to apply encryption to | |
| 132 | +| key | required | Path to the key file to encrypt data with, or `plain` for plaintext | |
| 133 | +| old-key | required | Path to key file the data is encrypted with, or `plain` for plaintext | |
| 134 | +| rotation-period | optional | How often data keys should be automatically rotated | |
| 135 | + |
| 136 | +The `key` and `old-key` components must **always** be specified. They allow for transitions between |
| 137 | +encryption algorithms, and between plaintext and encrypted. |
| 138 | + |
| 139 | +Starting a node for the first time using AES-128 encryption can be done using: |
| 140 | +{% include copy-clipboard.html %} |
| 141 | +~~~ shell |
| 142 | +$ cockroach start --store=cockroach-data --enterprise-encryption=path=cockroach-data,key=/path/to/my/aes-128.key,old-key=plain |
| 143 | +~~~ |
| 144 | + |
| 145 | +{{site.data.alerts.callout_danger}} |
| 146 | +Once specified for a given store, the `--enterprise-encryption` flag must always be present. |
| 147 | +{{site.data.alerts.end}} |
| 148 | + |
| 149 | +### Checking encryption status |
| 150 | + |
| 151 | +Encryption status can be see on the node's stores report, reachable through: `http(s)://nodeaddress:8080/#/reports/stores/local`. |
| 152 | + |
| 153 | +The report shows the currently-active store key as well as the currently-active data key. The `encryption_type` field |
| 154 | +reflects the algorithm currently in use. |
| 155 | + |
| 156 | +### Changing encryption algorithm or keys |
| 157 | + |
| 158 | +Encryption type and keys can be changed at any time by restarting the node. |
| 159 | +To change keys or encryption type, the `key` component of the `--enterprise-encryption` flag is set to the new key, |
| 160 | +while the key previously used must be specified in the `old-key` component. |
| 161 | + |
| 162 | +For example, we can switch from AES-128 to AES-256 using: |
| 163 | + |
| 164 | +{% include copy-clipboard.html %} |
| 165 | +~~~ shell |
| 166 | +$ cockroach start --store=cockroach-data --enterprise-encryption=path=cockroach-data,key=/path/to/my/aes-256.key,old-key=/path/to/my/aes-128.key |
| 167 | +~~~ |
| 168 | + |
| 169 | +Upon starting, the node will read the existing data keys using the old encryption key (`aes-128.key`), then rewrite |
| 170 | +the data keys using the new key (`aes-256.key`). A new data key will be generated to match the desired `AES-256` algorithm. |
| 171 | + |
| 172 | +The new key can be seen as active in the admin UI under the stores report page. |
| 173 | + |
| 174 | +To disable encryption, specify `key=plain`. The data keys will be stored in plaintext and new data will not be encrypted. |
| 175 | + |
| 176 | +To rotate keys, specify `key=/path/to/my/new-aes-128.key` and `old-key=/path/to/my/old-aes-128.key`. The data keys |
| 177 | +will be decrypted using the old key then encrypted using the new key. A new data key will also be generated. |
| 178 | + |
| 179 | +## See Also |
| 180 | + |
| 181 | ++ [Enterprise Licensing](enterprise-licensing.html) |
| 182 | ++ [`BACKUP`](backup.html) |
0 commit comments