diff --git a/specs/version0.5/tls-data-security-1.diag b/specs/version0.5/tls-data-security-1.diag new file mode 100644 index 0000000000..6af9c12cc2 --- /dev/null +++ b/specs/version0.5/tls-data-security-1.diag @@ -0,0 +1,16 @@ +seqdiag { + span_height = 10; + === If Certificate is pre-stored in Barbican === + User => Octavia [label="Create LB with TLS (passing tls_certificate_id)", note="HTTPS", return="202/400/401"] { + Octavia => Barbican [label="Fetch Certificate Container", note="HTTPS", return="Certificate Data"]; + } + === If Certificate is passed directly to Octavia === + User => Octavia [label="Create LB with TLS (passing tls_certificate, tls_private_key, etc)", note="HTTPS", return=" +202/400/401"] { + Octavia => Barbican [label="Store Secrets / Certificate Container", note="HTTPS", return="tls_certificate_id"]; + } + Octavia -> Octavia [label="Store tls_certificate_id"]; + === After certificate handling, in both cases === + Octavia -> Octavia [label="Fetch Amphora from Spare Pool"]; + Octavia => "Amphora API" [label="Configure Amphora", note="HTTPS", return="Update LB Status"]; +} diff --git a/specs/version0.5/tls-data-security-2.diag b/specs/version0.5/tls-data-security-2.diag new file mode 100644 index 0000000000..b98381b4c5 --- /dev/null +++ b/specs/version0.5/tls-data-security-2.diag @@ -0,0 +1,29 @@ +seqdiag { + span_height = 10; + activation = none; + === In Octavia === + Barbican; + Octavia => Nova [label="Create new Amphora", note="include Octavia Controller certificate and IP as Metadata"]; + loop { + Octavia => Nova [label="Poll for ACTIVE Amphora", return="Amphora Management IP"]; + } + Octavia -> Octavia [label="Store Amphora IP"]; + === Meanwhile, in the Amphora === + Amphora -> Amphora [label="Generate private key and CSR"]; + Amphora => Octavia [label="Request Certificate Signing", return = "Signed Certificate"] { + Octavia -> Octavia [label="Verify Amphora by source IP"]; + Octavia => Barbican [label="Process CSR using private CA", return="Signed Certificate"]; + } + Amphora -> Amphora [label="Start Services (API, Heartbeat)"]; + "Amphora Heartbeat" -> Octavia [label="Announce", note="UDP? HTTPS?"] { + Octavia -> Octavia [label="Verify Amphora by source IP (UDP) or certificate (HTTPS)"]; + === If Verification fails === + Octavia -> Octavia [label="Log and Ignore"]; + === If Verification succeeds === + Octavia => "Amphora API" [label="Run Self-test"]; + === If Self-test fails === + Octavia -> Octavia [label="Delete Amphora, retry process"]; + === If Self-test succeeds === + Octavia -> Octavia [label="Add Amphora to standby pool"]; + } +} diff --git a/specs/version0.5/tls-data-security.rst b/specs/version0.5/tls-data-security.rst new file mode 100644 index 0000000000..bc84e097dc --- /dev/null +++ b/specs/version0.5/tls-data-security.rst @@ -0,0 +1,164 @@ +.. + This work is licensed under a Creative Commons Attribution 3.0 Unported + License. + + http://creativecommons.org/licenses/by/3.0/legalcode + +============================== +TLS Data Security and Barbican +============================== +Launchpad blueprint: + +https://blueprints.launchpad.net/octavia/+spec/tls-data-security + +Octavia will have some need of secure storage for TLS related data. This BP is +intended to identify all of the data that needs secure storage, or any other +interaction that will require the use of Barbican or another secure solution. + +Problem description +=================== +1. Octavia will support TLS Termination (including SNI), which will require us +to store and retrieve certificates and private keys from a secure repository. + +2. Octavia will communicate with its Amphorae using TLS, so each Amphora +will need a certificate for the controller to validate. + +3. Octavia will need TLS data for exposing its own API via HTTPS. + +Proposed change +=============== +The initial supported implementation for TLS related functions will be +Barbican, but the interface will be generic such that other implementations +could be created later. + +.. seqdiag:: tls-data-security-1.diag + +1. Create a CertificateManager interface for storing and retrieving certificate +and private key pairs (and intermediate certs / private key passphrase). +Users will pass their TLS data to Octavia in the form of a certificate_id, +which is a reference to their data in some secure service. Octavia will store +that certificate_id for each Listener/SNI and will retrieve the data when +necessary. (Barbican specific: users will need to add Octavia's user account as +an authorized user on the Container and all Secrets [1] so we catch fetch the +data on their behalf.) + +We will need to validate the certificate data (including key and intermediates) +when we initially receive it, and will assume that it remains unchanged for +the lifespan of the LB (in Barbican the data is immutable so this is a safe +assumption, I do not know how well this will work for other services). In the +case of invalid TLS data, we will reject the request with a 400 (if it is an +initial create) or else put the LB into ERROR status (if it is on a failover +event or during some other non-interactive scenario). + +.. seqdiag:: tls-data-security-2.diag + +2. Create a CertificateGenerator interface to generate certificates from CSRs. +When an Amphora spins up, it will generate its own private key and CSR, then +contact the controller and request a signed certificate. The controller will +cause one to be generated [2] and return it to the Amphora (syncronous), which +will configure the Amphora API to listen using that certificate. All future +communications with the Amphora will do client certificate validation based on +our (private) certificate authority. + +If we are unable to generate a certificate for the Amphora, we will respond +with a 503 and the Amphora will be expected to wait some configurable retry +period before trying again. + +(The CertificateManager and CertificateGenerator interfaces are separate +because while Barbican can perform both functions, future implementations +may need to use two distinct services to achieve both.) + +3. The key/cert for the main Octavia API/controller should be maintained +manually by the server operators using whatever configuration management +they choose. We should not need to use a specific external repo for this. +The trusted CA Cert will also need to be retrieved from barbican and manually +loaded in the config. + +Alternatives +------------ +We could skip the interface and just use Barbican directly, but that would be +diverging from what seems to be the accepted Openstack model for Secret Store +integration. + +We could also store everything locally or in the DB, but that isn't a real +option for production systems because it is incredibly insecure (though there +will be a "dummy driver" that operates this way for development purposes). + +Data model impact +----------------- +Nothing new, the models for this should already be in place. Some of the +columns/classes might need to be renamed more generically (currently there is +a tls_container_id column, which would become tls_certificate_id to be more +generic). + +REST API impact +--------------- +There will need to be an API resource in the controller for the Amphora to +use when requesting a certificate. All further API based communication with +the Amphora will take place over HTTPS and validate the certificate of +both the server and the client. + +Security impact +--------------- +Using Barbican is considered secure. + +Notifications impact +-------------------- +None + +Other end user impact +--------------------- +None + +Performance Impact +------------------ +Adding an external touchpoint (a certificate signing service) to the Amphora +spin-up workflow will increase the average time for readying an Amphora. This +shouldn't be a huge problem if the standby-pool size is sufficient for the +particular deployment. + +Other deployer impact +--------------------- +None + +Developer impact +---------------- +None + +Implementation +============== + +Assignee(s) +----------- +Adam Harwell (adam-harwell) + +Work Items +---------- +1. Create CertificateManager interface. + +2. Create CertificateGenerator interface. + +3. Create BarbicanCertificateManager implementation. + +4. Create BarbicanCertificateGenerator implementation. + +5. Create unit tests! + +Dependencies +============ +This script will depend on the OpenStack Barbican project, including some +features that are still only at the blueprint stage. + +Testing +======= +There will be testing. Yes. + +Documentation Impact +==================== +Documentation changes will be primarily internal. + +References +========== +.. line-block:: + [1] https://review.openstack.org/#/c/127353/ + [2] https://review.openstack.org/#/c/129048/