tripleo-specs/specs/juno/haproxy_configuration.rst
Robert Collins 2cc5b31b54 Tweak HAProxy spec to deal with mixed services.
Turns out we didn't dig deep enough when designing it.

Change-Id: I144e627465d4a28ad692c14c03c1ec6387ef1f86
2014-08-11 11:42:43 +12:00

5.6 KiB

Haproxy ports and related services configuration

Blueprint: https://blueprints.launchpad.net/tripleo/+spec/tripleo-haproxy-configuration

Current spec provides options for HA endpoints delivery via haproxy.

Problem Description

Current tripleo deployment scheme binds services on 0.0.0.0:standard_port, with stunnel configured to listen on ssl ports.

This configuration has some drawbacks and wont work in ha, for several reasons:

  • haproxy cant bind on <vip_address>:<service_port> - openstack services are bound to 0.0.0.0:<service_port>
  • services ports hardcoded in many places (any_service.conf, init-keystone), so changing them and configuring from heat would be a lot of pain
  • the non-ssl endpoint is reachable from outside the local host, which could potentially confuse users and expose them to an insecure connection in the case where we want to run that service on SSL only. We want to offer SSL by default but we can't really prevent it.

Proposed Change

We will bind haproxy, stunnel (ssl), openstack services on ports with different ipaddress settings.

HAProxy will be bound to VIP addresses only.

STunnel where it is used will be bound to the controller ctlplane address.

OpenStack services will bind to localhost for SSL only configurations, and to the ctlplane address for non-SSL or mixed-mode configurations. They will bind to the standard non-encrypted ports, but will never bind to 0.0.0.0 on any port.

We'll strive to make SSL-only the default.

An example, using horizon in mixed mode (HTTPS and HTTP):

vip_address = 192.0.2.21 node_address = 192.0.2.24

  1. haproxy listen horizon_http bind vip_address:80 server node_1 node_address:80 listen horizon_https bind vip_address:443 server node_1 node_address:443
  2. stunnel accept node_address:443 connect node_address:80
  3. horizon bind node_address:80

A second example, using horizon in HTTPS only mode:

vip_address = 192.0.2.21 node_address = 192.0.2.24

  1. haproxy listen horizon_https bind vip_address:443 server node_1 node_address:443
  2. stunnel accept node_address:443 connect 127.0.0.1:80
  3. horizon bind 127.0.0.1:80

Alternatives

There are several alternatives which do not cover all the requirements for security or extensibility

Option 1: Assignment of different ports for haproxy, stunnel, openstack services on 0.0.0.0

  • requires additional firewall configuration
  • security issue with non-ssl services endpoints
  1. haproxy bind :80

    listen horizon server node_1 node_address:8800

  2. stunnel accept :8800 connect :8880

  3. horizon bind :8880

Option 2: Using only haproxy ssl termination is suboptimal:

  • 1.5 is still in devel phase -> potential stability issues
  • we would have to get this into supported distros
  • this also means that there is no SSL between haproxy and real service
  • security issue with non-ssl services endpoints
  1. haproxy bind vip_address:80

    listen horizon server node_1 node_address:80

  2. horizon bind node_address:80

Option 3: Add additional ssl termination before load-balancer

  • not useful in current configuration because load balancer (haproxy) and openstack services installed on same nodes

Security Impact

  • Only ssl protected endpoints are publicly available if running SSL only.
  • Minimal firewall configuration
  • Not forwarding decrypted traffic over non-localhost connections
  • compromise of a control node exposes all external traffic (future and possibly past) to decryption and/or spoofing

Other End User Impact

Several services will listen on same port, but it will be quite easy to understand if user (operator) will know some context.

Performance Impact

No differences between approaches.

Other Deployer Impact

None

Developer Impact

None

Implementation

We need to make the service configs - nova etc - know on a per service basis where to bind. The current approach uses logic in the template to choose between localhost and my_ip. If we move the selection into Heat this can become a lot simpler (read a bind address, if set use it, if not don't).

We considered extending the connect_ip concept to be on a per service basis. Right now all services are exposed to both SSL and plain, so this would be workable until we get a situation where only some services are plain - but we expect that sooner rather than later.

Assignee(s)

Primary assignee:

dshulyak

Work Items

tripleo-incubator: * build overcloud-control image with haproxy element

tripleo-image-elements:

  • openstack-ssl element refactoring
  • refactor services configs to listen on 127.0.0.1 / ctlplane address: horizon apache configuration, glance, nova, cinder, swift, ceilometer, neutron, heat, keystone, trove

tripleo-heat-templates: * add haproxy metadata to heat-templates

Dependencies

None

Testing

CI testing dependencies:

  • use vip endpoints in overcloud scripts
  • add haproxy element to overcloud-control image (maybe with stats enabled) before adding haproxy related metadata to heat templates

Documentation Impact

  • update incubator manual
  • update elements README.md

References

http://haproxy.1wt.eu/download/1.4/doc/configuration.txt

https://www.stunnel.org/howto.html