Re-propose LBaaS v2 specs for Kilo

Change-Id: I99ffc106714c03608c985e87156510d1569b455d
This commit is contained in:
Doug Wiegley 2014-12-05 18:34:14 -07:00
parent c697d1d3dd
commit 192004752a
4 changed files with 1402 additions and 0 deletions

View File

@ -0,0 +1,401 @@
==========================================
LBaaS Layer 7 rules
==========================================
Launchpad blueprint:
https://blueprints.launchpad.net/neutron/+spec/lbaas-l7-rules
Layer 7 switching takes its name from the OSI model, indicating that the device
switches requests based on layer 7 (application) data. Layer 7 switching is
also known as "request switching", "application switching", and
"content based routing".
A layer 7 switch presents to the outside world a "virtual server" that accepts
requests on behalf of a number of servers and distributes those requests based
on policies that use application data to determine which server should service
which request. This allows for the application infrastructure to be specifically
tuned/optimized to serve specific types of content. For example, one server can
be tuned to serve only images, another for execution of server-side scripting
languages like PHP and ASP, and another for static content such as HTML, CSS and
JavaScript.
Problem Description
===================
Use Cases:
1. Redirect traffic to a Pool that supports static content (HTML, CSS)
2. Redirect traffic to a Pool that serves images (jpg, png, etc)
Proposed Change
===============
Extend the LBaaS API and support Layer 7 switching.
L7 Entities:
1. L7Rule - Set of attributes that defines which part of the request should
be matched and how it should be matched.
2. L7Policy - A collection of L7Rules. Holds the action that should
be performed when the rules are matched.(Redirect to Pool, Redirect to URL,
Reject). L7Policy holds a Listener id, so a Listner can evaluate a collection
of L7Policies. L7Policy will return 'true' when all of the L7Rules that
belong to this L7Policy are matched. L7Policies under a specific Listener
are ordered and the first l7Policy that returns a match will be executed.
When none of the policies match the request gets forwarded to
listener.default_pool_id
Data Model Impact
-----------------
Model::
+--------------------+ +--------------------+
| Listener | | L7Policy |
+--------------------+ +--------------------+
| | | |
| id | | id |
| other attributes +--------+ action |
| | | pool id |
| | | redirect url |
| | | listener id |
+--------------------+ | index |
| |
| |
+-----------------+--+
|
|
+------------------+--+
| L7Rule |
+---------------------+
| |
| id |
| l7 policy id |
| type |
| compare type |
| key |
| value |
| |
+---------------------+
Two new entities are introduced: L7Rule and L7Policy
The L7Policy is a container of L7Rules.
The L7Policy contains a reference to a Listener
1. L7Rule object Data Model.
+----------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+================+==============+======+=====+=========+
| id | string(36) | NO | PRI | |
+----------------+--------------+------+-----+---------+
| l7_policy_id | string(36) | NO | FK | |
+----------------+--------------+------+-----+---------+
| type | Enum (*) | NO | | |
+----------------+--------------+------+-----+---------+
| compare_type | Enum (*) | NO | | |
+----------------+--------------+------+-----+---------+
| key | string(36) | NO | | |
+----------------+--------------+------+-----+---------+
| value | string(36) | YES | | |
+----------------+--------------+------+-----+---------+
* type values
- Hostname
- Path
- FileType: This is the file extension. Examples: txt, jpg, png, xls
A rule that is looking for text files will look like:
type = FileType, compare_type=EqualTo, value = txt
- Header
- Cookie: This is the value of a specific cookie
A rule that is looking for a cookie named 'department'
with the value starting with 'finance-' will look like:
type = Cookie, compare_type=StartsWith, key = department
value = finance-
* compare_type values
- Regexp
- StartsWith
- EndsWith
- Contains
- EqualTo
- GreaterThan
- LessThan
2. L7Policy object Data Model.
+----------------+--------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+================+==============+======+=====+=========+
| id | string(36) | NO | PRI | |
+----------------+--------------+------+-----+---------+
| listener_id | string(36) | NO | FK | |
+----------------+--------------+------+-----+---------+
| action | Enum (*) | NO | | |
+----------------+--------------+------+-----+---------+
| pool_id | string(36) | YES | | |
+----------------+--------------+------+-----+---------+
| redirect_url | string(256) | YES | | |
+----------------+--------------+------+-----+---------+
| index | int | NO | | |
+----------------+--------------+------+-----+---------+
* action: [Reject,RedirectToURL,RedirectToPool]
* If action is RedirectToURL redirect_url can not be null
* If action is RedirectToPool pool_id can not be null
* Index
- If total policies for this listener is less than index, append to end of
list.
- Index numbering starts with 0
- If policy with same index number exists, insert the new policy at that
index number and increment all policy indexes for this listener with an
equal or higher index value.
- Not specifying an index appends the policy to the list.
REST API Impact
---------------
l7rule-create Create a L7Rule for a given tenant.
Request
POST /v2.0/l7rules
Accept: application/json
.. code-block:: javascript
{
"l7rule":{
"l7_policy_id": "6b96ff0cb17a4b859e1e575d221683c5",
"type":"Header",
"compare_type":"StartsWith",
"key":'department',
"value":"HR"
}
}
Response
.. code-block:: javascript
{
"l7rule":{
"id": "6b96ff0cb17a4b859e1e575d221683d7",
"l7_policy_id": "6b96ff0cb17a4b859e1e575d221683c5",
"type":"Header",
"compare_type":"StartsWith",
"key":'department',
"value":"HR",
"tenant_id":"6b96ff0cb17a4b859e1e575d2216845"
}
}
l7rule-show Show information of a given L7Rule.
Request
GET /v2.0/l7rules/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json
Response
.. code-block:: javascript
{
"l7rule":{
"id": "6b96ff0cb17a4b859e1e575d221683d7",
"l7_policy_id": "6b96ff0cb17a4b859e1e575d221683c5",
"type":"Header",
"compare_type":"StartsWith",
"key":'department',
"value":"HR"
"tenant_id":"6b96ff0cb17a4b859e1e575d2216845"
}
}
l7rule-delete Delete a given L7Rule.
Request
DELETE /v2.0/l7rules/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json
l7policy-create Create a L7Policy for a given tenant.
POST /v2.0/l7policies
Accept: application/json
.. code-block:: javascript
{
"l7policy":{
"listener_id": "6b96ff0cb17a4b859e1e575d221683c5",
"action":"RedirectToPool",
"pool_id":6b96ff0cb17a4b859e1e575d22168399,
"index": 2
}
}
Response
.. code-block:: javascript
{
"l7policy":{
"id": "6b96ff0cb17a4b859e1e575d221683d7",
"listener_id": "6b96ff0cb17a4b859e1e575d221683c5",
"action":"RedirectToPool",
"pool_id":6b96ff0cb17a4b859e1e575d22168399,
"tenant_id":"6b96ff0cb17a4b859e1e575d2216845",
"index": 2
}
}
l7policy-show Show information of a given L7Policy.
Request
GET /v2.0/l7policies/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json
Response
.. code-block:: javascript
{
"l7policy":{
"id": "6b96ff0cb17a4b859e1e575d221683d7",
"listener_id": "6b96ff0cb17a4b859e1e575d221683c5",
"action":"RedirectToPool",
"pool_id":6b96ff0cb17a4b859e1e575d22168399,
"tenant_id":"6b96ff0cb17a4b859e1e575d2216845",
"index": 2
}
}
l7policy-delete Delete a given L7Policy.
Request
DELETE /v2.0/l7policies/6b96ff0cb17a4b859e1e575d221683d7
Accept: application/json
Security Impact
---------------
None.
Notifications Impact
--------------------
None.
Other End User Impact
---------------------
None.
Performance Impact
------------------
None.
IPv6 Impact
-----------
None
Other Deployer Impact
---------------------
None.
Developer Impact
----------------
None.
Community Impact
----------------
This change has been in review since Juno. Much discussion has taken place
over IRC and the mailing list.
Alternatives
------------
None.
Implementation
==============
Assignee(s)
-----------
Primary assignee:
https://launchpad.net/~avishayb
Other contributors:
**TBD**
Work Items
----------
* REST API
* DB Schema
* LBaaS plugin and driver API
* CLI update
Dependencies
============
* Depends on the new LBaaS model https://review.openstack.org/#/c/89903/
Testing
=======
Tempest Tests
--------------
* DB mixin and schema tests
* LBaaS Plugin with mocked driver end-to-end tests
* Tempest tests
* CLI tests
Functional Tests
----------------
* Specific driver tests for each existing driver supporting L7 switching
API Tests
---------
* REST API and attributes validation tests
Documentation Impact
====================
User Documentation
-------------------
* Neutron CLI should be modified with L7Rule and L7Policy entities
Developer Documentation
-----------------------
* Neutron API should be modified with L7Rule and L7Policy entities
References
==========
https://wiki.openstack.org/wiki/Neutron/LBaaS/l7

View File

@ -0,0 +1,219 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
==========================================
LBaaS reference implementation TLS support
==========================================
https://blueprints.launchpad.net/neutron/+spec/lbaas-ref-impl-tls-support
LBaaS reference HAProxy implementation needs improvement to support
TLS including SNI.
This blueprint describes the changes that should be made to the HAProxy
reference implementation to allow features provided by the blueprints:
https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination
https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface
and its successors to be implemented.
Problem Description
===================
The reference driver and its utilities currently do not support 'advanced'
features hindering the forward development of advanced API features suggested in
the 'lbaas-ssl-termination' blueprint.
In order to support TLS offloading configurations the reference driver (HAProxy)
must be updated to ensure proper 'backend' behavior and capabilities.
Features not currently supported in HAProxy 1.4 (current stable):
- TLS termination.
- TLS Source IP session persistence
- X-Forwarded-For headers for TLS connections.
- TLS Source IP load balancing method
- TLS re-encryption
This spec will not include scope for L7, source_ip session persistence, TLS
session ID session persistence, source_ip load balancing algorithm, TLS
re-encryption as well as x-forwarded-for or certificate based client
authentication.
Scope of this spec is to include TLS which includes SNI support.
Proposed Change
===============
The current reference driver named 'namespace_driver' utilizes HAProxy 1.4.
Update to use HAProxy 1.5(dependent on packaging)
In order to implement these features a few things need to be done:
1. Update HAProxy config. The configuration will be built using Jinja
as specified in spec: "https://blueprints.launchpad.net/neutron/+spec/
lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface" and will
expand on it to include TLS features.
The configuration utility will configure new directories and files for
HAProxy and certificates in the structure below. This will ensure no name
collisions.
::
$state_path/lbaas/$lb_uuid/
$state_path/lbaas/$lb_uuid/$cert1_barbican_id.pem
$state_path/lbaas/$lb_uuid/$cert2_barbican_id.pem
$state_path/lbaas/$lb_uuid/$certN_barbican_id.pem
$state_path/lbaas/$lb_uuid/haproxy.conf
$state_path/lbaas/$lb_uuid/run/
$state_path/lbaas/$lb_uuid/run/haproxy.pid
$state_path/lbaas/$lb_uuid/run/haproxy_stats.sock
2. The pem file containing the private key will be written
with permissions such that its only readable by root to protect security
credentials.
Modification of neutron.agent.linux.util#replace_file to accept an optional
'file_mode' argument to specify permissions other then default '0644'. This
protects against race condition where attacker reads the private key
before the file permissions are set.
3. There are also tear down methods i.e. undeploy_instance that will need to be
updated for proper clean up. (kill pids)
Additional Thoughts:
Those using devstack will not be able to use this feature unless manually
installed or devstack itself is updated. This would need to be updated
on that side at some point.
Data Model Impact
-----------------
None
REST API Impact
---------------
None. This blueprint is intended to provide capabilities that can be supported
in future versions of the REST API.
Security Impact
---------------
Users private key will be written into a file readable by root on the local file
system of the network node.
Notifications Impact
--------------------
None
Other End User Impact
---------------------
Devstack will need to be updated to install the new packages(HAProxy 1.5).
Performance Impact
------------------
Additional calls will have to be made to spawn additional instances.
TLS offloading increases overhead to the network node.
IPv6 Impact
-----------
None
Other Deployer Impact
---------------------
Deployer will need to ensure new dependencies are installed.
Developer Impact
----------------
Developers will need to ensure they are using the additional utilities based
on the lb configuration.
Developers will need to create a utility to retrieve Barbican secrets/data.
Community Impact
----------------
This change has been in review since Juno. Much discussion has taken place
over IRC and the mailing list.
Alternatives
------------
Alternatively, if we would like to support different TLS offloading tools like
Stud we could support plugin or extensions that are loaded in front of HAProxy.
Implementation
==============
Assignee(s)
-----------
Primary assignee:
phillip-toohill
Other contributors:
dlundquist
Work Items
----------
Update haproxy 'haproxy.conf' and jinja templates to handle new configurations.
Update namespace_driver methods for new actions.
Testing.
Dependencies
============
- Depends on blueprints:
https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement
https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination
https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface
and its successors noted within.
Testing
=======
Tempest Tests
-------------
* Add TLS to existing LBaaS tempest tests
Functional Tests
----------------
* Test to verify SSL termination
API Tests
---------
None
Documentation Impact
====================
User Documentation
-------------------
Document behavior and capabilities of the refactored reference implementation.
Developer Documentation
------------------------
Document behavior and capabilities of the refactored reference implementation.
References
==========
http://www.haproxy.org/
https://blueprints.launchpad.net/neutron/+spec/lbaas-api-and-objmodel-improvement
https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface
https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination

View File

@ -0,0 +1,188 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
=======================================
LBaaS Refactor HAProxy namespace driver
=======================================
https://blueprints.launchpad.net/neutron/+spec/lbaas-refactor-haproxy-namespace-driver-to-new-driver-interface
With the new LBaaS object model and driver interface we no longer have a
working reference implementation.
Problem Description
===================
Existing HAProxy namespace driver does not implement new LBaaS driver API or
support multiple listeners load balancer as supported by new LBaaS object
model.
Proposed Change
===============
Refactor LBaaS HAProxy namespace driver to use new object model driver
interface.
Use Jinja2 to render HAProxy configuration template, rather than the custom
configuration generation.
HAProxy configurations may include multiple listeners per load balancer in a
single HAProxy process.
Separate files in $state_path/lbaas/$lb_uuid/ placing files written by HAProxy
under $state_path/lbaas/$lb_uuid/run to prepare for storing TLS private keys
under $state_path/lbaas/$lb_uuid/. Renaming configuration file, PID file and
statistics socket stored in $state_path/lbaas/$lb_uuid/ to avoid name conflicts
with Stunnel. Further TLS related changes are outside the scope of this spec.
The new directory structure will look like this:
::
$state_path/lbaas/$lb_uuid/
$state_path/lbaas/$lb_uuid/haproxy.conf
$state_path/lbaas/$lb_uuid/run/
$state_path/lbaas/$lb_uuid/run/haproxy.pid
$state_path/lbaas/$lb_uuid/run/haproxy_stats.sock
The driver will need to detect if the sock and/or PID files are not present in
the new locations, and upgrade the running load balancer namespace to this new
file system. This will result in a brief interruption of load balancer service
while HAProxy is shutdown and configuration updated.
Further TLS and Layer 7 content filtering/manipulation are outside the scope of
this spec, but other specs may depend on this.
Data Model Impact
-----------------
None
REST API Impact
---------------
None
Security Impact
---------------
Restricting write access to $state_path/lbaas/$lb_uuid/ to root, and placing
HAProxy modified files in $state_path/lbaas/$lb_uuid/run/.
Notifications Impact
--------------------
None
Other End User Impact
---------------------
None
Performance Impact
------------------
Preformance should remain similar to existing HAProxy namespace driver.
IPv6 Impact
-----------
None
Other Deployer Impact
---------------------
The deployer will need to stop the lbaas-agent before while restarting
neutron-server upgrade the database schema and RPC protocol.
The deployer should also note the interruption in load balancer services and
each namespace's file system is updated to the new configuration.
Adding Jinja2 requirement for HAProxy namespace driver functionality, this is
already used within Neutron by the VPNaaS driver.
Developer Impact
----------------
This will significantly affect the HAProxy namespace driver in order to
accommodate the new driver interface and multiple listeners.
Addition of Jinja2 requirement for LBaaS support may require DevStack updates.
Community Impact
----------------
This change has been in review since Juno. Much discussion has taken place
over IRC and the mailing list.
Alternatives
------------
Implement a different LBaaS reference driver.
Implementation
==============
Assignee(s)
-----------
Primary assignee:
https://launchpad.net/~dlundquist
Other contributors:
https://launchpad.net/~phillip-toohill
Work Items
----------
* Develop Jinja2 template for HAProxy configuration.
* Update HAProxy namespace driver.
Dependencies
============
* LBaaS API and object model improvements
* LBaaS object model driver changes
Testing
=======
Implementation of this spec will allow end to end testing of new LBaaS object
model.
Tempest Tests
--------------
* Existing LBaaS tests should be modified to test LBaaS v2
Functional Tests
----------------
* End-to-end LBaaS v2 tests
API Tests
---------
None
Documentation Impact
====================
User Documentation
------------------
Existing LBaaS ref driver documentation needs to be updated.
Developer Documentation
-----------------------
None
References
==========
* specs/juno/lbaas-api-and-objmodel-improvement.rst
* specs/juno/lbaas-objmodel-driver-changes.rst

594
specs/kilo/lbaas-tls.rst Normal file
View File

@ -0,0 +1,594 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
==================================
Neutron LBaaS TLS - Specification
==================================
BP https://blueprints.launchpad.net/neutron/+spec/lbaas-ssl-termination
Terminating TLS connections on the load balancer is a capability
expected from modern load balancers and incorporated into many applications.
This capability enables better certificate management and improved
application based load balancing e.g. cookie-based persistency,
L7 Policies appliance, etc.
Problem Description
===================
No TLS offloading capability is available for Neutron LBaaS
Proposed Change
===============
*Note: This document is referencing to the new LBaaS objects model
proposed at https://review.openstack.org/#/c/89903*
*Note: This document does not consider flavors framework proposed at
https://review.openstack.org/#/c/90070
Before the flavors framework is in place, specific back-end driver which
does not support TLS capabilities should throw an exception stating a lack
of TLS support once it gets request for listener with TLS configuration.
This document specifies a "core" feature set that every back-end implementing
TLS capabilities must comply.
TLS capabilities of various back-end implementations
may differ in future releases, thus flavors aspect should definitely be part
of TLS capabilities specification*
*Note: Horizon project aspect is not a part of this specification.*
* Tenant will manage his TLS certificates using Barbican.
Certificates will be stored in Barbican secure containers.
* Barbican is in charge of containers life cycle management,
containers classification and validation.
LBaaS TLS requires a specific container type (TLS).
Only container of this type will be listed to the tenant for selection
while configuring listener's TLS containers to use.
Any invalid container usage will raise an error.
* Barbican will also manage list of interested consumers for each container.
See spec at https://review.openstack.org/#/c/99516
Neutron LBaaS (a consumer, according to Barbican's terminology) will not
use a regular GET request for container resource in order to get the
container. Instead, it will use a POST request to container's consumers
resource (http://admin-api/v1/containers/{container-uuid}/consumers) with
following info:
{
"type": "LBaaS",
"URL": "https://lbaas.myurl.net/loadbalancers/<lb_id>/"
}
**Note:**
We might want to use specific Listener URL instead of
Loadbalancer's one, like
"https://lbaas.myurl.net/lbaas/listeners/<listener_id>"
As a response, it will get containers data like container's resource GET
request was used.
Barbican, in its turn will store consumer's (LBaaS instance URL) data
in its database so this info can be used for getting all consumers of
a specific TLS container.
As a result, Neutron LBaaS TLS implementation is required to:
* Use only POST request to container's consumers resource in order to get
the container's data.
* Perform DELETE request to container's consumers resource when
stop using a container.
* Barbican TLS container will contain PEM encoded data. Specific back-end
implementation might convert the certificates data to other format
such as DER, if needed.
* In addition to existing HTTP, HTTPS and TCP, new protocol, TERMINATED_HTTPS
will be added for listener creation
* For tenant, creating listener with TERMINATED_HTTPS as a protocol means
desire to offload incoming encrypted traffic. New configuration options
will be available for listener's configuration including:
* Default TLS container id for TLS termination
* TLS containers list for SNI
* In case when specific back-end is not able to support TLS capabilities,
its driver should throw an exception. The exception message should state
that this specific back-end (provider) does not support listeners with TLS
offloading. The clear sign of listener's requirement for TLS
offloading capabilities is its TERMINATED_HTTPS protocol.
* New module will be developed in Neutron LBaaS for Barbican TLS containers
interactions. The module will be used by Neutron LBaaS front-end API code
and providers' driver code. The module will be used for validation and
data extraction from default TLS container and SNI containers.
This module represents the only legitimate API for Barbican TLS containers
interactions. See 'SNI certificates list management' section for detailed
module specification.
* When creating listener with TERMINATED_HTTPS protocol:
* Front-end TLS offloading is always enabled - hard coded as a default
behaviour for listener with TERMINATED_HTTPS protocol
* Tenant must supply default TLS container for front-end offloading.
Not supplying a container is an invalid configuration.
* TLS supported protocols and cipher suites for termination will be
set to sane values by each back-end's specific code
* SNI certificates list is optional and not mandatory to specify
* SNI certificates list specifying is described
in "SNI certificates list management" section
* Certificate intermediate chain will be stored as a part of Barbican's
TLS container
* Back-end re-encryption will not be supported in first phase
* Front-end client authentication and back-end server authentication will not
be supported in first phase
* When updating listener with TERMINATED_HTTPS protocol:
* In TLS configuration domain, default TLS container ID for front-end
offloading and SNI container IDs list are values that may be changed
* In case when defaut TLS container ID is replaced for the listener,
back-end implementation should ensure a lack of a downtime on LB appliance.
* Same for changing SNI container IDs list, back-end should
avoid LB downtime.
* HA-Proxy LBaaS implementaion and other LBaaS implementations should
be modified to support this specification.
**With stated above, following is a description of a basic tenant use case - creating listener with TLS offloading:**
* Tenant cteates Barbican TLS container with a certificate.
* Tenant creates listener with TERMINATED_HTTPS as a listener protocol
and specifies the Barbican TLS container ID as a default TLS container
for front-end offloading
* As a result, listener created, offloading encrypted traffic on front-end
with default tenant's TLS certificate, not re-encrypting traffic to the
back-end.
Requirements from Barbican
--------------------------
* Tenant should be able to create and delete
TLS containers using Barbican
* Ability to store TLS certificates in Barbican containers
that contain the TLS certificate itself, its private key
and optionaly, intermediate chain
* Creating TLS container with:
* Certificate : PEM text field
* Private_key: PEM text_field
* (extracted) Private_key_pass_phrase : text field
* Intermediates: PEM text field (optional)
This field is a concatination of PEM encoded certificate blocks
in specific order
* Delete TLS certificate
**optional:** Check if certificate is in use by any consumer
and warn before deleting.
Barbican's BP discussing this feature:
https://review.openstack.org/#/c/99516/
* Get TLS container, including private key in PEM encoded PKCS1 or PKCS7
formats, by container id
* Get TLS certificate in pem encoded x509 format, by container id
Restrictions
------------
* TLS settings are only available for listeners
having TERMINATED_HTTPS as a protocol. In other cases TLS settings
will be disabled and have None or empty values.
There should be a meaningfull error message to a user explaining the exact
reason of a failure in case of an invalid configuration.
* Listener protocol is immutable. Changing the protocol will require
radical re-configuration of provider's back-end system, which seems to be
not justified for this use case. Tenant should create new listener.
* While updating existing TLS certificate, name and description are only values
allowed to be modified. Creating new TLS container and using it instead of
the old one will be easier option than re-configuring LBaaS back-end
with modified container, at least in first phase.
SNI certificates list management
--------------------------------
For SNI functionality, tenant will supply list of TLS containers in specific
order.
In case when specific back-end is not able to support SNI capabilities,
its driver should throw an exception. The exception message should state
that this specific back-end (provider) does not support SNI capability.
The clear sign of listener's requirement for SNI capability is
a none empty SNI container ids list.
However, reference implementation must support SNI capability.
New separate module will be developed in Neutron LBaaS for Barbican TLS
containers interactions.
The module will use service account for Barbican API interation.
The module will have API for:
* Ensuring Barbican TLS container existence (used by LBaaS front-end API)
* Validating Barbican TLS container (used by LBaaS front-end API)
This API will also "register" LBaaS as a container's consumer in Barbican's
repository.
* Extracting SubjectCommonName and SubjectAltName information
from certificates X509 (used by LBaaS front-end API)
As for now, only dNSName and directoryName types will be extracted from
SubjectAltName sequence, while directoryName type usage is an issue
for further discussion.
* Extracting certificates data from Barbican TLS container
(used by provider/driver code)
* Unregistering LBaaS as a consumer of the container when container is not
used by any listener any more (used by LBaaS front-end API)
The module will use pyOpenSSL and PyASN1 packages.
Only this new common module should be used by Neutron LBaaS code for Barbican
containers interactions.
Front-end LBaaS API (plugin) code will use a new developed module for
validating Barbican TLS containers.
Driver, in its turn, can extract SubjectCommonName and SubjectAltName
information from certificates X509 via the common module API
and use it for its specific SNI implementation.
**Note:**
**Specific back-end driver does not have to use SubjectAltName
information. Furthermore, specific driver may throw
an exception saying SubjectAltName is not supported by
its provider**
Any specific driver implementation may extract host names info from
certificates using the mentioned above common module API only, if needed.
**SNI conflicts**
Employing the order of certificates list is not a common requirement
for all back-end implementations.
The order of SNI containers list may be used by specific back-end code,
like Radware's, for specifying priorities among certificates.
Order is meant to be a hint to resolve conflicts when 2 or more certificates
match the DNS name requested in the SNI client hello.
Specific backends might choose to ignore this order and might employ their
own mechanisms to choose one among the clashing certificates.
For ex. NetScaler employs the best match algorithm and does not require
order for conflict resolution.
It's also possible that specific driver throws an exception saying there is
a collision and this specific SNI setup will not be supported by the back-end.
Data Model Impact
-----------------
**Data model changes**
* *lbaas_listeners* table will be modified with new
* default_tls_container_id (nullable string 36) - Barbican's
TLS container id
* New *lbaas_sni* table will be created for storing
ordered list of TLS containers associated to a listener for SNI capabilities.
Association objects is composed of:
* id (immutable string 36) - generated object id
* listener_id (string 36) - associated listener id
* tls_container_id (string 36) - associated Barbican TLS container id
* position - (integer) index for preserving the order
**Required database migration**
* add new columns to *lbaas_isteners* table
* create new *lbaas_sni* table
**New data initial set**
* New columns for *lbaas_listeners* table's existing entries will be set
to defaults
REST API Impact
---------------
**Listener Attributes**
+-------------+-------+---------+---------+------------+----------------------+
|Attribute |Type |Access |Default |Validation/ |Description |
|Name | | |Value |Conversion | |
+=============+=======+=========+=========+============+======================+
|default-tls- |UUID |RW,tenant|NULL |UUID |default TLS cert id |
|container-id | | | | |to use for offloading |
+-------------+-------+---------+---------+------------+----------------------+
|sni_container|UUID |RW,tenant|NULL |UUID list |ordered list of |
|_ids |list | | | |TLS containers to use |
| | | | | |for SNI .|
+-------------+-------+---------+---------+------------+----------------------+
**Functions**
* create_listener
* Creates new listener
* Request
*POST /v2.0/lbaas/listeners
Accept: application/json
{
"listener":{
<...usual listener parameters>,
"protocol": "TERMINATED_HTTPS"
"default_tls_container_id": "7804a0de-7f6b-409a-a47c-a1cc7bc77b4j",
"sni_container_ids": None
}
}*
* Response
*{
"listener":{
"id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e"
<...usual listener parameters>,
"default_tls_container_id": "7804a0de-7f6b-409a-a47c-a1cc7bc77b4c",
"sni_container_ids": None
"tenant_id":"6b96ff0cb17a4b859e1e575d221683d3"
}
}*
* create_listener (with SNI list)
* Creates new listener
* Request
*POST /v2.0/lbaas/listeners
Accept: application/json
{
"listener":{
<...usual listener parameters>,
"protocol": "TERMINATED_HTTPS"
"default_tls_container_id": "7804a0de-7f6b-409a-a47c-a1cc7bc77b4j",
"sni_container_ids": [5404a0de-7f6b-409a-a47c-a1ccgbc77b3j,
1206a0de-7f6b-409a-a47c-a1ccgbc7bgf3]
}
}*
* Response
*{
"listener":{
"id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e"
<...usual listener parameters>,
"default_tls_container_id": "7804a0de-7f6b-409a-a47c-a1cc7bc77b4c",
"sni_container_ids":[5404a0de-7f6b-409a-a47c-a1ccgbc77b3j,
1206a0de-7f6b-409a-a47c-a1ccgbc7bgf3]
"tenant_id":"6b96ff0cb17a4b859e1e575d221683d3"
}
}*
* update_listener
* Updates VIP listener
* Request
*PUT /v2.0/lbaas/listeners/<listener-id>
Accept: application/json
{
"listener":{
<...usual listener parameters>,
"protocol": "TERMINATED_HTTPS"
"default_tls_container_id": "7804a0de-7f6b-409a-a47c-a1cc7bc77b4c",
"sni_container_ids": None
}
}*
* Response
*{
"listener":{
"id": "8604a0de-7f6b-409a-a47c-a1cc7bc77b2e"
<...usual listener parameters>,
"default_tls_container_id": "7804a0de-7f6b-409a-a47c-a1cc7bc77b4c",
"sni_container_ids": None
"tenant_id":"6b96ff0cb17a4b859e1e575d221683d3"
}
}*
Security Impact
---------------
Following are security requirements:
* Retrieving TLS container from Barbican to LBaaS plugin/driver
must be secured
* Sending TLS container contents from driver to back-end system
must be secured
* Storing secrets on neutron server is prohibited
* Back-end systems may need to ensure secured store for secrets
to meet certain security compliance requirements
Notifications Impact
--------------------
None
CLI Impact
---------------------
* Listener creation with TERMINATED_HTTPS protocol (default behavior)
*lb-listener-create* **--protocol TERMINATED_HTTPS**
*--protocol-port 443*
**--default_tls_container_id 9a96ff0cb17a4b859e1e575d2216cd23**
*...<usual CLI options>*
* Listener creation with TERMINATED_HTTPS protocol and SNI certificates list
*lb-listener-create* **--protocol TERMINATED_HTTPS**
*--protocol-port 443*
**--default_tls_container_id 9a96ff0cb17a4b859e1e575d2216cd23
--sni_container_ids list=true
6b96ff0cb17a4b859e1e575d221683d3 4596ff0cb17a4b859e1e575d22168ba1**
*...<usual CLI options>*
Other End User Impact
---------------------
None
Performance Impact
------------------
* When updating listener without modifying TLS settings
(default container id or SNI list) - Barbican API should not be used
for retrieving container content which was not actually changed.
This will prevent unnecessary resources consumption when, for example,
members are added to the pool used by listener.
It means that each Barbican TLS container will be validated only once
for a listener while it's still in use by this listener.
IPv6 Impact
-----------
None
Other Deployer Impact
---------------------
* Barbican is required to be deployed and functional in order this feature
to work.
* New dependencies are added for neutron, pyOpenSSL and PyASN1. These
are required by new module for Barbican TLS containers interactions.
Developer Impact
----------------
None
Community Impact
----------------
This change has been in review since Juno. Much discussion has taken place
over IRC and the mailing list.
Alternatives
------------
None
Implementation
==============
Assignee(s)
-----------
Primary assignee:
https://launchpad.net/~evgenyf
Other contributors:
Barbican TLS containers interactions module -
https://launchpad.net/~carlos-garza
Work Items
----------
* Develop new module for BArbican TLS containers interactions using pyOpenSSL
and PyASN1 packages.
* Implement changes in LBaaS DB schema v2
* Implement changes in LBaaS extension v2
* Implement all required CLI changes
* Implement all required unit testing
* Implement all required tempest testing
* Make integration with Barbican certificates storage API
Detailed specificatio of how Barbican's API for containers should be used
is at https://review.openstack.org/#/c/99516
* Modifying LBaaS HA-Proxy driver to support TLS capability
Detailed specification of this work item
is at https://review.openstack.org/#/c/100931
* Use HA-Proxy version 1.5
* Implement horizon part of this spec, not as part of Juno release.
Dependencies
============
* Barbican API requirements
* Neutron LBaaS API v2 with new listener object implemented
* New dependencies will be added for neutron, pyOpenSSL and PyASN1. These
are required by new module for Barbican TLS containers interactions.
Testing
=======
Tempest Tests
-------------
**listener unit testing domains**
* REST API and attributes validation tests
* DB mixin and schema tests
* LBaaS Plugin with mocked driver end-to-end tests
* Specific driver tests for each existing driver supporting TLS offloading
* Tempest tests
* CLI tests
* New listener creation with TERMINATED_HTTPS as a protocol
* No default TLS container for termination supplied.
Check error generation
* Default TLS container for termination supplied.
Test expected default configuration took place.
* Default TLS container supplied.
SNI TLS containers list was supplied
Test expected configuration took place
* Update existing listener with TERMINATED_HTTPS as a protocole
* Change default TLS container. Test expected configuration
* Add/Modify SNI containers list. Test expected configuration
CLI tests should test inconsistency issues such as:
* No default offloading TLS container specified when creating listener
with TERMINATES_HTTPS protocole
Functional Tests
----------------
As above.
API Tests
----------
As above.
Documentation Impact
====================
User Documentation
------------------
* Neutron CLI should be modified with updated
listener commands with TLS options
Developer Documentation
-----------------------
* Neutron API should be modified with new listener TLS attributes
References
==========
* TLS RFC http://tools.ietf.org/html/rfc2818