diff --git a/specs/rocky/support-image-signature-verification.rst b/specs/rocky/support-image-signature-verification.rst new file mode 100644 index 00000000..8510315f --- /dev/null +++ b/specs/rocky/support-image-signature-verification.rst @@ -0,0 +1,373 @@ +.. + This work is licensed under a Creative Commons Attribution 3.0 Unported + License. + + http://creativecommons.org/licenses/by/3.0/legalcode + +==================================== +Support Image Signature Verification +==================================== + +https://blueprints.launchpad.net/cinder/+spec/cinder-support-image-signing + +Cinder currently does not support signature validation of downloaded signed +images. Equipping Cinder with the ability to validate image signatures will +provide end users with stronger assurances of the integrity of the image data +they are using to create volumes. This change will use the same data model for +image metadata as the accompanying functionality in Glance, which will allow +the end user to sign images and verify these image signatures upon +upload `[1]`_. + +Problem description +=================== + +Previously, OpenStack's protection against unexpected modification of images +was limited to verifying an MD5 checksum. While this may be sufficient for +protecting against accidental modifications, MD5 is a hash function, not an +authentication primitive `[2]`_, and thus provides no protection against +deliberate, malicious modification of images. An image could potentially be +modified in transit, such as when it is uploaded to Glance or transferred to +Cinder. An image that is modified could include malicious code. + +Currently, Glance has support for image signature verification upon upload, +but Cinder does not support the feature to ensure the integrity of the image +data before using it. Providing support for signature verification would allow +Cinder to verify the signature before creating volume from image. This feature +will secure OpenStack against the following attack scenarios: + +* Man-in-the-Middle Attack - An adversary with access to the network between + Cinder and Glance is altering image data as Cinder downloads the data from + Glance. The adversary is potentially incorporating malware into the image + and/or altering the image metadata. + +* Untrusted Glance - In a hybrid cloud deployment, Glance is hosted on + machines which are located in a physically insecure location or is hosted by + a company with limited security infrastructure. Adversaries may be able to + compromise the integrity of Glance and/or the integrity of images stored by + Glance through physical access to the host machines or through poor network + security on the part of the company hosting Glance. + +Please note that our threat model considers only threats to the integrity of +images while they are in transit between the end user and Glance, while they +are at rest in Glance and while they are in transit between Glance and Cinder. +This threat model does not include, and this feature therefore does not +address, threats to the integrity, availability, or confidentiality of Cinder. + +Use Cases +========= + +* A user wants a high degree of assurance that a customized image which they + have uploaded to Glance has not been accidentally or maliciously modified + prior to creating a volume from the image. + +With this proposed change, Cinder will verify the signature of a signed image +while downloading that image. If the image signature cannot be verified, then +Cinder will not create a volume from the image and instead place the volume +into an error state. The user will begin to use this feature by uploading the +image and the image signature metadata to Glance via the Glance API's +image-create method. The required image signature metadata properties are as +follows: + +* img_signature - A string representation of the base 64 encoding of the + signature of the image data. + +* img_signature_hash_method - A string designating the hash method used for + signing. Currently, the supported values are SHA-224, SHA-256, SHA-384 and + SHA-512. MD5 and other cryptographically weak hash methods will not be + supported for this field. Any image signed with an unsupported hash + algorithm will not pass validation. + +* img_signature_key_type - A string designating the signature scheme used to + generate the signature. For more detail on which are currently supported, + please check Glance's documentation `[7]`_. + +* img_signature_certificate_uuid - A string encoding the certificate + uuid used to retrieve the certificate from the key manager. + +The image verification functionality in Glance uses the +cursive.signature_utils module to verify this signature metadata before +storing the image. If the signature is not valid or the metadata is +incomplete, this API method will return a 400 error status and put +the image into a "killed" state. Note that, if the signature metadata +is simply not present, the image will be stored as it would normally. + +The user would then create a volume from this image using the Cinder API's +volume create method. If the verify_glance_signatures flag in cinder.conf is +set to 'True', Cinder will call out to Glance for the image's properties, +which include the properties necessary for image signature verification. +Cinder will pass the image data and image properties to the signature +verification module, which will verify the signature. If signature +verification fails, or if the image signature metadata is either incomplete +or absent, creating volume from the image will fail and Cinder will log an +exception. If signature verification succeeds, Cinder will create volume +from the image and log a message indicating that image signature verification +succeeded along with detailed information about the signing certificate. + +Proposed change +=============== + +Since Nova has implemented this feature and all of the verification process +has been moved into ``cursive`` module `[4]`_, it's more convenient to support +this in Cinder now. + +**Verify image signature with certificate** + +We propose an initial implementation by incorporating ``cursive`` into +Cinder's control flow for Creating volumes from images, and use new +configuration ``verify_glance_signatures`` to turn this on or off. +Initially it will have two options (default is ``enabled``): + +1. ``enabled``: verify when image has complete signature metadata. +2. ``disabled``: verification is turned off. + +**NOTE**: We have discussed to add ``required`` option to introduce a +strict mode on verification, but this can't be guaranteed as we can't +do verification when image volume is cloned in backend. Strict mode will +still be considered when we can cover every approach. + +Upon downloading an image, Cinder will both check the new configuration +flag and image's metadata. If needs, the module will perform image signature +verification using image properties passed to Cinder by Glance. If this fails, +or if the image signature metadata is incomplete or missing, Cinder will not +create the volume from the image. Instead, Cinder will throw an exception and +log an error. If the signature verification succeeds, Cinder will proceed with +creating the volume. The code sample is below:: + + if CONF.glance.verify_glance_signatures != 'disabled': + verifier = None + image_meta_dict = self.show(context, image_id, + include_locations=False) + image_meta = objects.ImageMeta.from_dict(image_meta_dict) + img_signature = image_meta.properties.get('img_signature') + img_sig_hash_method = image_meta.properties.get( + 'img_signature_hash_method' + ) + img_sig_cert_uuid = image_meta.properties.get( + 'img_signature_certificate_uuid' + ) + img_sig_key_type = image_meta.properties.get( + 'img_signature_key_type' + ) + try: + verifier = signature_utils.get_verifier( + context=context, + img_signature_certificate_uuid=img_sig_cert_uuid, + img_signature_hash_method=img_sig_hash_method, + img_signature=img_signature, + img_signature_key_type=img_sig_key_type, + ) + except cursive_exception.SignatureVerificationError: + #Image signature verification failed + # Collect image data + try: + if verifier: + verifier.verify() + except cryptography.exceptions.InvalidSignature: + #Image signature verification failed + +**NOTE**: We will try different approaches when +creating volume from images, so we have to mention +this feature will not cover every approach especially +when volume is created at backend. + +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 regardless of configuration option and +provided signature metadata, in order not to confuse end users, +we will add verification flag ``signature_verified`` in volume's +image metadata when creating from image. + +**Verify certificate with trusted certificates** + +This feature tries to find a way to determine if the certificate +used to generate and verify that signature is a certificate that +is trusted by the user, we could find more detail in Nova spec `[5]`_. +In short, within that feature end user can also validate the image's +certificate with the given trusted certificates (specified via API +or config option). +Considering the feature is in the process of being added to Nova +now, we will follow this up with another spec when it's merged +into Nova for the purpose of consistency. + +Alternatives +------------ + +An alternative to signing the image's data directly is to support signatures +which are created by signing a hash of the image data. This introduces +unnecessary complexity to the feature by requiring an additonal hashing stage +and an additional metadata option. Due to the Glance community's performance +concerns associated with hashing image data, the developers initially pursued +an implementation which produced the signature by signing an MD5 checksum +which was already computed by Glance. This approach was rejected by the Nova +community due to the security weaknesses of MD5 and the unnecessary complexity +of performing a hashing operation twice and maintaining information about both +hash algorithms. + +An alternative to using certificates for signing and signature verification +would be to use a public key. However, this approach presents the significant +weakness that an attacker could generate their own public key in the key +manager, use this to sign a tampered image, and pass the reference to their +public key to Cinder along with their signed image. Alternatively, the use of +certificates provides a means of attributing such attacks to the certificate +owner, and follows common cryptographic standards by placing the root of trust +at the certificate authority. + +An alternative to using the verify_glance_signatures configuration flag to +specify that Cinder should perform image signature verification is to use +a "verify_glance_signatures" type-key for a volume type to specify that +individual volume should be created from signed images. The user, when using +the Cinder CLI to create a volume from image, would specify a volume type +which includes a type-key "verify_glance_signatures=True" to indicate that +image signature verification should occur as part of the control flow for +creating the volume. This may be added in a later change, but will not be +included in the initial implementation. If added, the +"verify_glance_signatures" type-key option will work alongside the +configuration option approach. In this case, Cinder would perform image +signature verification if either the configuration flag is set, or if the user +has specified creating a volume of the volume type which includes +"verify_glance_signatures=True" type-key. + +Another alternative to using the verify_glance_signatures configuration flag +to specify that Cinder should perform image signature verification is amending +the Cinder create command to accept an additional parameter specifying whether +image signature verification should occur. This may be added in a later +change, but will not be included in the initial implementation. If added, the +additional parameter will work alongside the configuration option approach. +In this case, Cinder would perform image signature verification if either the +configuration flag is set, or if the user has specified creating a volume of +the additional parameter. + +We maybe only need to choose one of the above two alternatives. + +Data model impact +----------------- + +The accompanying work in Glance introduced additional Glance image properties +necessary for image signing. The initial implementation in Cinder will +introduce a configuration flag indicating whether Cinder should perform image +signature verification before booting an image. + +REST API impact +--------------- + +None + +Security impact +--------------- + +Cinder currently lacks a mechanism to validate images prior to creating +volumes from them. The checksum included with an image protects against +accidental modifications but provides little protection against an adversary +with access to Glance or to the communication network between Cinder and +Glance. This feature facilitates the creation of a logical trust boundary +between Cinder and Glance; this trust boundary permits the end user to have +high assurance that Cinder is creating a volume from an image signed by a +trusted user. + +Although Cinder will use certificates to perform this task, the certificates +will be stored by a key manager and accessed via Castellan. + +Notifications impact +-------------------- + +This change will involve adding log messages to indicate the success or +failure of signature verification and creation. + +A later change will involve notifying the user about failure in case signature +verification fails, this will use async error notification feature `[3]`_. + +Other end user impact +--------------------- + +If the verification of a signature fails, then Cinder will not create a +volume from the image, and an error message will be logged and recorded. +The user can get the error messages through the log file or CLI command, +and know the reason for the error. In this case, the user will have to +edit the image's metadata through the Glance API, or the Horizon interface; +or reinitiate an upload of the image to Glance with the correct signature +metadata in order to create a volume from the image. + +Performance Impact +------------------ + +This feature will only be used if the verify_glance_signatures configuration +flag is set. + +When signature verification occurs there will be latency as a result of +retrieving certificates from the key manager through the Castellan interface. +There will also be CPU overhead associated with hashing the image data and +decrypting a signature using a public key. + +Other deployer impact +--------------------- + +We will recommend you deploy Barbican service `[6]`_ to store your +certificate information as other projects suggest, although you can integrate +any other secret manager service via Castellan `[8]`_. + + +Developer impact +---------------- + +None + + +Implementation +============== + +Assignee(s) +----------- + +Primary assignee: + ji-xuepeng + TommyLike(tommylikehu@gmail.com) + +Other contributors: + None + +Work Items +---------- + +The feature will be implemented in the following stages: + +* Add functionality to Cinder which calls the ``cursive`` module when Cinder + downloads a Glance image and the verify_glance_signatures configuration flag + is set. + +* Generate notification messages at the time of failure for signature + verification. + +Dependencies +============ + +None + +Testing +======= + +Unit tests and also, tempest tests will be added into +barbican-tempest-plugin to cover the case of create +volume from signed image. + + +Documentation Impact +==================== + +Instructions for how to use this functionality will need to be documented. + + +References +========== + +Cryptography API: https://pypi.python.org/pypi/cryptography/0.2.2 + +_`[1]` https://review.openstack.org/#/c/252462/ +_`[2]` https://en.wikipedia.org/wiki/MD5#Security +_`[3]` https://blueprints.launchpad.net/cinder/+spec/summarymessage +_`[4]` https://git.openstack.org/cgit/openstack/cursive +_`[5]` http://specs.openstack.org/openstack/nova-specs/specs/queens/approved/nova-validate-certificates.html +_`[6]` https://docs.openstack.org/barbican/latest/ +_`[7]` https://docs.openstack.org/glance/pike/user/signature.html +_`[8]` https://wiki.openstack.org/wiki/Castellan