Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client-side encrypted snapshot repository (feature flag) #66773

Merged
merged 19 commits into from
Dec 23, 2020

Conversation

albertzaharovits
Copy link
Contributor

@albertzaharovits albertzaharovits commented Dec 23, 2020

The client-side encrypted repository is a new type of snapshot repository that
internally delegates to the regular variants of snapshot repositories (of types
Azure, S3, GCS, FS, and maybe others but not yet tested). After the encrypted
repository is set up, it is transparent to the snapshot and restore APIs (i.e. all
snapshots stored in the encrypted repository are encrypted, no other parameters
required).
The encrypted repository is protected by a password stored on every node's
keystore (which must be the same across the nodes).
The password is used to generate a key encrytion key (KEK), using the PBKDF2
function, which is used to encrypt (using the AES Wrap algorithm) other
symmetric keys (referred to as DEK - data encryption keys), which themselves
are generated randomly, and which are ultimately used to encrypt the snapshot
blobs.

For example, here is how to set up an encrypted FS repository:

  1. make sure that the cluster runs under at least a "platinum" license
    (simplest test configuration is to put xpack.license.self_generated.type: "trial"
    in the elasticsearch.yml file)
  2. identical to the un-encrypted FS repository, specify the mount point of the
    shared FS in the elasticsearch.yml conf file (on all the cluster nodes),
    e.g. path.repo: ["/tmp/repo"]
  3. store the repository password inside the elasticsearch.keystore, on every cluster node.
    In order to support changing password on existing repository (implemented in a follow-up),
    the password itself must be names, e.g. for the "test_enc_key" repository password name:
    ./bin/elasticsearch-keystore add repository.encrypted.test_enc_pass.password
    type in the password
  4. start up the cluster and create the new encrypted FS repository, named "test_enc", by calling:
    curl -X PUT "localhost:9200/_snapshot/test_enc?pretty" -H 'Content-Type: application/json' -d' { "type": "encrypted", "settings": { "location": "/tmp/repo/enc", "delegate_type": "fs", "password_name": "test_enc_pass" } } '
  5. the snapshot and restore APIs work unmodified when they refer to this new repository, e.g.
    curl -X PUT "localhost:9200/_snapshot/test_enc/snapshot_1?wait_for_completion=true&pretty"

Related: #49896 #41910 #50846 #48221 #65768

This adds a new bare snapshot repository project which contains the classes implementing encryption (and decryption) input stream decorators that support mark and reset.

Relates #48221 , #46170
This builds upon the data encryption streams from #49896
to create an encrypted snapshot repository.
The repository encryption works with the following existing repository types:
FS, Azure, S3, GCS (possibly works with HDFS and URL, but these are not tested).
The encrypted repository is protected by a password stored on every node's keystore.
The repository keys (KEK - key encryption key) are generated from the password
using the PBKDF2 function, and are used to encrypt (using the AES Wrap algorithm)
other symmetric keys (referred to as DEK - data encryption keys) which are themselves
used to encrypt the blobs of the regular snapshot.

The platinum or enterprise licenses are required to snapshot to the encrypted repository,
but no license is required to list or restore already encrypted snapshots.
The encrypted repository plugin only adds the new repository plugin factory
if the feature flag `es.encrypted_repository_feature_flag_registered` is toggled.
Encrypted snapshots are available on active PLATINUM and ENTERPRISE license modes.
Listing encrypted repositories, as well as restoring and deleting encrypted snapshots is still
permitted after the license expires or is downgraded, to avoid a data hostage situation.

This PR updates the last usage time stamp of the encrypted snapshots feature to the creation
time of the most recent encrypted snapshot.
@albertzaharovits albertzaharovits self-assigned this Dec 23, 2020
@albertzaharovits albertzaharovits changed the title Repository encrypted client side Client-side encrypted snapshot repository (feature flag) Dec 23, 2020
@albertzaharovits albertzaharovits added :Security/Security Security issues without another label v7.12.0 v8.0.0 >non-issue :Distributed Coordination/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs labels Dec 23, 2020
@albertzaharovits albertzaharovits marked this pull request as ready for review December 23, 2020 21:35
@elasticmachine elasticmachine added Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. Team:Security Meta label for security team labels Dec 23, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

@albertzaharovits
Copy link
Contributor Author

albertzaharovits commented Dec 23, 2020

Since this is a merge of a feature branch, where all the PRs (excluding nits, compilation and test fixes) contained on the feature branch have been independently reviewed, I'm going to merge this without asking for reviews again.

Because this is merged behind a feature flag, I'm going to label this as >non-issue, as opposed to >feature, because
the feature is not yet available in regular (non-snapshot) builds.

@albertzaharovits albertzaharovits merged commit cd72f45 into master Dec 23, 2020
@albertzaharovits albertzaharovits deleted the repository-encrypted-client-side branch December 23, 2020 21:47
albertzaharovits added a commit to albertzaharovits/elasticsearch that referenced this pull request Dec 23, 2020
The client-side encrypted repository is a new type of snapshot repository that
internally delegates to the regular variants of snapshot repositories (of types
Azure, S3, GCS, FS, and maybe others but not yet tested). After the encrypted
repository is set up, it is transparent to the snapshot and restore APIs (i.e. all
snapshots stored in the encrypted repository are encrypted, no other parameters
required).
The encrypted repository is protected by a password stored on every node's
keystore (which must be the same across the nodes).
The password is used to generate a key encrytion key (KEK), using the PBKDF2
function, which is used to encrypt (using the AES Wrap algorithm) other
symmetric keys (referred to as DEK - data encryption keys), which themselves
are generated randomly, and which are ultimately used to encrypt the snapshot
blobs.

For example, here is how to set up an encrypted  FS repository:
------
 1) make sure that the cluster runs under at least a "platinum" license
(simplest test configuration is to put `xpack.license.self_generated.type: "trial"`
in the elasticsearch.yml file)
 2) identical to the un-encrypted FS repository, specify the mount point of the
shared FS in the elasticsearch.yml conf file (on all the cluster nodes),
e.g. `path.repo: ["/tmp/repo"]`
 3) store the repository password inside the elasticsearch.keystore, *on every cluster node*.
In order to support changing password on existing repository (implemented in a follow-up),
the password itself must be names, e.g. for the "test_enc_key" repository password name:
`./bin/elasticsearch-keystore add repository.encrypted.test_enc_pass.password`
*type in the password*
4) start up the cluster and create the new encrypted FS repository, named "test_enc", by calling:
`
curl -X PUT "localhost:9200/_snapshot/test_enc?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "encrypted",
  "settings": {
    "location": "/tmp/repo/enc",
    "delegate_type": "fs",
    "password_name": "test_enc_pass"
  }
}
'
`
5) the snapshot and restore APIs work unmodified when they refer to this new repository, e.g.
` curl -X PUT "localhost:9200/_snapshot/test_enc/snapshot_1?wait_for_completion=true"`

Related: elastic#49896 elastic#41910 elastic#50846 elastic#48221 elastic#65768
albertzaharovits added a commit that referenced this pull request Dec 28, 2020
The client-side encrypted repository is a new type of snapshot repository that
internally delegates to the regular variants of snapshot repositories (of types
Azure, S3, GCS, FS, and maybe others but not yet tested). After the encrypted
repository is set up, it is transparent to the snapshot and restore APIs (i.e. all
snapshots stored in the encrypted repository are encrypted, no other parameters
required).
The encrypted repository is protected by a password stored on every node's
keystore (which must be the same across the nodes).
The password is used to generate a key encrytion key (KEK), using the PBKDF2
function, which is used to encrypt (using the AES Wrap algorithm) other
symmetric keys (referred to as DEK - data encryption keys), which themselves
are generated randomly, and which are ultimately used to encrypt the snapshot
blobs.

For example, here is how to set up an encrypted  FS repository:
------
 1) make sure that the cluster runs under at least a "platinum" license
(simplest test configuration is to put `xpack.license.self_generated.type: "trial"`
in the elasticsearch.yml file)
 2) identical to the un-encrypted FS repository, specify the mount point of the
shared FS in the elasticsearch.yml conf file (on all the cluster nodes),
e.g. `path.repo: ["/tmp/repo"]`
 3) store the repository password inside the elasticsearch.keystore, *on every cluster node*.
In order to support changing password on existing repository (implemented in a follow-up),
the password itself must be names, e.g. for the "test_enc_key" repository password name:
`./bin/elasticsearch-keystore add repository.encrypted.test_enc_pass.password`
*type in the password*
4) start up the cluster and create the new encrypted FS repository, named "test_enc", by calling:
`
curl -X PUT "localhost:9200/_snapshot/test_enc?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "encrypted",
  "settings": {
    "location": "/tmp/repo/enc",
    "delegate_type": "fs",
    "password_name": "test_enc_pass"
  }
}
'
`
5) the snapshot and restore APIs work unmodified when they refer to this new repository, e.g.
` curl -X PUT "localhost:9200/_snapshot/test_enc/snapshot_1?wait_for_completion=true"`

Related: #49896 #41910 #50846 #48221 #65768
@jbnjohnathan
Copy link

What happened to this feature?

Trying it on v8 seems to indicate its not implemented, and I cannot find any references in the documentation.

repository type [encrypted] does not exist

@albertzaharovits
Copy link
Contributor Author

@jbnjohnathan

Unfortunately this was abandoned before reaching the maturity level for functionality required for general availability.

Could you maybe share any details on the setup you were looking to implement, in order to help us design for it when we will resume work?

Information such as:

  • what type of ES snapshot repository were you planning to encrypt (cloud providers, or shared file-system)
  • any requirements for encryption (e.g. is it ok if the encrypted snapshot exposes some metadata, such as index names and sizes, rough data sizes of snapshots/indices)
  • how are the encryption keys generated/stored to be accessed by ES (e.g. do you use a separate service for it like vault, or local node disk is OK)
  • how would the process of rotating the keys look like, if you'd thought about it (e.g. is unavailability of the repository permitted while the rotation is in-progress?)
    Is very valuable to us.

Lastly, what are you going to use instead given that ES does not support it today?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Distributed Coordination/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs >non-issue :Security/Security Security issues without another label Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. Team:Security Meta label for security team v7.12.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants