Skip to content

Data at rest encryption

Data at rest encryption in Percona Server for MongoDB is supported by the Operator since version 1.1.0.

Note

Data at rest means inactive data stored as files, database records, etc.

Data at rest encryption is turned on by default. The Operator implements it by either using encryption key stored in a Secret, or obtaining encryption key from the HashiCorp Vault key storage.

Using encryption key Secret

  1. The secrets.encryptionKey key in the deploy/cr.yaml file should specify the name of the encryption key Secret:

    secrets:
      ...
      encryptionKey: my-cluster-name-mongodb-encryption-key
    

    Encryption key Secret will be created automatically by the Operator if it doesn’t exist. If you would like to create it yourself, take into account that the key must be a 32 character string encoded in base64.

  2. The replsets.configuration, replsets.nonvoting.configuration, and sharding.configsvrReplSet.configuration keys should include the following two MongoDB encryption-specific options:

    ...
    configuration: |
      ...
      security:
        enableEncryption: true
        encryptionCipherMode: "AES256-CBC"
        ...
    

    The enableEncryption option should be set to true (the default value). The security.encryptionCipherMode option should specify a proper cipher mode for decryption: either AES256-CBC (the default value) or AES256-GCM.

Don’t forget to apply the modified cr.yaml configuration file as usual:

$ kubectl deploy -f deploy/cr.yaml

Using HashiCorp Vault storage for encryption keys

Starting from the version 1.13, the Operator supports using HashiCorp Vault storage for encryption keys - a universal, secure and reliable way to store and distribute secrets without depending on the operating system, platform or cloud provider.

Warning

Vault integration has technical preview status and is not yet recommended for production environments.

The Operator will use Vault if the deploy/cr.yaml configuration file contains the following items:

  • a secrets.vault key equal to the name of a specially created Secret,
  • configuration keys for mongod and config servers with a number of Vault-specific options.

The Operator itself neither installs Vault, nor configures it; both operations should be done manually, as described in the following parts.

Installing Vault

The following steps will deploy Vault on Kubernetes with the Helm 3 package manager. Other Vault installation methods should also work, so the instruction placed here is not obligatory and is for illustration purposes. Read more about installation in Vault’s documentation.

  1. Add helm repo and install:

    $ helm repo add hashicorp https://helm.releases.hashicorp.com
    "hashicorp" has been added to your repositories
    
    $ helm install vault hashicorp/vault
    
  2. After installation, Vault should be first initialized and then unsealed. Initializing Vault is done with the following commands:

    $ kubectl exec -it pod/vault-0 -- vault operator init -key-shares=1 -key-threshold=1 -format=json > /tmp/vault-init
    $ unsealKey=$(jq -r ".unseal_keys_b64[]" < /tmp/vault-init)
    

    To unseal Vault, execute the following command for each Pod of Vault running:

    $ kubectl exec -it pod/vault-0 -- vault operator unseal "$unsealKey"
    

Configuring Vault

  1. First, you should enable secrets within Vault. For this you will need a Vault token. Percona Server for MongoDB can use any regular token which allows all operations inside the secrets mount point. In the following example we are using the root token to be sure the permissions requirement is met, but actually there is no need in root permissions. We don’t recommend using the root token on the production system.

    $ cat /tmp/vault-init | jq -r ".root_token"
    

    The output will show you the token:

    s.VgQvaXl8xGFO1RUxAPbPbsfN
    

    Now login to Vault with this token to enable the key-value secret engine:

    $ kubectl exec -it vault-0 -- /bin/sh
    $ vault login s.VgQvaXl8xGFO1RUxAPbPbsfN
    
    Expected output
    Success! You are now authenticated. The token information displayed below
    is already stored in the token helper. You do NOT need to run "vault login"
    again. Future Vault requests will automatically use this token.
    
    Key                  Value
    ---                  -----
    token                s.VgQvaXl8xGFO1RUxAPbPbsfN
    token_accessor       iMGp477aReYkPBWrR42Z3L6R
    token_duration       ∞
    token_renewable      false
    token_policies       ["root"]
    identity_policies    []
    policies             ["root"]`
    

    Now enable the key-value secret engine with the following command:

    $ vault secrets enable -path secret kv-v2
    
    Expected output
    Success! Enabled the kv-v2 secrets engine at: secret/
    

    Note

    You can also enable audit, which is not mandatory, but useful:

    $ vault audit enable file file_path=/vault/vault-audit.log
    
    Expected output
    Success! Enabled the file audit device at: file/
    
  2. Now generate Secret with the Vault root token using kubectl command (don’t forget to substitute the token from the example with your real root token) and add necessary options to configuration keys in your deploy/cr.yaml:

    Generate Secret:

    $ kubectl create secret generic vault-secret --from-literal=token="s.VgQvaXl8xGFO1RUxAPbPbsfN"
    

    Now modify your deploy/cr.yaml:

    First set the secrets.encryptionKey key to the name of your Secret created on the previous step. Then Add Vault-specific options to the replsets.configuration, replsets.nonvoting.configuration, and sharding.configsvrReplSet.configuration keys, using the following template:

    ...
    configuration: |
      ...
      security:
        enableEncryption: true
        vault:
          serverName: vault
          port: 8200
          tokenFile: /etc/mongodb-vault/token
          secret: secret/data/dc/<cluster name>/<path>
          disableTLSForTesting: true
        ...
    

    Generate Secret, using the path to your ca.crt certificate instead of the <path to CA> placeholder (see the Operator TLS guide, if needed):

    kubectl create secret generic vault-secret --from-literal=token="s.VgQvaXl8xGFO1RUxAPbPbsfN" --from-file=ca.crt=<path to CA>/ca.crt
    

    Now modify your deploy/cr.yaml:

    First set the secrets.encryptionKey key to the name of your Secret created on the previous step. Then Add Vault-specific options to the replsets.configuration, replsets.nonvoting.configuration, and sharding.configsvrReplSet.configuration keys, using the following template:

    ...
    configuration: |
      ...
      security:
        enableEncryption: true
        vault:
          serverName: vault
          port: 8200
          tokenFile: /etc/mongodb-vault/token
          secret: secret/data/dc/<cluster name>/<path>
          serverCAFile: /etc/mongodb-vault/ca.crt
        ...
    

    While adding options, modify this template as follows: * substitute the <cluster name> placeholder with your real cluster name, * substitute the placeholder with rs0 when adding options to replsets.configuration and replsets.nonvoting.configuration, * substitute the placeholder with cfg when adding options to sharding.configsvrReplSet.configuration.

    Finally, apply your modified cr.yaml as usual:

    $ kubectl deploy -f deploy/cr.yaml
    
  3. To verify that everything was configured properly, use the following log filtering command (substitute the <cluster name> and <namespace> placeholders with your real cluster name and namespace):

    $ kubectl logs <cluster name>-rs0-0 -c mongod -n <namespace> | grep -i "Encryption keys DB is initialized successfully"
    

More details on how to install and configure Vault can be found in the official documentation.


Last update: 2022-11-03