Chapter 8. Creating secure HTTP load balancers


In Red Hat OpenStack Services on OpenShift (RHOSO) environments, you can create various types of load balancers to manage secure HTTP (HTTPS) network traffic.

For more information, see the following sections:

8.1. About non-terminated HTTPS load balancers

A non-terminated HTTPS load balancer acts effectively like a generic TCP load balancer: the load balancer forwards the raw TCP traffic from the web client to the back-end servers where the HTTPS connection is terminated with the web clients. While non-terminated HTTPS load balancers do not support advanced load balancer features like Layer 7 functionality, they do lower load balancer resource utilization by managing the certificates and keys themselves.

8.2. Creating a non-terminated HTTPS load balancer

If your application requires HTTPS traffic to terminate on the back-end member servers, typically called HTTPS pass through, you can use the HTTPS protocol for your Red Hat OpenStack Services on OpenShift (RHOSO) load balancer listeners in a RHOSO environment.

Prerequisites

  • The administrator has created a project for you and has provided you with a clouds.yaml file for you to access the cloud.
  • The python-openstackclient package resides on your workstation.

    $ dnf list installed python-openstackclient
  • A shared external (public) subnet that you can reach from the internet.

Procedure

  1. Confirm that the system OS_CLOUD variable is set for your cloud:

    $ echo $OS_CLOUD
    my_cloud

    Reset the variable if necessary:

    $ export OS_CLOUD=my_other_cloud

    As an alternative, you can specify the cloud name by adding the --os-cloud <cloud_name> option each time you run an openstack command.

  2. Create a load balancer (lb1) on a public subnet (public_subnet).

    Note

    Values inside parentheses are sample values that are used in the example commands in this procedure. Substitute these sample values with values that are appropriate for your site.

    Example
    $ openstack loadbalancer create --name lb1 \
    --vip-subnet-id public_subnet --wait
  3. Create a listener (listener1) on a port (443).

    Example
    $ openstack loadbalancer listener create --name listener1 \
    --protocol HTTPS --protocol-port 443 lb1 --wait
  4. Create the listener default pool (pool1).

    Example

    The command in this example creates an HTTPS pool that uses a private subnet containing back-end servers that host HTTPS applications configured with a TLS-encrypted web application on TCP port 443:

    $ openstack loadbalancer pool create --name pool1 \
    --lb-algorithm ROUND_ROBIN --listener listener1 \
    --protocol HTTPS --wait
  5. Create a health monitor (healthmon1) on the pool (pool1) of type (TLS-HELLO) that connects to the back-end servers and tests the path (/).

    Health checks can help to avoid a false positive. If no health monitor is defined, the member server is assumed to be ONLINE.

    Example
    $ openstack loadbalancer healthmonitor create --name healthmon1 \
    --delay 15 --max-retries 4 --timeout 10 --type TLS-HELLO \
    --url-path / pool1 --wait
  6. Add load balancer members (192.0.2.10 and 192.0.2.11) on the private subnet (private_subnet) to the default pool.

    Example

    In this example, the back-end servers, 192.0.2.10 and 192.0.2.11, are named member1 and member2, respectively:

    $ openstack loadbalancer member create --name member1 --subnet-id \
    private_subnet --address 192.0.2.10 --protocol-port 443 pool1 --wait
    
    $ openstack loadbalancer member create --name member2 --subnet-id \
    private_subnet --address 192.0.2.11 --protocol-port 443 pool1 --wait

Verification

  1. View and verify the load balancer (lb1) settings.

    Example
    $ openstack loadbalancer show lb1
    Sample output
    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | description         |                                      |
    | flavor              |                                      |
    | id                  | 788fe121-3dec-4e1b-8360-4020642238b0 |
    | listeners           | 09f28053-fde8-4c78-88b9-0f191d84120e |
    | name                | lb1                                  |
    | operating_status    | ONLINE                               |
    | pools               | 627842b3-eed8-4f5f-9f4a-01a738e64d6a |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | provider            | amphora                              |
    | provisioning_status | ACTIVE                               |
    | updated_at          | 2024-01-15T11:12:42                  |
    | vip_address         | 198.51.100.11                        |
    | vip_network_id      | 9bca13be-f18d-49a5-a83d-9d487827fd16 |
    | vip_port_id         | 69a85edd-5b1c-458f-96f2-b4552b15b8e6 |
    | vip_qos_policy_id   | None                                 |
    | vip_subnet_id       | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    +---------------------+--------------------------------------+
  2. When a health monitor is present and functioning properly, you can check the status of each member.

    Example

    A working member (member1) has an ONLINE value for its operating_status.

    $ openstack loadbalancer member show pool1 member1
    Sample output
    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | address             | 192.0.2.10                           |
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | id                  | b85c807e-4d7c-4cbd-b725-5e8afddf80d2 |
    | name                | member1                              |
    | operating_status    | ONLINE                               |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | protocol_port       | 443                                  |
    | provisioning_status | ACTIVE                               |
    | subnet_id           | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    | updated_at          | 2024-01-15T11:12:42                  |
    | weight              | 1                                    |
    | monitor_port        | None                                 |
    | monitor_address     | None                                 |
    | backup              | False                                |
    +---------------------+--------------------------------------+

8.3. About TLS-terminated HTTPS load balancers

When a TLS-terminated HTTPS load balancer is implemented in a Red Hat OpenStack Services on OpenShift (RHOSO) environment, web clients communicate with the load balancer over Transport Layer Security (TLS) protocols. The load balancer terminates the TLS session and forwards the decrypted requests to the back-end servers. When you terminate the TLS session on the load balancer, you offload the CPU-intensive encryption operations to the load balancer, and allow the load balancer to use advanced features such as Layer 7 inspection.

8.4. Creating a TLS-terminated HTTPS load balancer

When you use TLS-terminated HTTPS load balancers, you offload the CPU-intensive encryption operations to the load balancer, and allow the load balancer to use advanced features such as Layer 7 inspection. In Red Hat OpenStack Services on OpenShift (RHOSO) environments, it is a best practice to also create a health monitor to ensure that your back-end members remain available.

Prerequisites

  • The administrator has created a project for you and has provided you with a clouds.yaml file for you to access the cloud.
  • The python-openstackclient package resides on your workstation.

    $ dnf list installed python-openstackclient
  • A shared external (public) subnet that you can reach from the internet.
  • TLS public-key cryptography is configured with the following characteristics:

    • A TLS certificate, key, and intermediate certificate chain is obtained from an external certificate authority (CA) for the DNS name that is assigned to the load balancer VIP address, for example, www.example.com.
    • The certificate, key, and intermediate certificate chain reside in separate files in the current directory.
    • The key and certificate are PEM-encoded.
    • The intermediate certificate chain contains multiple certificates that are PEM-encoded and concatenated together.
  • You must configure the Load-balancing service (octavia) to use the Key Manager service (barbican). For more information, see the _Managing secrets with the Key Manager service.

Procedure

  1. Combine the key (server.key), certificate (server.crt), and intermediate certificate chain (ca-chain.crt) into a single PKCS12 file (server.p12).

    Note

    Values inside parentheses are sample values that are used in the example commands in this procedure. Substitute these sample values with values that are appropriate for your site.

    Example
    $ openssl pkcs12 -export -inkey server.key -in server.crt \
    -certfile ca-chain.crt -passout pass: -out server.p12
    Note

    The following procedure does not work if you password protect the PKCS12 file.

  2. Confirm that the system OS_CLOUD variable is set for your cloud:

    $ echo $OS_CLOUD
    my_cloud

    Reset the variable if necessary:

    $ export OS_CLOUD=my_other_cloud

    As an alternative, you can specify the cloud name by adding the --os-cloud <cloud_name> option each time you run an openstack command.

  3. Use the Key Manager service to create a secret resource (tls_secret1) for the PKCS12 file.

    Example
    $ openstack secret store --name='tls_secret1' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < server.p12)"
  4. Create a load balancer (lb1) on the public subnet (public_subnet).

    Example
    $ openstack loadbalancer create --name lb1 \
    --vip-subnet-id public_subnet --wait
  5. Create a TERMINATED_HTTPS listener (listener1), and reference the secret resource as the default TLS container for the listener.

    Example
    $ openstack loadbalancer listener create --protocol-port 443 \
    --protocol TERMINATED_HTTPS \
    --default-tls-container=\
    $(openstack secret list | awk '/ tls_secret1 / {print $2}') lb1 --wait
  6. Create a pool (pool1) and make it the default pool for the listener.

    Example

    The command in this example creates an HTTP pool that uses a private subnet containing back-end servers that host non-secure HTTP applications on TCP port 80:

    $ openstack loadbalancer pool create --name pool1 --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --wait
  7. Create a health monitor (healthmon1) of type (HTTP) on the pool (pool1) that connects to the back-end servers and tests the path (/).

    Health checks can help to avoid a false positive. If no health monitor is defined, the member server is assumed to be ONLINE.

    Example
    $ openstack loadbalancer healthmonitor create --name healthmon1 \
    --delay 15 --max-retries 4 --timeout 10 --type HTTP --url-path / \
    pool1 --wait
  8. Add the non-secure HTTP back-end servers (192.0.2.10 and 192.0.2.11) on the private subnet (private_subnet) to the pool.

    Example

    In this example, the back-end servers, 192.0.2.10 and 192.0.2.11, are named member1 and member2, respectively:

    $ openstack loadbalancer member create --name member1 --subnet-id \
    private_subnet --address 192.0.2.10 --protocol-port 443 pool1 --wait
    
    $ openstack loadbalancer member create --name member2 --subnet-id \
    private_subnet --address 192.0.2.11 --protocol-port 443 pool1 --wait

Verification

  1. View and verify the load balancer (lb1) settings.

    Example
    $ openstack loadbalancer show lb1
    Sample output
    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | description         |                                      |
    | flavor              |                                      |
    | id                  | 788fe121-3dec-4e1b-8360-4020642238b0 |
    | listeners           | 09f28053-fde8-4c78-88b9-0f191d84120e |
    | name                | lb1                                  |
    | operating_status    | ONLINE                               |
    | pools               | 627842b3-eed8-4f5f-9f4a-01a738e64d6a |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | provider            | amphora                              |
    | provisioning_status | ACTIVE                               |
    | updated_at          | 2024-01-15T11:12:42                  |
    | vip_address         | 198.51.100.11                        |
    | vip_network_id      | 9bca13be-f18d-49a5-a83d-9d487827fd16 |
    | vip_port_id         | 69a85edd-5b1c-458f-96f2-b4552b15b8e6 |
    | vip_qos_policy_id   | None                                 |
    | vip_subnet_id       | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    +---------------------+--------------------------------------+
  2. When a health monitor is present and functioning properly, you can check the status of each member.

    Example
    $ openstack loadbalancer member show pool1 member1

    A working member (member1) has an ONLINE value for its operating_status:

    Sample output
    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | address             | 192.0.2.10                           |
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | id                  | b85c807e-4d7c-4cbd-b725-5e8afddf80d2 |
    | name                | member1                              |
    | operating_status    | ONLINE                               |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | protocol_port       | 80                                   |
    | provisioning_status | ACTIVE                               |
    | subnet_id           | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    | updated_at          | 2024-01-15T11:12:42                  |
    | weight              | 1                                    |
    | monitor_port        | None                                 |
    | monitor_address     | None                                 |
    | backup              | False                                |
    +---------------------+--------------------------------------+

For TLS-terminated HTTPS load balancers that employ Server Name Indication (SNI) technology, a single listener can contain multiple TLS certificates and enable the load balancer to know which certificate to present when it uses a shared IP. In Red Hat OpenStack Services on OpenShift (RHOSO) environments, it is a best practice to also create a health monitor to ensure that your back-end members remain available.

Prerequisites

  • The administrator has created a project for you and has provided you with a clouds.yaml file for you to access the cloud.
  • The python-openstackclient package resides on your workstation.

    $ dnf list installed python-openstackclient
  • A shared external (public) subnet that you can reach from the internet.
  • TLS public-key cryptography is configured with the following characteristics:

    • Multiple TLS certificates, keys, and intermediate certificate chains have been obtained from an external certificate authority (CA) for the DNS names assigned to the load balancer VIP address, for example, www.example.com and www2.example.com.
    • The keys and certificates are PEM-encoded.
  • You must configure the Load-balancing service (octavia) to use the Key Manager service (barbican). For more information, see the _Managing secrets with the Key Manager service.

Procedure

  1. For each of the TLS certificates in the SNI list, combine the key (server.key), certificate (server.crt), and intermediate certificate chain (ca-chain.crt) into a single PKCS12 file (server.p12).

    In this example, you create two PKCS12 files (server.p12 and server2.p12) one for each certificate (www.example.com and www2.example.com).

    Note

    Values inside parentheses are sample values that are used in the example commands in this procedure. Substitute these sample values with values that are appropriate for your site.

    Example
    $ openssl pkcs12 -export -inkey server.key -in server.crt \
    -certfile ca-chain.crt -passout pass: -out server.p12
    
    $ openssl pkcs12 -export -inkey server2.key -in server2.crt \
    -certfile ca-chain2.crt -passout pass: -out server2.p12
  2. Confirm that the system OS_CLOUD variable is set for your cloud:

    $ echo $OS_CLOUD
    my_cloud

    Reset the variable if necessary:

    $ export OS_CLOUD=my_other_cloud

    As an alternative, you can specify the cloud name by adding the --os-cloud <cloud_name> option each time you run an openstack command.

  3. Use the Key Manager service to create secret resources (tls_secret1 and tls_secret2) for the PKCS12 file.

    Example
    $ openstack secret store --name='tls_secret1' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < server.p12)"
    
    $ openstack secret store --name='tls_secret2' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < server2.p12)"
  4. Create a load balancer (lb1) on the public subnet (public_subnet).

    Example
    $ openstack loadbalancer create --name lb1 \
    --vip-subnet-id public_subnet --wait
  5. Create a TERMINATED_HTTPS listener (listener1), and use SNI to reference both the secret resources.

    (Reference tls_secret1 as the default TLS container for the listener.)

    Example
    $ openstack loadbalancer listener create  --name listener1 \
    --protocol-port 443 --protocol TERMINATED_HTTPS \
    --default-tls-container=\
    $(openstack secret list | awk '/ tls_secret1 / {print $2}') \
    --sni-container-refs \
    $(openstack secret list | awk '/ tls_secret1 / {print $2}') \
    $(openstack secret list | awk '/ tls_secret2 / {print $2}') -- lb1 --wait
  6. Create a pool (pool1) and make it the default pool for the listener.

    Example

    The command in this example creates an HTTP pool that uses a private subnet containing back-end servers that host non-secure HTTP applications on TCP port 80:

    $ openstack loadbalancer pool create --name pool1 \
    --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --wait
  7. Create a health monitor (healthmon1) of type (HTTP) on the pool (pool1) that connects to the back-end servers and tests the path (/).

    Health checks can help to avoid a false positive. If no health monitor is defined, the member server is assumed to be ONLINE.

    Example
    $ openstack loadbalancer healthmonitor create --name healthmon1 \
    --delay 15 --max-retries 4 --timeout 10 --type HTTP --url-path / \
    pool1 --wait
  8. Add the non-secure HTTP back-end servers (192.0.2.10 and 192.0.2.11) on the private subnet (private_subnet) to the pool.

    Example

    In this example, the back-end servers, 192.0.2.10 and 192.0.2.11, are named member1 and member2, respectively:

    $ openstack loadbalancer member create --name member1 --subnet-id \
    private_subnet --address 192.0.2.10 --protocol-port 443 pool1 --wait
    
    $ openstack loadbalancer member create --name member2 --subnet-id \
    private_subnet --address 192.0.2.11 --protocol-port 443 pool1 --wait

Verification

  1. View and verify the load balancer (lb1) settings.

    Example
    $ openstack loadbalancer show lb1
    Sample output
    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | description         |                                      |
    | flavor              |                                      |
    | id                  | 788fe121-3dec-4e1b-8360-4020642238b0 |
    | listeners           | 09f28053-fde8-4c78-88b9-0f191d84120e |
    | name                | lb1                                  |
    | operating_status    | ONLINE                               |
    | pools               | 627842b3-eed8-4f5f-9f4a-01a738e64d6a |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | provider            | amphora                              |
    | provisioning_status | ACTIVE                               |
    | updated_at          | 2024-01-15T11:12:42                  |
    | vip_address         | 198.51.100.11                        |
    | vip_network_id      | 9bca13be-f18d-49a5-a83d-9d487827fd16 |
    | vip_port_id         | 69a85edd-5b1c-458f-96f2-b4552b15b8e6 |
    | vip_qos_policy_id   | None                                 |
    | vip_subnet_id       | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    +---------------------+--------------------------------------+
  2. When a health monitor is present and functioning properly, you can check the status of each member.

    Example
    $ openstack loadbalancer member show pool1 member1
    Sample output

    A working member (member1) has an ONLINE value for its operating_status:

    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | address             | 192.0.2.10                           |
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | id                  | b85c807e-4d7c-4cbd-b725-5e8afddf80d2 |
    | name                | member1                              |
    | operating_status    | ONLINE                               |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | protocol_port       | 80                                   |
    | provisioning_status | ACTIVE                               |
    | subnet_id           | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    | updated_at          | 2024-01-15T11:12:42                  |
    | weight              | 1                                    |
    | monitor_port        | None                                 |
    | monitor_address     | None                                 |
    | backup              | False                                |
    +---------------------+--------------------------------------+

When you use TLS-terminated HTTPS load balancers, you offload the CPU-intensive encryption operations to the load balancer, and allow the load balancer to use advanced features such as Layer 7 inspection. With the addition of an HTTP/2 listener, you can leverage the HTTP/2 protocol to improve performance by loading pages faster. Load balancers negotiate HTTP/2 with clients by using the Application-Layer Protocol Negotiation (ALPN) TLS extension.

The Load-balancing service (octavia) supports end-to-end HTTP/2 traffic, which means that the HTTP2 traffic is not translated by HAProxy from the point where the request reaches the listener until the response returns from the load balancer. To achieve end-to-end HTTP/2 traffic, you must have an HTTP pool with back-end re-encryption: pool members that are listening on a secure port and web applications that are configured for HTTPS traffic.

You can send HTTP/2 traffic to an HTTP pool without back-end re-encryption. In this situation, HAProxy translates the traffic before it reaches the pool, and the response is translated back to HTTP/2 before it returns from the load balancer.

Red Hat recommends that you create a health monitor to ensure that your back-end members remain available in your Red Hat OpenStack Services on OpenShift (RHOSO) environment.

Note

Currently, the Load-balancing service does not support health monitoring for TLS-terminated load balancers that use HTTP/2 listeners.

Prerequisites

  • The administrator has created a project for you and has provided you with a clouds.yaml file for you to access the cloud.
  • The python-openstackclient package resides on your workstation.

    $ dnf list installed python-openstackclient
  • TLS public-key cryptography is configured with the following characteristics:

    • A TLS certificate, key, and intermediate certificate chain is obtained from an external certificate authority (CA) for the DNS name that is assigned to the load balancer VIP address, for example, www.example.com.
    • The certificate, key, and intermediate certificate chain reside in separate files in the current directory.
    • The key and certificate are PEM-encoded.
    • The intermediate certificate chain contains multiple certificates that are PEM-encoded and concatenated together.
  • You must configure the Load-balancing service (octavia) to use the Key Manager service (barbican). For more information, see the _Managing secrets with the Key Manager service.

Procedure

  1. Combine the key (server.key), certificate (server.crt), and intermediate certificate chain (ca-chain.crt) into a single PKCS12 file (server.p12).

    Note

    Values inside parentheses are sample values that are used in the example commands in this procedure. Substitute these sample values with values that are appropriate for your site.

    Important

    When you create the PKCS12 file, do not password protect the file.

    Example

    In this example, the PKCS12 file is created without a password:

    $ openssl pkcs12 -export -inkey server.key -in server.crt \
    -certfile ca-chain.crt -passout pass: -out server.p12
  2. Use the Key Manager service to create a secret resource (tls_secret1) for the PKCS12 file.

    Example
    $ openstack secret store --name='tls_secret1' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < server.p12)"
  3. Confirm that the system OS_CLOUD variable is set for your cloud:

    $ echo $OS_CLOUD
    my_cloud

    Reset the variable if necessary:

    $ export OS_CLOUD=my_other_cloud

    As an alternative, you can specify the cloud name by adding the --os-cloud <cloud_name> option each time you run an openstack command.

  4. Create a load balancer (lb1) on the public subnet (public_subnet).

    Example
    $ openstack loadbalancer create --name lb1 --vip-subnet-id \
    public_subnet --wait
  5. Create a TERMINATED_HTTPS listener (listener1) and do the following:

    • reference the secret resource (tls_secret1) as the default TLS container for the listener.
    • set the ALPN protocol (h2).
    • set the fallback protocol if the client does not support HTTP/2 (http/1.1).

      Example
      $ openstack loadbalancer listener create --name listener1 \
      --protocol-port 443 --protocol TERMINATED_HTTPS --alpn-protocol h2 \
      --alpn-protocol http/1.1 --default-tls-container=\
      $(openstack secret list | awk '/ tls_secret1 / {print $2}') lb1 --wait
  6. Create a pool (pool1) and make it the default pool for the listener.

    Example

    The command in this example creates an HTTP pool containing back-end servers that host HTTP applications configured with a web application on TCP port 80:

    $ openstack loadbalancer pool create --name pool1 \
    --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --wait
  7. Create a health monitor (healthmon1) of type (TCP) on the pool (pool1) that connects to the back-end servers.

    Health checks can help to avoid a false positive. If no health monitor is defined, the member server is assumed to be ONLINE.

    Example
    $ openstack loadbalancer healthmonitor create --name healthmon1 \
    --delay 15  --max-retries 4 --timeout 10 --type TCP pool1 --wait
  8. Add the HTTP back-end servers (192.0.2.10 and 192.0.2.11) on the private subnet (private_subnet) to the pool.

    Example

    In this example, the back-end servers, 192.0.2.10 and 192.0.2.11, are named member1 and member2, respectively:

    $ openstack loadbalancer member create --name member1 --subnet-id \
    private_subnet --address 192.0.2.10 --protocol-port 80 pool1 --wait
    
    $ openstack loadbalancer member create --name member2 --subnet-id \
    private_subnet --address 192.0.2.11 --protocol-port 80 pool1 --wait

Verification

  1. View and verify the load balancer (lb1) settings.

    Example
    $ openstack loadbalancer status show lb1
    Sample output
    {
        "loadbalancer": {
            "id": "936dad29-4c3f-4f24-84a8-c0e6f10ed810",
            "name": "lb1",
            "operating_status": "ONLINE",
            "provisioning_status": "ACTIVE",
            "listeners": [
                {
                    "id": "708b82c6-8a6b-4ec1-ae53-e619769821d4",
                    "name": "listener1",
                    "operating_status": "ONLINE",
                    "provisioning_status": "ACTIVE",
                    "pools": [
                        {
                            "id": "5ad7c678-23af-4422-8edb-ac3880bd888b",
                            "name": "pool1",
                            "provisioning_status": "ACTIVE",
                            "operating_status": "ONLINE",
                            "health_monitor": {
                                "id": "4ad786ef-6661-4e31-a325-eca07b2b3dd1",
                                "name": "healthmon1",
                                "type": "TCP",
                                "provisioning_status": "ACTIVE",
                                "operating_status": "ONLINE"
                            },
                            "members": [
                                {
                                    "id": "facca0d3-61a7-4b46-85e8-da6994883647",
                                    "name": "member1",
                                    "operating_status": "ONLINE",
                                    "provisioning_status": "ACTIVE",
                                    "address": "192.0.2.10",
                                    "protocol_port": 80
                                },
                                {
                                    "id": "2b0d9e0b-8e0c-48b8-aa57-90b2fde2eae2",
                                    "name": "member2",
                                    "operating_status": "ONLINE",
                                    "provisioning_status": "ACTIVE",
                                    "address": "192.0.2.11",
                                    "protocol_port": 80
                                }
    ...
  2. When a health monitor is present and functioning properly, you can check the status of each member.

    Example
    $ openstack loadbalancer member show pool1 member1
    Sample output

    A working member (member1) has an ONLINE value for its operating_status:

    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | address             | 192.0.2.10                           |
    | admin_state_up      | True                                 |
    | created_at          | 2024-08-16T20:08:01                  |
    | id                  | facca0d3-61a7-4b46-85e8-da6994883647 |
    | name                | member1                              |
    | operating_status    | ONLINE                               |
    | project_id          | 9b29c91f67314bd09eda9018616851cf     |
    | protocol_port       | 80                                   |
    | provisioning_status | ACTIVE                               |
    | subnet_id           | 3b459c95-64d2-4cfa-b348-01aacc4b3fa9 |
    | updated_at          | 2024-08-16T20:25:42                  |
    | weight              | 1                                    |
    | monitor_port        | None                                 |
    | monitor_address     | None                                 |
    | backup              | False                                |
    | tags                |                                      |
    +---------------------+--------------------------------------+

You can configure a non-secure listener and a TLS-terminated HTTPS listener on the same load balancer and the same IP address when you want to respond to web clients with the exact same content, regardless if the client is connected with a secure or non-secure HTTP protocol. In Red Hat OpenStack Services on OpenShift (RHOSO) environments, it is a best practice to also create a health monitor to ensure that your back-end members remain available.

Prerequisites

  • The administrator has created a project for you and has provided you with a clouds.yaml file for you to access the cloud.
  • The python-openstackclient package resides on your workstation.

    $ dnf list installed python-openstackclient
  • A shared external (public) subnet that you can reach from the internet.
  • TLS public-key cryptography is configured with the following characteristics:

    • A TLS certificate, key, and optional intermediate certificate chain have been obtained from an external certificate authority (CA) for the DNS name assigned to the load balancer VIP address (for example, www.example.com).
    • The certificate, key, and intermediate certificate chain reside in separate files in the current directory.
    • The key and certificate are PEM-encoded.
    • The intermediate certificate chain contains multiple certificates that are PEM-encoded and concatenated together.
  • The non-secure HTTP listener is configured with the same pool as the HTTPS TLS-terminated load balancer.

Procedure

  1. Combine the key (server.key), certificate (server.crt), and intermediate certificate chain (ca-chain.crt) into a single PKCS12 file (server.p12).

    Note

    Values inside parentheses are sample values that are used in the example commands in this procedure. Substitute these sample values with values that are appropriate for your site.

    Example
    $ openssl pkcs12 -export -inkey server.key -in server.crt \
    -certfile ca-chain.crt -passout pass: -out server.p12
  2. Confirm that the system OS_CLOUD variable is set for your cloud:

    $ echo $OS_CLOUD
    my_cloud

    Reset the variable if necessary:

    $ export OS_CLOUD=my_other_cloud

    As an alternative, you can specify the cloud name by adding the --os-cloud <cloud_name> option each time you run an openstack command.

  3. Use the Key Manager service to create a secret resource (tls_secret1) for the PKCS12 file.

    Example
    $ openstack secret store --name='tls_secret1' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < server.p12)"
  4. Create a load balancer (lb1) on the public subnet (public_subnet).

    Example
    $ openstack loadbalancer create --name lb1 \
    --vip-subnet-id external_subnet --wait
  5. Create a TERMINATED_HTTPS listener (listener1), and reference the secret resource as the default TLS container for the listener.

    Example
    $ openstack loadbalancer listener create --name listener1 \
    --protocol-port 443 --protocol TERMINATED_HTTPS \
    --default-tls-container=\
    $(openstack secret list | awk '/ tls_secret1 / {print $2}') lb1 --wait
  6. Create a pool (pool1) and make it the default pool for the listener.

    Example

    The command in this example creates an HTTP pool that uses a private subnet containing back-end servers that host non-secure HTTP applications on TCP port 80:

    $ openstack loadbalancer pool create --name pool1 \
    --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --wait
  7. Create a health monitor (healthmon1) of type (HTTP) on the pool (pool1) that connects to the back-end servers and tests the path (/).

    Health checks can help to avoid a false positive. If no health monitor is defined, the member server is assumed to be ONLINE.

    Example
    $ openstack loadbalancer healthmonitor create --name healthmon1 \
    --delay 15 --max-retries 4 --timeout 10 --type HTTP --url-path / \
    pool1 --wait
  8. Add the non-secure HTTP back-end servers (192.0.2.10 and 192.0.2.11) on the private subnet (private_subnet) to the pool.

    Example

    In this example, the back-end servers, 192.0.2.10 and 192.0.2.11, are named member1 and member2, respectively:

    $ openstack loadbalancer member create --name member1 --subnet-id \
    private_subnet --address 192.0.2.10 --protocol-port 443 pool1 --wait
    
    $ openstack loadbalancer member create --name member2 --subnet-id \
    private_subnet --address 192.0.2.11 --protocol-port 443 pool1 --wait
  9. Create a non-secure, HTTP listener (listener2), and make its default pool, the same as the secure listener.

    Example
    $ openstack loadbalancer listener create --name listener2 \
    --protocol-port 80 --protocol HTTP --default-pool pool1 lb1 --wait

Verification

  1. View and verify the load balancer (lb1) settings.

    Example
    $ openstack loadbalancer show lb1
    Sample output
    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | description         |                                      |
    | flavor              |                                      |
    | id                  | 788fe121-3dec-4e1b-8360-4020642238b0 |
    | listeners           | 09f28053-fde8-4c78-88b9-0f191d84120e |
    | name                | lb1                                  |
    | operating_status    | ONLINE                               |
    | pools               | 627842b3-eed8-4f5f-9f4a-01a738e64d6a |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | provider            | amphora                              |
    | provisioning_status | ACTIVE                               |
    | updated_at          | 2024-01-15T11:12:42                  |
    | vip_address         | 198.51.100.11                        |
    | vip_network_id      | 9bca13be-f18d-49a5-a83d-9d487827fd16 |
    | vip_port_id         | 69a85edd-5b1c-458f-96f2-b4552b15b8e6 |
    | vip_qos_policy_id   | None                                 |
    | vip_subnet_id       | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    +---------------------+--------------------------------------+
  2. When a health monitor is present and functioning properly, you can check the status of each member.

    Example
    $ openstack loadbalancer member show pool1 member1
    Sample output

    A working member (member1) has an ONLINE value for its operating_status:

    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | address             | 192.0.2.10                           |
    | admin_state_up      | True                                 |
    | created_at          | 2024-01-15T11:11:09                  |
    | id                  | b85c807e-4d7c-4cbd-b725-5e8afddf80d2 |
    | name                | member1                              |
    | operating_status    | ONLINE                               |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | protocol_port       | 80                                   |
    | provisioning_status | ACTIVE                               |
    | subnet_id           | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    | updated_at          | 2024-01-15T11:12:42                  |
    | weight              | 1                                    |
    | monitor_port        | None                                 |
    | monitor_address     | None                                 |
    | backup              | False                                |
    +---------------------+--------------------------------------+

With a TLS-terminated HTTPS load balancer, web clients communicate with the load balancer using TLS protocols. The load balancer terminates the TLS session and forwards the decrypted requests to the back-end servers. By terminating the TLS session on the load balancer, you offload the CPU-intensive encryption work to the load balancer, and enable advanced load balancer features, such as Layer 7 load balancing and header manipulation. Adding client authentication allows users to authenticate connections to the VIP using certificates. This is also known as two-way TLS authentication. In Red Hat OpenStack Services on OpenShift (RHOSO) environments, it is a best practice to also create a health monitor to ensure that your back-end members remain available.

Prerequisites

  • The administrator has created a project for you and has provided you with a clouds.yaml file for you to access the cloud.
  • The python-openstackclient package resides on your workstation.

    $ dnf list installed python-openstackclient
  • A shared external (public) subnet that you can reach from the internet.
  • TLS public-key cryptography is configured with the following characteristics:

    • A TLS certificate, key, and optional intermediate certificate chain have been obtained from an external certificate authority (CA) for the DNS name assigned to the load balancer VIP address (for example, www.example.com).
    • The certificate, key, and intermediate certificate chain reside in separate files in the current directory.
    • The key and certificate are PEM-encoded.
    • The intermediate certificate chain contains multiple certificates that are PEM-encoded and concatenated together.
  • The non-secure HTTP listener is configured with the same pool as the HTTPS TLS-terminated load balancer.

Procedure

  1. Combine the key (server.key), certificate (server.crt), and intermediate certificate chain (ca-chain.crt) into a single PKCS12 file (server.p12).

    Note

    Values inside parentheses are sample values that are used in the example commands in this procedure. Substitute these sample values with values that are appropriate for your site.

    Example
    $ openssl pkcs12 -export -inkey server.key -in server.crt \
    -certfile ca-chain.crt -passout pass: -out server.p12
  2. Confirm that the system OS_CLOUD variable is set for your cloud:

    $ echo $OS_CLOUD
    my_cloud

    Reset the variable if necessary:

    $ export OS_CLOUD=my_other_cloud

    As an alternative, you can specify the cloud name by adding the --os-cloud <cloud_name> option each time you run an openstack command.

  3. Use the Key Manager service to create a secret resource (tls_secret1) for the PKCS12 file.

    Example
    $ openstack secret store --name='tls_secret1' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < server.p12)"
  1. Use the Key Manager service to create a secret resource (client_ca_cert) for the client CA certificate.

    Example
    $ openstack secret store --name='client_ca_cert' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < client_ca.pem)"
  1. (Optional) use the Key Manager service to create a secret resource (client_ca_crl) for the CRL file.

    Example
    $ openstack secret store --name='client_ca_crl' \
    -t 'application/octet-stream' -e 'base64' \
    --payload="$(base64 < client_ca.crl)"
  2. Create a load balancer (lb1) on the public subnet (public_subnet).

    Example
    $ openstack loadbalancer create --name lb1 \
    --vip-subnet-id external_subnet --wait
  3. Create a TERMINATED_HTTPS listener (listener1) and do the following:

    • reference the secret resource (tls_secret1) as the default TLS container for the listener.
    • enable client authentication.
    • reference the secret resource (client_ca_cert) as the default TLS container for the client CA certificate.
    • reference the secret resource (client_ca_crl) as the default TLS container for the client CRL file.

      Example
      $ openstack loadbalancer listener create --name listener1\
      --protocol-port 443 --protocol TERMINATED_HTTPS \
      --default-tls-container=\
      $(openstack secret list | awk '/ tls_secret1 / {print $2}') \
      --client-authentication=MANDATORY \
      --client-ca-tls-container-ref=\
      $(openstack secret list | awk '/ client_ca_cert / {print $2}') \
      --client-crl-container=\
      $(openstack secret list | awk '/ client_ca_crl / {print $2}') \
      --wait lb1
  4. Create a pool (pool1) and configure it as the default pool for the listener.

    Example

    The command in this example creates an HTTP pool that uses a private subnet containing back-end servers that host non-secure HTTP applications on TCP port 80:

    $ openstack loadbalancer pool create --name pool1 \
    --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --wait
  5. Create a health monitor (healthmon1) of type (HTTP) on the pool (pool1) that connects to the back-end servers and tests the path (/).

    Health checks can help to avoid a false positive. If no health monitor is defined, the member server is assumed to be ONLINE.

    Example
    $ openstack loadbalancer healthmonitor create --name healthmon1 \
    --delay 15 --max-retries 4 --timeout 10 --type HTTP --url-path / \
    --wait pool1
  6. Add the non-secure HTTP back-end servers (192.0.2.10 and 192.0.2.11) on the private subnet (private_subnet) to the pool.

    Example

    In this example, the back-end servers, 192.0.2.10 and 192.0.2.11, are named member1 and member2, respectively:

    $ openstack loadbalancer member create --name member1 --subnet-id \
    private_subnet --address 192.0.2.10 --protocol-port 443 --wait pool1 \
    --wait
    
    $ openstack loadbalancer member create --name member2 --subnet-id \
    private_subnet --address 192.0.2.11 --protocol-port 443 --wait pool1 \
    --wait
  7. Create a non-secure, HTTP listener (listener2), and make its default pool, the same as the secure listener.

    Example
    $ openstack loadbalancer listener create --name listener2 \
    --protocol-port 80 --protocol HTTP --default-pool pool1 lb1 --wait

Verification

  1. View and verify the load balancer listener (lb1) settings.

    Example
    $ openstack loadbalancer listener show listener2
    Sample output

    The client_authentication value should read MANDATORY.

    ---------------------------------------------------------------------------+
    | Field                       | Value                                        |
    ---------------------------------------------------------------------------+
    | admin_state_up              | True                                         |
    | connection_limit            | -1                                           |
    | created_at                  | 2025-06-18T14:35:45                          |
    | default_pool_id             | f43b4259-3ca2-4393-bc7f-12143f6ec015         |
    | default_tls_container_ref   | https://barbican.openstack.svc:9311/v1/secre |
    |                             | ts/eb16233e-0cb1-4750-85af-d01931b409ca      |
    | description                 |                                              |
    | id                          | 5ab57588-6c9c-49f1-a562-6596eded84ff         |
    | insert_headers              | None                                         |
    | l7policies                  |                                              |
    | loadbalancers               | 5cb69415-281a-486e-96d4-b10c67291997         |
    | name                        | listener2                                    |
    | operating_status            | ONLINE                                       |
    | project_id                  | 4676472cb1344f449b367b6ac473bf93             |
    | protocol                    | TERMINATED_HTTPS                             |
    | protocol_port               | 443                                          |
    | provisioning_status         | ACTIVE                                       |
    | sni_container_refs          | []                                           |
    | timeout_client_data         | 50000                                        |
    | timeout_member_connect      | 5000                                         |
    | timeout_member_data         | 50000                                        |
    | timeout_tcp_inspect         | 0                                            |
    | updated_at                  | 2025-06-18T14:41:20                          |
    | client_ca_tls_container_ref | https://barbican.openstack.svc:9311/v1/secre |
    |                             | ts/81086194-3e51-474f-a6f6-fa9afd850939      |
    | client_authentication       | MANDATORY                                    |
    | client_crl_container_ref    | https://barbican.openstack.svc:9311/v1/secre |
    |                             | ts/8e3f75e1-611d-4fa2-b7e6-83a195270a91      |
    | allowed_cidrs               | None                                         |
    | tls_ciphers                 | TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305 |
    |                             | _SHA256:TLS_AES_128_GCM_SHA256:DHE-RSA-      |
    |                             | AES256-GCM-SHA384:DHE-RSA-AES128-GCM-        |
    |                             | SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-    |
    |                             | RSA-AES128-GCM-SHA256:DHE-RSA-               |
    |                             | AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-   |
    |                             | RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256    |
    | tls_versions                | [TLSv1.2, TLSv1.3]                       |
    | alpn_protocols              | [h2, http/1.1, http/1.0]               |
    | tags                        |                                              |
    ---------------------------------------------------------------------------+
  2. When a health monitor is present and functioning properly, you can check the status of each member.

    Example
    $ openstack loadbalancer member show pool1 member1
    Sample output

    A working member (member1) has an ONLINE value for its operating_status:

    +---------------------+--------------------------------------+
    | Field               | Value                                |
    +---------------------+--------------------------------------+
    | address             | 192.0.2.10                           |
    | admin_state_up      | True                                 |
    | created_at          | 2025-06-18T14:36:28                  |
    | id                  | 9da5aac4-b8c2-f113-6cef-a7f14327cb4a |
    | name                | member1                              |
    | operating_status    | ONLINE                               |
    | project_id          | dda678ca5b1241e7ad7bf7eb211a2fd7     |
    | protocol_port       | 80                                   |
    | provisioning_status | ACTIVE                               |
    | subnet_id           | 5bd7334b-49b3-4849-b3a2-b0b83852dba1 |
    | updated_at          | 2025-06-18T14:36:49                  |
    | weight              | 1                                    |
    | monitor_port        | None                                 |
    | monitor_address     | None                                 |
    | backup              | False                                |
    +---------------------+--------------------------------------+
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2026 Red Hat
Back to top