Merge "Support certificate validation"
This commit is contained in:
commit
c114d7a6e7
|
@ -0,0 +1,395 @@
|
|||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
=============================
|
||||
Cinder Certificate Validation
|
||||
=============================
|
||||
|
||||
https://blueprints.launchpad.net/cinder/+spec/certificate-validate
|
||||
|
||||
OpenStack now supports signature verification for signed images. However, it
|
||||
does not support strong certificate validation for certificates used to
|
||||
generate image signatures. Specifically, cinder has no mechanism to identify
|
||||
trusted certificates. While cinder verifies the signature of a signed image
|
||||
using cursive, there is no way to determine if the certificate used to
|
||||
generate and verify that signature is a certificate that is trusted by the
|
||||
user. This change will introduce an addition to the cinder API allowing the
|
||||
user to specify a list of trusted certificates when creating volume from
|
||||
images. These trusted certificates will be used to conduct certificate
|
||||
validation in concert with signature verification in cursive, providing the
|
||||
user confidence in the identity and integrity of the image being created.
|
||||
|
||||
|
||||
Problem description
|
||||
===================
|
||||
|
||||
Cinder is capable of verifying the signature of a signed image by using
|
||||
cursive, the OpenStack signature verification library [1]. Signature
|
||||
verification ensures that unmodified image data is retrieved from glance.
|
||||
However, the validation of the certificate used to generate the signature
|
||||
of the signed image is currently limited to a timestamp validity check,
|
||||
ensuring only that the certificate is valid for use at the time of signature
|
||||
verification. There is no mechanism to ensure that the certificate used is
|
||||
one approved by the end user. An attacker with access to glance could replace
|
||||
a user's signed image with a modified, malicious image signed with the
|
||||
attacker's certificate, stored in the OpenStack deployment's certificate
|
||||
manager. If asked to create volume from the modified image, cinder would
|
||||
retrieve the image and its corresponding certificate, verify the image
|
||||
signature, and build a volume using the malicious image data. Providing
|
||||
support for certificate validation in cursive helps cinder detect this
|
||||
attack scenario and take steps to alert the user of the potential compromise.
|
||||
|
||||
Note that this threat model considers glance to be untrusted and does not
|
||||
include threats to the integrity, availability, or confidentiality of cinder.
|
||||
It assumes that: (1) an attacker has access to the certificate manager and is
|
||||
able to store certificates for use with image signing, and (2) this attacker
|
||||
is unable to access arbitrary certificate public/private key pairs belonging
|
||||
to other users. An attacker with such access would be able to impersonate the
|
||||
user, replacing signed images and perfectly updating the corresponding image
|
||||
signatures and metadata as needed to conceal the attack.
|
||||
|
||||
Use Cases
|
||||
---------
|
||||
|
||||
Cinder users want to ensure that they are creating from images they trust by
|
||||
controlling the set of certificates used to sign their images.
|
||||
|
||||
With this change, a cinder user can specify the identities of trusted
|
||||
certificates when creating volumes from a signed image if
|
||||
signature verification and certificate validation are enabled. One of these
|
||||
trusted certificates is expected to be the signing certificate of the
|
||||
certificate used to generate the image signature.
|
||||
|
||||
With certificate validation enabled, image signature verification will only
|
||||
succeed if the image signing certificate was generated by a trusted
|
||||
certificate. This allows users to place themselves in-the-loop of the
|
||||
signature verification process, requiring valid certificate information for
|
||||
boot to succeed. Note that if the deployment is configured to trust certain
|
||||
certificates that the user isn't aware of, the deployer could still manipulate
|
||||
images in a way that the user wouldn't detect with this feature.
|
||||
|
||||
Proposed change
|
||||
===============
|
||||
|
||||
Supporting certificate validation requires several changes. The initial change
|
||||
adds a pair of new configuration options. The first configuration option,
|
||||
``enable_certificate_validation``, will enable the use of the cursive
|
||||
certificate validation routine when conducting image signature verification
|
||||
(see the fifth change below). This option will only be used if
|
||||
``verify_glance_signatures`` is set to ``enabled`` and will default to
|
||||
``False``. Certificate validation will be performed if this option is
|
||||
set to ``True``.
|
||||
|
||||
The second configuration option, ``default_trusted_certificate_ids``, will
|
||||
contain a list of certificate IDs that are designated as trusted by the
|
||||
cinder deployment. This list of trusted certificate IDs will only be used if
|
||||
certificate validation is enabled and if no trusted certificate IDs were
|
||||
provided by the user (see the second and third changes below). The list should
|
||||
be defined by an administrator as it will be the default set of trusted
|
||||
certificate IDs for the cinder deployment. The default value of this option
|
||||
will be an empty list, requiring a user-provided set of trusted certificate
|
||||
IDs if left empty. If the user does provide a list of trusted certificate IDs,
|
||||
the list of default trusted certificate IDs will be ignored.
|
||||
|
||||
The second change adds a parameter, ``trusted_image_certificates``, to the
|
||||
volume create command of the cinder API. The value of the parameter is an array
|
||||
containing the string IDs of the trusted certificates used to validate the
|
||||
signed image's signing certificate. These IDs are assigned by the certificate
|
||||
manager upon upload of the trusted certificates. Multiple IDs are allowed here
|
||||
to provide flexibility for the user. It may not be feasible for the user to
|
||||
know which specific certificate corresponds to their image. Allowing the user
|
||||
to define a set of trusted certificates removes the need for an
|
||||
image/certificate mapping, simplifying the user experience. When provided,
|
||||
cinder will pass these values to the certificate validation routine in cursive,
|
||||
overriding the default list of trusted certificate IDs (see the second
|
||||
configuration option above). Cursive will use them to fetch the trusted
|
||||
certificates using castellan. If provided, the value of the parameter will be
|
||||
saved in image metadata.
|
||||
|
||||
The third change integrates the certificate verification routine into the
|
||||
signature verification workflow. When the certificate verification routine
|
||||
fetches the image's signing certificate, it builds the verification context
|
||||
using the trusted certificates provided by the user. It then passes the
|
||||
signing certificate through the context for certificate validation. If
|
||||
validation succeeds, signature verification can proceed as normal.
|
||||
If validation fails, signature verification fails as well, the volume is
|
||||
placed in an ERROR state.
|
||||
|
||||
**NOTE**: The corresponding feature [2] has been merged into Cursive already.
|
||||
|
||||
It is possible a silent fail scenario could occur if (1) cinder is not
|
||||
configured to conduct certificate validation, and (2) the user provides
|
||||
trusted certificate IDs expecting certificate validation to occur. In this
|
||||
case, cinder would not conduct certificate validation and would boot the
|
||||
instance, causing the user to believe certificate validation succeeded even
|
||||
though it never happened. To prevent this from happening, the create workflow
|
||||
will be updated to conduct signature and certificate verification if trusted
|
||||
certificate IDs are associated with the create request. This matches
|
||||
the user's expectations and prevents a silent fail scenario from ever
|
||||
occurring. Note here that this override only occurs if the user specifies
|
||||
certificate IDs. The default list of certificate IDs is only used if
|
||||
the feature is enabled and therefore will never trigger the override.
|
||||
|
||||
The fourth change updates the cinderclient to support the
|
||||
trusted_image_certificates parameter for the volume create commands.
|
||||
This includes support for a new environment variable,
|
||||
OS_TRUSTED_CERTIFICATE_IDS, that can be used to define a comma-delimited list
|
||||
of trusted certificate IDs. If the trusted_image_certificates parameter is not
|
||||
used, the client will pull the value of the environment variable and use it
|
||||
instead. This value will be converted into a list before being passed on.
|
||||
|
||||
If the user does not provide a value for the trusted_image_certificates
|
||||
parameter, either explicitly or through the OS_TRUSTED_CERTIFICATE_IDS
|
||||
environment variable, cinder will pull the list of trusted certificate IDs from
|
||||
the default_trusted_certificate_ids configuration option. If this option is
|
||||
left as an empty list, there is no way for nova to obtain a trusted
|
||||
certificate for certificate validation. In this case there would be no way to
|
||||
determine if the image's signing certificate is trusted so signature
|
||||
verification would fail, in turn failing volume creation.
|
||||
|
||||
To be clear, we will verify the image's signature only when image is
|
||||
downloaded from glance and content is copied to volume on host. So when image
|
||||
volume is created via ``clone_image`` or ``clone_image_volume`` we will skip
|
||||
this verification process, in order not to confuse end users, we will also add
|
||||
a flag in volume image metadata to indicate whether we validated the
|
||||
certificates during volume creation, and the service will generate an user
|
||||
message if the certificate validation fails in the backend.
|
||||
|
||||
Note that these trusted certificates are stored in a certificate manager
|
||||
independent of the volume service. For this work, a certificate manager is
|
||||
any service backend supported by castellan that provides management
|
||||
operations for certificates objects. Certificate management is often a
|
||||
subset of the functionality provided by generic key managers, which are
|
||||
capable of managing different types of cryptographic secrets (e.g.,
|
||||
encryption keys, passwords). As of the Pike release, barbican (the OpenStack
|
||||
key management service) is the only OpenStack service that satisfies the
|
||||
requirements for a certificate manager. In the future, any OpenStack or
|
||||
third-party service that is supported by castellan and provides certificate
|
||||
management could be used instead of barbican.
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
||||
An alternative approach to certificate validation here would be to support
|
||||
certificate trust stores, collections of trusted certificates associated with
|
||||
individual users or projects. When creating a new server, the user would
|
||||
specify their trust store as a source of trusted certificates, replacing the
|
||||
list of certificates provided in the trusted_image_certificates parameter.
|
||||
There are many ways to support trust stores, including: a filesystem
|
||||
directory trust store containing trusted certificate files stored locally on
|
||||
the compute host, a metadata/managed resource approach supported under
|
||||
services like nova or keystone, and a container-based secret storage approach
|
||||
supported by services like barbican. While useful in defining collections of
|
||||
trusted certificates, a trust store approach would need to scale for large
|
||||
cloud deployments which may be difficult from a management and maintenance
|
||||
perspective. Trust stores also introduce a new construct that must be
|
||||
trusted by the user, especially if the user is not directly responsible for
|
||||
maintaining their trust store. These restrictions may not be feasible for
|
||||
some cloud deployments.
|
||||
|
||||
An alternative to the user providing trusted certificates, or storing trusted
|
||||
certificates in a trust store(or just a database table), would be to
|
||||
dynamically fetch certificates using information stored in the Private
|
||||
Internet Extension of the signed certificate being validated. This approach
|
||||
allows deployers and users to use signing certificates without needing to
|
||||
pre-fetch all of the root and intermediate certificates required to complete
|
||||
the certificate validation process. However, this approach requires the
|
||||
compute service have persistent network access to all possible certificate
|
||||
repositories where root and intermediate certificates may be stored. In many
|
||||
cases, this will include network access to the public Internet which may not
|
||||
be feasible for a generic deployment.
|
||||
|
||||
An enhanced certificate validation routine would include certificate
|
||||
revocation, supporting commonly used approaches like certificate revocation
|
||||
lists (CRLs) and/or the Online Certificate Status Protocol (OCSP). Supporting
|
||||
certificate revocation would allow the compute service to dynamically
|
||||
determine when certificates become invalid in real time due to compromise,
|
||||
further improving the security of booting signed images. However, supporting
|
||||
certificate revocation involves dynamically fetching and trusting network
|
||||
resources, often under the control and authority of third-parties. This may
|
||||
not be feasible for some deployments. It is possible that certificate
|
||||
revocation could be integrated outside of the compute service, for example
|
||||
within the certificate manager or through another third-party service. This
|
||||
would grant nova the benefits of timely revocation without complicating the
|
||||
signature verification and certificate validation features in nova itself.
|
||||
|
||||
It should be noted here that support for certificate revocation is intended
|
||||
to be added in future work for this feature.
|
||||
|
||||
Data model impact
|
||||
-----------------
|
||||
|
||||
None
|
||||
|
||||
REST API impact
|
||||
---------------
|
||||
|
||||
1. Add a new microversion to support specifying ``trusted_image_certificates``
|
||||
when creating volume::
|
||||
|
||||
POST: /V3/{tenant_id}/volumes
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
"volume": {
|
||||
"size": 1,
|
||||
"name": "image_volume",
|
||||
"imageRef": "CAB56EC2-4BDC-45D4-9898-3F88A7003261",
|
||||
"trusted_image_certificates": [
|
||||
"00000000-0000-0000-0000-000000000000",
|
||||
"11111111-1111-1111-1111-111111111111",
|
||||
"22222222-2222-2222-2222-222222222222"
|
||||
],
|
||||
}
|
||||
|
||||
Note that while in these examples the values in trusted_image_certificates
|
||||
are UUIDs they are not guaranteed to be so. Certificate managers use
|
||||
different ID allocation schemes; while some use strict UUIDs, others use
|
||||
simple incrementing integers or raw hex strings. For this feature, the type
|
||||
of trusted_image_certificates will be an array containing zero or more JSON
|
||||
string values.
|
||||
|
||||
The following is a JSON schema description of the trusted_image_certificates
|
||||
parameter:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
"type": "array",
|
||||
"minItems": 0,
|
||||
"maxItems": 50,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
||||
Note the upper and lower bounds for the number of certificate IDs included
|
||||
in the trusted_image_certificates parameter. If an API call is made for a
|
||||
signed image and exceeds the maximum number of allowed certificate IDs, then
|
||||
the API call will fail.
|
||||
|
||||
API version bump will be required for these changes.
|
||||
|
||||
Security impact
|
||||
---------------
|
||||
|
||||
With the added verification step provided by this feature when enabled, the
|
||||
security of the signed image verification feature is improved.
|
||||
|
||||
Notifications impact
|
||||
--------------------
|
||||
|
||||
None
|
||||
|
||||
Other end user impact
|
||||
---------------------
|
||||
|
||||
With support being added for the OS_TRUSTED_CERTIFICATE_IDS environment
|
||||
variable, users are encouraged to set the variable with the list of trusted
|
||||
certificate IDs through their openrc file, alongside their authentication
|
||||
credentials. The value of the OS_TRUSTED_CERTIFICATE_IDS environment variable
|
||||
is a comma-delimited string of trusted certificate IDs, which will be
|
||||
converted into a list of certificate IDs for the trusted_image_certificates
|
||||
parameter.
|
||||
|
||||
An example openrc file is shown below, using the same trusted certificate IDs
|
||||
as those used in the API example (see REST API Impact above):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
export OS_USERNAME=username
|
||||
export OS_PASSWORD=password
|
||||
export OS_TENANT_NAME=projectName
|
||||
export OS_AUTH_URL=https://identityHost:portNumber/v2.0
|
||||
export OS_TRUSTED_CERTIFICATE_IDS=00000000-0000-0000-0000-000000000000,
|
||||
11111111-1111-1111-1111-111111111111,22222222-2222-2222-2222-222222222222
|
||||
|
||||
Performance Impact
|
||||
------------------
|
||||
|
||||
Cinder will load the user's trusted certificates via cursive every time
|
||||
signature verification is performed. Depending upon the size and number of
|
||||
certificates, and the frequency of signature verification, this could
|
||||
introduce a performance burden on the volume service, such as consuming images
|
||||
from the Cinder image cache. To alleviate this, see "Alternatives" above
|
||||
regarding a persistent certificate trust store and dynamically loading
|
||||
certificates from remote storage.
|
||||
|
||||
Other deployer impact
|
||||
---------------------
|
||||
|
||||
The inclusion of two new configuration options, enable_certificate_validation
|
||||
and default_trusted_certificate_ids, will smooth the transition for
|
||||
deployments looking to enable this feature.
|
||||
|
||||
Developer impact
|
||||
----------------
|
||||
|
||||
None
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Assignee(s)
|
||||
-----------
|
||||
|
||||
Primary assignee:
|
||||
Yikun Jiang(yikunkero@gmail.com)
|
||||
|
||||
Other assignee:
|
||||
tommylikehu(tommylikehu@gmail.com)
|
||||
|
||||
Work Items
|
||||
----------
|
||||
|
||||
* Add two new configuration options, enable_certificate_validation and
|
||||
default_trusted_certificate_ids. The first will enable the use of
|
||||
certificate validation if signature verification is enabled. The second will
|
||||
provide a default list of trusted certificate IDs that can be used if no
|
||||
trusted certificate IDs are provided with the volume request.
|
||||
* Update the existing signature verification workflow in cinder to incorporate
|
||||
certificate validation, using the verify_certificate routine in cursive to
|
||||
validate the signing certificate.
|
||||
* Add a new cinder API parameter, trusted_image_certificates, to the volume
|
||||
create command. The value of this parameter will need to be
|
||||
passed through to the signature verification step when downloading the image
|
||||
from glance.
|
||||
* Update cinderclient to support the trusted_image_certificates parameter.
|
||||
* Update cinderclient to pull the value of the OS_TRUSTED_CERTIFICATE_IDS
|
||||
environment variable when the trusted_image_certificates parameter is not
|
||||
provided by the user.
|
||||
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
None
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
Unit tests will be included to test the functionality implemented in cinder,
|
||||
cinderclient. Tempest tests will also be implemented to test the end-to-end
|
||||
feature across glance and cinder.
|
||||
|
||||
|
||||
Documentation Impact
|
||||
====================
|
||||
|
||||
Documentation on the trusted_image_certificates API parameter and the two
|
||||
new configuration options will need to be added, as will instructions
|
||||
defining the OS_TRUSTED_CERTIFICATE_IDS environment variable and its usage.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] "Cursive." Online: https://launchpad.net/cursive
|
||||
|
||||
[2] "Add certificate validation." https://review.openstack.org/#/c/357202/
|
Loading…
Reference in New Issue