]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/kms/kmip - document configuration for a new feature: kmip kms 33996/head
authorMarcus Watts <mwatts@redhat.com>
Wed, 3 Feb 2021 19:26:46 +0000 (14:26 -0500)
committerMarcus Watts <mwatts@redhat.com>
Thu, 4 Mar 2021 00:14:10 +0000 (19:14 -0500)
I've written up a brief description of using kmip
with ceph.  Major features:
* ceph configuration.
* making keys with a "paste-in" python script.
* pointers to PyKMIP and IBM SKLM.

Signed-off-by: Marcus Watts <mwatts@redhat.com>
doc/radosgw/encryption.rst
doc/radosgw/index.rst
doc/radosgw/kmip.rst [new file with mode: 0644]

index 124b57b216969dc585ce1c24da9ab67bb22ca4ca..07fd60ac5d12449c8b2db17564e4d1be68dde1b4 100644 (file)
@@ -37,10 +37,11 @@ or decrypt data.
 
 This is implemented in S3 according to the `Amazon SSE-KMS`_ specification.
 
-In principle, any key management service could be used here, but currently
-only integration with `Barbican`_ and `Vault`_ are implemented.
+In principle, any key management service could be used here.  Currently
+integration with `Barbican`_, `Vault`_, and `KMIP`_ are implemented.
 
-See `OpenStack Barbican Integration`_ and `HashiCorp Vault Integration`_.
+See `OpenStack Barbican Integration`_, `HashiCorp Vault Integration`_,
+and `KMIP Integration`_.
 
 Automatic Encryption (for testing only)
 =======================================
@@ -61,5 +62,7 @@ The configuration expects a base64-encoded 256 bit key. For example::
 .. _Amazon SSE-KMS: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html
 .. _Barbican: https://wiki.openstack.org/wiki/Barbican
 .. _Vault: https://www.vaultproject.io/docs/
+.. _KMIP: http://www.oasis-open.org/committees/kmip/
 .. _OpenStack Barbican Integration: ../barbican
 .. _HashiCorp Vault Integration: ../vault
+.. _KMIP Integration: ../kmip
index 5d4ab692df135bbfc90699907ec373a40173210b..e9d30a43281960ef3e493a62f1e758203414fba3 100644 (file)
@@ -56,6 +56,7 @@ you may write data with one API and retrieve it with the other.
    OpenStack Keystone Integration <keystone>
    OpenStack Barbican Integration <barbican>
    HashiCorp Vault Integration <vault>
+   KMIP Integration <kmip>
    Open Policy Agent Integration <opa>
    Multi-tenancy <multitenancy>
    Compression <compression>
diff --git a/doc/radosgw/kmip.rst b/doc/radosgw/kmip.rst
new file mode 100644 (file)
index 0000000..9888971
--- /dev/null
@@ -0,0 +1,219 @@
+================
+KMIP Integration
+================
+
+`KMIP`_ can be used as a secure key management service for
+`Server-Side Encryption`_ (SSE-KMS).
+
+.. ditaa::
+
+           +---------+       +---------+        +------+      +-------+
+           |  Client |       | RadosGW |        | KMIP |      |  OSD  |
+           +---------+       +---------+        +------+      +-------+
+                | create secret   |                 |             |
+                | key for key ID  |                 |             |
+                |-----------------+---------------->|             |
+                |                 |                 |             |
+                | upload object   |                 |             |
+                | with key ID     |                 |             |
+                |---------------->| request secret  |             |
+                |                 | key for key ID  |             |
+                |                 |---------------->|             |
+                |                 |<----------------|             |
+                |                 | return secret   |             |
+                |                 | key             |             |
+                |                 |                 |             |
+                |                 | encrypt object  |             |
+                |                 | with secret key |             |
+                |                 |--------------+  |             |
+                |                 |              |  |             |
+                |                 |<-------------+  |             |
+                |                 |                 |             |
+                |                 | store encrypted |             |
+                |                 | object          |             |
+                |                 |------------------------------>|
+
+#. `Setting KMIP Access for Ceph`_
+#. `Creating Keys in KMIP`_
+#. `Configure the Ceph Object Gateway`_
+#. `Upload object`_
+
+Before you can use KMIP with ceph, you will need to do three things.
+You will need to associate ceph with client information in KMIP,
+and configure ceph to use that client information.
+You will also need to create 1 or more keys in KMIP.
+
+Setting KMIP Access for Ceph
+============================
+
+Setting up Ceph in KMIP is very dependent on the mechanism(s) supported
+by your implementation of KMIP.  Two implementations are described
+here,
+
+1. `IBM Security Guardium Key Lifecycle Manager (SKLM)`__.  This is a well
+   supported commercial product.
+
+__ SKLM_
+
+2. PyKMIP_.  This is a small python project, suitable for experimental
+   and testing use only.
+
+Using IBM SKLM
+--------------
+
+IBM SKLM__ supports client authentication using certificates.
+Certificates may either be self-signed certificates created,
+for instance, using openssl, or certificates may be created
+using SKLM.  Ceph should then be configured (see below) to
+use KMIP and an attempt made to use it.  This will fail,
+but it will leave an "untrusted client device certificate" in SKLM.
+This can be then upgraded to a registered client using the web
+interface to complete the registration process.
+
+__ SKLM_
+
+Find untrusted clients under ``Advanced Configuration``,
+``Client Device Communication Certificates``.  Select
+``Modify SSL/KMIP Certificates for Clients``, then toggle the flag
+``allow the server to trust this certificate and communicate...``.
+
+Using PyKMIP 
+------------
+
+PyKMIP_ has no special registration process, it simply
+trusts the certificate.  However, the certificate has to
+be issued by a certificate authority that is trusted by
+pykmip.  PyKMIP also prefers that the certificate contain
+an extension for "extended key usage".  However, that
+can be defeated by specifying ``enable_tls_client_auth=False``
+in the server configuration.
+
+Creating Keys in KMIP
+=====================
+
+Some KMIP implementations come with a web interface or other
+administrative tools to create and manage keys.  Refer to your
+documentation on that if you wish to use it.  The KMIP protocol can also
+be used to create and manage keys.  PyKMIP comes with a python client
+library that can be used this way.
+
+In preparation to using the pykmip client, you'll need to have a valid
+kmip client key & certificate, such as the one you created for ceph.
+
+Next, you'll then need to download and install it::
+
+  virtualenv $HOME/my-kmip-env
+  source $HOME/my-kmip-env/bin/activate
+  pip install pykmip
+
+Then you'll need to prepare a configuration file
+for the client, something like this::
+
+   cat <<EOF >$HOME/my-kmip-configuration
+   [client]
+   host={hostname}
+   port=5696
+   certfile={clientcert}
+   keyfile={clientkey}
+   ca_certs={clientca}
+   ssl_version=PROTOCOL_TLSv1_2
+   EOF
+
+You will need to replace {hostname} with the name of your kmip host,
+also replace {clientcert} {clientkey} and {clientca} with pathnames to
+a suitable pem encoded certificate, such as the one you created for
+ceph to use.
+
+Now, you can run this python script directly from
+the shell::
+
+  python
+  from kmip.pie import client
+  from kmip import enums
+  import ssl
+  import os
+  import sys
+  import json
+  c = client.ProxyKmipClient(config_file=os.environ['HOME']+"/my-kmip-configuration")
+
+  while True:
+    l=sys.stdin.readline()
+    keyname=l.strip()
+    if keyname == "": break
+    with c:
+      key_id = c.create(
+         enums.CryptographicAlgorithm.AES,
+         256,
+         operation_policy_name='default',
+         name=keyname,
+         cryptographic_usage_mask=[
+             enums.CryptographicUsageMask.ENCRYPT,
+             enums.CryptographicUsageMask.DECRYPT
+         ]
+      )
+      c.activate(key_id)
+      attrs = c.get_attributes(uid=key_id)
+      r = {}
+      for a in attrs[1]:
+       r[str(a.attribute_name)] = str(a.attribute_value)
+      print (json.dumps(r))
+
+If this is all entered at the shell prompt, python will
+prompt with ">>>" then "..." until the script is read in,
+after which it will read and process names with no prompt
+until a blank line or end of file (^D) is given it, or
+an error occurs.  Of course you can turn this into a regular
+python script if you prefer.
+
+Configure the Ceph Object Gateway
+=================================
+
+Edit the Ceph configuration file to enable Vault as a KMS backend for
+server-side encryption::
+
+  rgw crypt s3 kms backend = kmip
+  rgw crypt kmip ca path: /etc/ceph/kmiproot.crt
+  rgw crypt kmip client cert: /etc/ceph/kmip-client.crt
+  rgw crypt kmip client key: /etc/ceph/private/kmip-client.key
+  rgw crypt kmip kms key template: pykmip-$keyid
+
+You may need to change the paths above to match where
+you actually want to store kmip certificate data.
+
+The kmip key template describes how ceph will modify
+the name given to it before it looks it up
+in kmip.  The default is just "$keyid".
+If you don't want ceph to see all your kmip
+keys, you can use this to limit ceph to just the
+designated subset of your kmip key namespace.
+
+Upload object
+=============
+
+When uploading an object to the Gateway, provide the SSE key ID in the request.
+As an example, for the kv engine, using the AWS command-line client::
+
+  aws --endpoint=http://radosgw:8000 s3 cp plaintext.txt \
+  s3://mybucket/encrypted.txt --sse=aws:kms --sse-kms-key-id mybucketkey
+  
+As an example, for the transit engine, using the AWS command-line client::
+
+  aws --endpoint=http://radosgw:8000 s3 cp plaintext.txt \
+  s3://mybucket/encrypted.txt --sse=aws:kms --sse-kms-key-id mybucketkey
+
+The Object Gateway will fetch the key from Vault, encrypt the object and store
+it in the bucket. Any request to download the object will make the Gateway
+automatically retrieve the correspondent key from Vault and decrypt the object.
+
+Note that the secret will be fetched from kmip using a name constructed
+from the key template, replacing ``$keyid`` with the key provided.
+
+With the ceph configuration given above,
+radosgw would fetch the secret from::
+
+  pykmip-mybucketkey
+
+.. _Server-Side Encryption: ../encryption
+.. _KMIP: http://www.oasis-open.org/committees/kmip/
+.. _SKLM: https://www.ibm.com/products/ibm-security-key-lifecycle-manager
+.. _PyKMIP: https://pykmip.readthedocs.io/en/latest/