Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
Applies to SUSE OpenStack Cloud 8

7 Transport Layer Security (TLS) Overview Edit source

The Transport Layer Security (TLS) protocol, successor to SSL, provides the mechanisms to ensure authentication, non-repudiation, confidentiality, and integrity of user communications to and between the SUSE OpenStack Cloud services from internal and public endpoints.

OpenStack endpoints are HTTP (REST) services providing APIs to other OpenStack services on the management network. All traffic to OpenStack services coming in on the public endpoints and some traffic between services can be secured using TLS connections.

In SUSE OpenStack Cloud 8, the following are enabled for TLS

  • API endpoints in the internal and admin VIPs can now be secured by TLS.

  • API endpoints can be provided with their own certificates (this is shown in the model examples) or they can simply use the default certificate.

  • The Barbican key management service API can be secured by TLS from the load balancer to the service endpoint.

  • You can add multiple trust chains (certificate authority (CA) certificates).

  • Fully qualified domain names (FQDNs) can be used for public endpoints and now they can be changed. The external name in the input model files (in ~/openstack/my_cloud/definition/data/network_groups.yml) is where the domain name is indicated and changed.

  • There are two monitoring alarms specific to certificates, 14-days to certificate expiration and 1-day to expiration.

  • TLS can be turned off/on for individual endpoints.

7.1 Comparing Clean Installation and Upgrade of SUSE OpenStack Cloud Edit source

Clean install: all TLS-encrypted services are already listed under tls-components in network_groups.yml

You just have to:

  • Add your self-signed CA cert and server cert (for testing)

  • Or add your public (or company) CA-signed server cert and the public (or company) CA cert (for production)

Upgrade: you do not have TLS enabled already on the internal endpoints so you need to

  • Add your self-signed CA cert and server cert (for testing)

  • Or add your public (or company) CA-signed server cert and the public (or company) CA cert (for production)

  • Add all the services to tls-components in network_groups.yml

For information on enabling and disabling TLS, see Section 7.2, “TLS Configuration”.

For instructions on installing certificates, see Section 7.2, “TLS Configuration”.

7.2 TLS Configuration Edit source

In SUSE OpenStack Cloud 8, you can provide your own certificate authority and certificates for internal and public virtual IP addresses (VIPs), and you should do so for any production cloud. The certificates automatically generated by SUSE OpenStack Cloud are useful for testing and setup, but you should always install your own for production use. Certificate installation is discussed below.

7.2.1 Using the Default My Public Cert Edit source

Read the following if you are using the default cert-name: my-public-cert in your model.

The bundled test cert for public endpoints, located at ~/openstack/my_cloud/config/tls/certs/my-public-cert, is now expired but was left in the product in case you changed the content with your valid cert. Please verify if the certificate is expired and generate your own by following the guidelines further down on this page or by using a generic instruction from the web.

You can verify the expiry by running this command:

openssl x509 -in ~/openstack/my_cloud/config/tls/certs/my-public-cert -noout -enddate
notAfter=Feb 12 01:18:46 2019 GMT

7.2.2 Certificate Terms Edit source

Before you begin, the following list of terms will be helpful when generating and installing certificates.

Openstack-generated public CA

An OpenStack-generated public CA (openstack_frontend_cacert.crt) is available for you in /usr/local/share/ca-certificates.

Fully qualified domain name (FQDN) of the public VIP

The registered domain name. A FQDN is not mandatory. It is valid to have no FQDN and use IP addresses instead. You can use FQDNs on public endpoints, and you may change them whenever the need arises.

Certificate authority (CA) certificate

Your certificates must be signed by a CA, such as your internal IT department or a public certificate authority. For this example we will use a self-signed certificate.

Server certificate

It is easy to confuse server certificates and CA certificates. Server certificates reside on the server and CA certificates reside on the client. A server certificate affirms that the server that sent it serves a set of IP addresses, domain names, and set of services. A CA certificate is used by the client to authenticate this claim.

SAN (subject-alt-name)

The set of IP addresses and domain names in a server certificate request: A template for a server certificate.

Certificate signing request (CSR)

A blob of data generated from a certificate request and sent to a CA, which would then sign it, produce a server certificate, and send it back.

External VIP

External virtual IP address

Internal VIP

Internal virtual IP address

The major difference between an external VIP certificate and an internal VIP certificate is that the internal VIP has approximately 40 domain names in the SAN. This is because each service has a different domain name in SUSE OpenStack Cloud 8. So it is unlikely that you can create an internal server certificate before running the configuration processor. But after a configuration processor run, a certificate request would be created for each of your cert-names.

7.2.3 Configuring TLS in the input model Edit source

For this example certificate configuration, let us assume there is no FQDN for the external VIP and that you are going to use the default IP address provided by SUSE OpenStack Cloud 8. Let's also assume that for the internal VIP you will use the defaults as well. If you were to call your certificate authority "example-CA," the CA certificate would then be called "example-CA.crt" and the key would be called "example-CA.key." In the following examples, the external VIP certificate will be named "example-public-cert" and the internal VIP certificate will be named "example-internal-cert."

Any time you make a cert change when using your own CA:

  • You should use a distinct name from those already existing in config/tls/cacerts. This also means you should not reuse your CA names. You should use unique and distinguishable names such as MyCompanyXYZ_PrivateRootCA.crt. A new name is what indicates that a file is new or changed, so reusing a name means that the file is not considered changed even its contents have changed.

  • You should not remove any existing CA files from config/tls/cacerts.

  • If you want to remove an existing CA use the following steps:

    1. Remove the file.

    2. Then run:

      ansible -i hosts/verb_hosts FND-STN -a 'sudo keytool -delete -alias debian:<filename to remove> \
      -keystore /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/cacerts -storepass changeit'
Important
Important

Be sure to install your own certificate for all production clouds after installing and testing your cloud. If you ever want to test or troubleshoot later, you will be able to revert to the sample certificate to get back to a stable state for testing.

Note
Note

Unless this is a new deployment, do not update both the certificate and the CA together. Add the CA first and then run a site deploy. Then update the certificate and run tls-reconfigure, FND-CLU-stop, FND-CLU-start and then hlm-reconfigure. If a playbook has failed, rerun it with -vv to get detailed error information. The configure, HAproxy restart, and reconfigure steps are included below. If this is a new deployment and you are adding your own certs/CA before running site.yml this caveat does not apply.

You can add your own certificate by following the instructions below. All changes must go into the following file:

~/openstack/my_cloud/definition/data/network_groups.yml

The entries for TLS for the internal and admin load balancers are:

- provider: ip-cluster
        name: lb
        tls-components:
        - default
        components:
        # These services do not currently support TLS so they are not listed
        # under tls-components
        - nova-metadata
        roles:
        - internal
        - admin
        cert-file: openstack-internal-cert
        # The openstack-internal-cert is a reserved name and
        # this certificate will be autogenerated. You
        # can bring in your own certificate with a different name

        # cert-file: customer-provided-internal-cert
        # replace this with name of file in "config/tls/certs/"

The configuration processor will also create a request template for each named certificate under info/cert_reqs/, which looks like:

info/cert_reqs/customer-provided-internal-cert

7.2.4 Generating and Signing Certificates Edit source

These request templates contain the subject Alt-names that the certificates need. You can add to this template before generating your certificate signing request.

You would then send the CSR to your CA to be signed, and once you receive the certificate, place it in config/tls/certs

When you bring in your own certificate, you may want to bring in the trust chains (or CA certificate) for this certificate. This is usually not required if the CA is a public signer that is typically bundled with the operating system. However, we suggest you include it anyway by copying the file into the directory config/cacerts/.

7.2.5 User-provided certificates and trust chains Edit source

SUSE OpenStack Cloud generates its own internal certificates but is designed to allow you to bring in your own certificates for the VIPs. Here is the general process.

  1. You must have a server certificate and a CA certificate to go with it (unless the signer is a public CA and it is already bundled with most distributions).

  2. You must decide the names of the server certificates and configure the network_groups.yml file in the input model such that each load balancer provider has at least one cert-name associated with it.

  3. Run the configuration processor. You may or may not have the certificate file at this point. The configuration processor would create certificate request file artefacts under info/cert_reqs/ for each of the cert-name(s) in the network_groups.yml file. While there is no special reason to use the request file created for an external endpoint VIP certificate, it is important to use the request files created for internal certificates since the canonical names for the internal VIP as there can be many of them and they will be service specific. Each of these needs to be in the Subject Alt Names attribute of the. certificate.

  4. Create a certificate signing request for this request file and send it to your internal CA or a public CA to get it certified and issued with a certificate. You will now have a server certificate and possibly a trust chain or CA certificate.

  5. Upload to the Cloud Lifecycle Manager. Server certificates should be added to config/tls/certs and CA certificates should be added to config/tls/cacerts. The file extension should be .crt for the CA certificate to be processed by SUSE OpenStack Cloud. Detailed steps are next.

7.2.6 Edit the Input Model to Include Your Certificate Files Edit source

  1. Edit the load balancer configuration in openstack/my_cloud/definition/data/network_groups.yml:

    load-balancers:
     - provider: ip-cluster
     name: lb
     tls-components:
     - default
     components:
     - cassandra
     - nova-metadata
     roles:
     - internal
     - admin
     cert-file: example-internal-cert #<<<-------- Certificate name for the internal VIP
    
    - provider: ip-cluster
     name: extlb
     external-name: myardana.test #<<<------ Use just IP for the external VIP in this example
     tls-components:
     - default
     roles:
     - public
     cert-file: example-public-cert #<<<-------- Certificate name for the external VIP
  2. Commit your changes to the local git repository and run the configuration processor:

    cd ~/openstack/ardana/ansible
    git add -A
    git commit -m "changed VIP certificates"
    ansible-playbook -i hosts/localhost config-processor-run.yml
  3. Verify that certificate requests have been generated by the configuration processor for every certificate file configured in the networks_groups.yml file. In this example, there are two files, as shown from the list command:

    ls ~/openstack/my_cloud/info/cert_reqs
    example-internal-cert
    example-public-cert

7.2.7 Generating a Self-signed CA Edit source

Note
Note

In a production setting you will not perform this step. You will use your company's CA or a valid public CA.

This section demonstrates to how you can create your own self-signed CA and then use this CA to sign server certificates. This CA can be your organization's IT internal CA that is self-signed and whose CA certificates are deployed on your organization's machines. This way the server certificate becomes legitimate.

  1. Copy the commands below to the command line and execute. This will cause the two files to be created: example-CA.key and example-CA.crt.

    export EXAMPLE_CA_KEY_FILE='example-CA.key'
    export EXAMPLE_CA_CERT_FILE='example-CA.crt'
    openssl req -x509 -batch -newkey rsa:2048 -nodes -out "${EXAMPLE_CA_CERT_FILE}" \
    -keyout "${EXAMPLE_CA_KEY_FILE}" \
    -subj "/C=UK/O=hp/CN=YourOwnUniqueCertAuthorityName" \
    -days 365

    You can tweak the subj and days settings above to meet your needs, or to test. For instance, if you want to test what happens when a CA expires, you can set 'days' to a very low value.

  2. Select the configuration processor-generated request file from info/cert_reqs/:

    cat ~/openstack/my_cloud/info/cert_reqs/example-internal-cert
  3. Copy this file to your working directory and append a .req extension to it.

    cp ~/openstack/my_cloud/info/cert_reqs/example-internal-cert \
      example-internal-cert.req
Example 7.1: Certificate request file

The certificate request file should look similar to the following example:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[ req_distinguished_name ]
CN = "openstack-vip"

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = "deployerincloud-ccp-c0-m1-mgmt"
DNS.2 = "deployerincloud-ccp-vip-CEI-API-mgmt"
DNS.3 = "deployerincloud-ccp-vip-CND-API-mgmt"
[...]
DNS.47 = "192.168.245.5"
IP.1 = "192.168.245.5"

=============end of certificate request file.
Note
Note

In the case of a public VIP certificate, please add all the FQDNs you want it to support Currently, SUSE OpenStack Cloud does not add the hostname for the external-name specified in network_groups.yml to the certificate request file. However, you can add it to the certificate request file manually. Here we assume that myopenstack.test is your external-name. In that case you would add this line (to the full sample certificate request file shown in Example 7.1, “Certificate request file”):

DNS.48 = "myopenstack.test"
Note
Note

Any attempt to use IP addresses rather than FQDNs in certificates must use subject alternate name entries that list both the IP address (needed for Google) and DNS with an IP (needed for a Python bug workaround). Failure to create the certificates in this manner will cause future installations of Go-based tools (such as Cloud Foundry, Stackato and other PaaS components) to fail.

In the case of a public VIP certificate, add all the FQDNs you want it to support. Openstack does not add the hostname for the external-name specified in network_groups.yml to the certificate request file. However, you can add it to the certificate request file manually. Assume that myopenstack.test is your external-name. In that case you would add this line to the full sample certificate request file shown above.

DNS.48 = "myopenstack.test"
Note
Note

Any attempt to use IP addresses rather than FQDNs in certificates must use subject alternate name entries that list both the IP address (needed for Google) and DNS with an IP (needed for a Python bug workaround). Failure to create the certificates in this manner will cause future installations of Go-based tools (such as Cloud Foundry, Stackato and other PaaS components) to fail.

7.2.8 Generate a Certificate Signing Request Edit source

Note
Note

In a production setting you will not perform this step. You will use your company's CA or a valid public CA.

Now that you have a CA and a certificate request file, it is time to generate a CSR.

Note
Note

Please use a unique CN for your example Certificate Authority and do not install multiple CA certificates with the same CN into your cloud.

export EXAMPLE_SERVER_KEY_FILE='example-internal-cert.key'
export EXAMPLE_SERVER_CSR_FILE='example-internal-cert.csr'
export EXAMPLE_SERVER_REQ_FILE=example-internal-cert.req
openssl req -newkey rsa:2048 -nodes -keyout "$EXAMPLE_SERVER_KEY_FILE" \
-out "$EXAMPLE_SERVER_CSR_FILE" -extensions v3_req -config "$EXAMPLE_SERVER_REQ_FILE"

In production you would usually send the generated example-internal-cert.csr file to your IT department. But in this example you are your own CA, so sign and generate a server certificate.

7.2.9 Generate a Server Certificate Edit source

Note
Note

In a production setting you will not perform this step. You will send the CSR created in the previous section to your company CA or a to a valid public CA and have them sign and send you back the certificate.

This section demonstrates how you would use the self-signed CA that you created earlier to sign and generate a server certificate. A server certificate is essentially a signed public key, the signer being a CA and trusted by a client. When you install this signed CA's certificate (called CA certificate or trust chain) on the client machine, you are telling the client to trust this CA, and to implicitly trust any server certificates that are signed by this CA. This creates a trust anchor.

CA configuration file

When the CA signs the certificate, it uses a configuration file that tells it to verify the CSR. Note that in a production scenario the CA takes care of this for you.

  1. Create a file called openssl.cnf and add the following contents to it.

    # Copyright 2010 United States Government as represented by the
    # Administrator of the National Aeronautics and Space Administration.
    # All Rights Reserved.
    #...
    
    # OpenSSL configuration file.
    #
    
    # Establish working directory.
    
    dir = .
    
    [ ca ]
    default_ca = CA_default
    
    [ CA_default ]
    serial = $dir/serial
    database = $dir/index.txt
    new_certs_dir = $dir/
    certificate = $dir/cacert.pem
    private_key = $dir/cakey.pem
    unique_subject = no
    default_crl_days = 365
    default_days = 365
    default_md = md5
    preserve = no
    email_in_dn = no
    nameopt = default_ca
    certopt = default_ca
    policy = policy_match
    copy_extensions = copy
    
    [ policy_match ]
    countryName = optional
    stateOrProvinceName = optional
    organizationName = optional
    organizationalUnitName = optional
    commonName = supplied
    emailAddress = optional
    
    [ req ]
    default_bits = 1024 # Size of keys
    default_keyfile = key.pem # name of generated keys
    default_md = md5 # message digest algorithm
    string_mask = nombstr # permitted characters
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    x509_extensions = v3_ca
    
    [ req_distinguished_name ]
    # Variable name Prompt string
    #---------------------- ----------------------------------
    0.organizationName = Organization Name (company)
    organizationalUnitName = Organizational Unit Name (department, division)
    emailAddress = Email Address
    emailAddress_max = 40
    localityName = Locality Name (city, district)
    stateOrProvinceName = State or Province Name (full name)
    countryName = Country Name (2 letter code)
    countryName_min = 2
    countryName_max = 2
    commonName = Common Name (hostname, IP, or your name)
    commonName_max = 64
    
    [ v3_ca ]
    basicConstraints = CA:TRUE
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer:always
    subjectAltName = @alt_names
    
    [ v3_req ]
    basicConstraints = CA:FALSE
    subjectKeyIdentifier = hash
    
    [ alt_names ]
    
    ######### end of openssl.cnf #########
  2. Sign the server certificate with your CA. Copy the comands below to the command line and execute. This will cause the file, example-internal-cert.crt, to be created.

    export EXAMPLE_SERVER_CERT_FILE='example-internal-cert.crt'
    export EXAMPLE_SERVER_CSR_FILE='example-internal-cert.csr'
    export EXAMPLE_CA_KEY_FILE='example-CA.key'
    export EXAMPLE_CA_CERT_FILE='example-CA.crt'
    
    touch index.txt
    openssl rand -hex -out serial 6
    
    openssl ca -batch -notext -md sha256 -in "$EXAMPLE_SERVER_CSR_FILE" \
    -cert "$EXAMPLE_CA_CERT_FILE" \
    -keyfile "$EXAMPLE_CA_KEY_FILE" \
    -out "$EXAMPLE_SERVER_CERT_FILE" \
    -config openssl.cnf -extensions v3_req
  3. Concatenate both the server key and certificate in preparation for uploading to the Cloud Lifecycle Manager.

    cat example-internal-cert.key example-internal-cert.crt > example-internal-cert
  4. You have only created the internal-cert in this example. Repeat the above sequence for example-public-cert. Make sure you use the appropriate certificate request generated by the configuration processor.

7.2.10 Upload to the Cloud Lifecycle Manager Edit source

  1. The two files created from the example above will need to be uploaded to the Cloud Lifecycle Manager and copied into config/tls:

    • example-internal-cert

    • example-CA.crt

  2. On the Cloud Lifecycle Manager, execute the following copy commands. If you created an external cert, copy that in a similar manner.

    cp example-internal-cert ~/openstack/my_cloud/config/tls/certs/
    cp example-CA.crt ~/openstack/my_cloud/config/tls/cacerts/
  3. Log into the Cloud Lifecycle Manager node. Save and commit the changes to the local Git repository:

    cd ~/openstack/ardana/ansible
    git add -A
    git commit -m "updated certificate and CA"
  4. Rerun the config-processor-run playbook, and run ready-deployment.yml:

    cd ~/openstack/ardana/ansible
    ansible-playbook -i hosts/localhost config-processor-run.yml
    ansible-playbook -i hosts/localhost ready-deployment.yml
  5. If you receive any prompts, enter the required information.

    Note
    Note

    For automated installation (for example, CI) you can specify the required passwords on the Ansible command line. For example, the command below will disable encryption by the configuration processor:

    ansible-playbook -i hosts/localhost config-processor-run.yml -e encrypt="" -e rekey=""
  6. Run this series of runbooks to complete the deployment:

    cd ~/scratch/ansible/next/ardana/ansible
    ansible-playbook -i hosts/verb_hosts tls-reconfigure.yml
    ansible-playbook -i hosts/verb_hosts FND-CLU-stop.yml
    ansible-playbook -i hosts/verb_hosts FND-CLU-start.yml
    ansible-playbook -i hosts/verb_hosts monasca-stop.yml
    ansible-playbook -i hosts/verb_hosts monasca-start.yml
    ansible-playbook -i hosts/verb_hosts ardana-reconfigure.yml

7.2.11 Configuring the Cipher Suite Edit source

By default, the cipher suite is set to: HIGH:!aNULL:!eNULL:!DES:!3DES. This setting is recommended in the OpenStack documentation. You may override this by editing config/haproxy/defaults.yml. The parameters can be found under the haproxy_globals list.

- "ssl-default-bind-ciphers HIGH:!aNULL:!eNULL:!DES:!3DES"
- "ssl-default-server-ciphers HIGH:!aNULL:!eNULL:!DES:!3DES"

Make the changes as needed. Keep the two options identical.

7.2.12 Testing Edit source

You can determine if an endpoint is behind TLS by running the following command, which probes a Keystone identity service endpoint that is behind TLS:

tux > echo | openssl s_client -connect 192.168.245.5:5000 | \
  openssl x509 -fingerprint -noout
depth=0 CN = openstack-vip
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = openstack-vip
verify error:num=27:certificate not trusted
verify return:1
depth=0 CN = openstack-vip
verify error:num=21:unable to verify the first certificate
verify return:1
DONE
SHA1 Fingerprint=C6:46:1E:59:C6:11:BF:72:5E:DD:FC:FF:B0:66:A7:A2:CC:32:1C:B8

The next command probes a MariaDB endpoint that is not behind TLS:

echo | openssl s_client -connect 192.168.245.5:3306 | openssl x509 -fingerprint -noout
140448358213264:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:795:
unable to load certificate
140454148159120:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: TRUSTED CERTIFICATE

7.2.13 Verifying That the Trust Chain is Correctly Deployed Edit source

You can determine if the trust chain is correctly deployed by running the following commands:

tux > echo | openssl s_client -connect 192.168.245.9:5000 2>/dev/null \
  | grep code
Verify return code: 21 (unable to verify the first certificate)
tux > echo | openssl s_client -connect 192.168.245.9:5000 -CAfile \
  /usr/local/share/ca-certificates/openstack_frontend_cacert.crt 2>/dev/null \
  | grep code
Verify return code: 0 (ok)

The first command produces error 21, which is then fixed by providing the CA certificate file. This verifies that the CA certificate matches the server certificate.

7.2.14 Turning TLS on or off Edit source

You should leave TLS enabled in production. However, if you need to disable it for any reason, you must change tls-components to components in network_groups.yml (as shown earlier) and comment out the cert-file. Additionally, if you have a network_groups.yml file from a previous installation, TLS will not be enabled unless you change components to tls-components in that file. By default, Horizon is configured with TLS in the input model. You should not disable TLS in the input model for Horizon as that is a public endpoint and is required. Additionally, you should keep all services behind TLS, but using the input model file network_groups.yml you may turn TLS off for a service for troubleshooting or debugging. TLS should always be enabled for production environments.

If you are using an example input model on a clean install, all supported TLS services will be enabled before deployment of your cloud. If you want to change this setting later, such as when upgrading, you can change the input model and reconfigure the system. The process is as follows:

  1. Edit the input model network_groups.yml file appropriately as described above, changing tls-components to components.

  2. Commit the changes to the Git repository:

    cd ~/openstack/ardana/ansible/
    git add -A
    git commit -m "TLS change"
  3. Change directories again and run the configuration processor and ready deployment playbooks:

    ansible-playbook -i hosts/localhost config-processor-run.yml
    ansible-playbook -i hosts/localhost ready-deployment.yml
  4. Change directories again and run the reconfigure playbook:

    cd ~/scratch/ansible/next/ardana/ansible
    ansible-playbook -i hosts/verb_hosts ardana-reconfigure.yml

7.3 Enabling TLS for MySQL Traffic Edit source

MySQL traffic can be encrypted using TLS. For completely new SUSE OpenStack Cloud deployments using the supplied input model example files, you will have to uncomment the commented entries for tls-component-endpoints:. For upgrades from a previous version, you will have to add the entries to your input model files if you have not already done so. This topic explains how to do both.

7.3.1 Enabling TLS on the database server for client access Edit source

  1. Edit network_groups.yml to either add mysql under tls-component-endpoints in your existing file from a previous version, or uncomment it if installing from scratch.

    tls-component-endpoints:
      - mysql
  2. After making the necessary changes, commit the changed file to git and run the config-processor-run and reconfigure Ansible playbooks:

    cd ~/openstack
    git add -A
    git commit -m "My changed config"
    cd ~/openstack/ardana/ansible/
    ansible-playbook -i hosts/localhost config-processor-run.yml -e encrypt="<encryption key>" -e rekey=""
    ansible-playbook -i hosts/localhost ready-deployment.yml
    cd ~/scratch/ansible/next/ardana/ansible
  3. Next, either run site.yml if you are installing a new system:

    ansible-playbook -i hosts/verb_hosts site.yml
  4. or ardana-reconfigure if you are reconfiguring an existing one:

    ansible-playbook -i hosts/verb_hosts ardana-reconfigure.yml

7.3.2 MySQL replication over TLS Edit source

MySQL replication over TLS is disabled. This is true even if you followed the instruction to turn on Mysql TLS in the previous section. Those steps turn on the service interactions to the database.

Turning on MySQL replication over TLS

Note
Note

Using TLS connections for MySQL replication will incur a performance cost.

You should have already enabled TLS for MySQL client interactions in the previous section. If not, read Section 7.3.1, “Enabling TLS on the database server for client access”.

TLS for MySQL replication is not turned on by default. Therefore, you will need to follow a manual process. Again, the steps are different for new systems and upgrades.

7.3.3 Enabling TLS for MySQL replication on a new deployment Edit source

  1. Log in to the Cloud Lifecycle Manager node and before running the config processor, edit the ~/openstack/my_cloud/config/mariadb/defaults.yml file.

  2. Search for mysql_gcomms_bind_tls. You should find this section:

    # TLS disabled for cluster
    #mysql_gcomms_bind_tls: "{{ host.bind['FND_MDB'].mysql_gcomms.tls }}"
    mysql_gcomms_bind_tls: False
  3. Uncomment the appropriate line so the file looks like this:

    # TLS disabled for cluster
    mysql_gcomms_bind_tls: "{{ host.bind['FND_MDB'].mysql_gcomms.tls }}"
    #mysql_gcomms_bind_tls: False
  4. Follow the steps to deploy or reconfigure your cloud: Step 2 in Section 7.3.1, “Enabling TLS on the database server for client access”.

7.3.4 Enabling TLS for MySQL replication on an existing system Edit source

If your cluster is already up, perform these steps to enable MySQL replication over TLS:

  1. Edit the following two files: ~/openstack/my_cloud/config/mariadb/defaults.yml and ~/scratch/ansible/next/ardana/ansible/roles/FND-MDB/defaults/main.yml. Note that these files are identical. The first is a master file and the second is a scratch version that is used for the current deployment. Make the same changes as explained in Section 7.3.3, “Enabling TLS for MySQL replication on a new deployment”.

  2. Then run the following command:

    ansible-playbook -i hosts/verb_hosts tls-percona-reconfigure.yml

    After this your MySQL should come up and replicate over TLS. You need to follow this section again if you ever want to switch TLS off for MySQL replication. You also must repeat these steps if any lifecycle operation changes the mysql_gcomms_bind_tls option.

7.3.5 Testing whether a service is using TLS Edit source

Almost all services that have a database are able to communicate over TLS. You can test whether a service, in this example the Identity service (Keystone), is communicating with MySQL over TLS by executing the following steps:

  1. Log into the Cloud Lifecycle Manager as root and run the mysql command.

    root@<server>:~# mysql

    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

  2. Run:

    mysql> select * from information_schema.user_statistics where user='keystone'\G
  3. Note the results. TOTAL_SSL_CONNECTIONS should not be zero:

    *************************** 1. row ***************************
                      USER: keystone
         TOTAL_CONNECTIONS: 316
    CONCURRENT_CONNECTIONS: 0
            CONNECTED_TIME: 905790
                 BUSY_TIME: 205
                  CPU_TIME: 141
            BYTES_RECEIVED: 197137617
                BYTES_SENT: 801964
      BINLOG_BYTES_WRITTEN: 0
              ROWS_FETCHED: 972421
              ROWS_UPDATED: 6893
           TABLE_ROWS_READ: 1025866
           SELECT_COMMANDS: 660209
           UPDATE_COMMANDS: 3039
            OTHER_COMMANDS: 299746
       COMMIT_TRANSACTIONS: 0
     ROLLBACK_TRANSACTIONS: 295200
        DENIED_CONNECTIONS: 0
          LOST_CONNECTIONS: 83
             ACCESS_DENIED: 0
             EMPTY_QUERIES: 71778
     TOTAL_SSL_CONNECTIONS: 298
    1 row in set (0.00 sec)
    
    mysql>

7.4 Enabling TLS for RabbitMQ Traffic Edit source

RabbitMQ traffic can be encrypted using TLS. To enable it, you will have to add entries for tls-component-endpoints: in your input model files if you have not already done so. This topic explains how.

  1. Edit openstack/my_cloud/definition/data/network_groups.yml, adding rabbitmq to the tls-component-endpoints section:

    tls-component-endpoints:
         - barbican-api
         - mysql
         - rabbitmq
  2. Commit the changes:

    cd ~/openstack
    git add -A
    git commit -m "My changed config"
  3. Then run the typical deployment steps:

    cd ~/openstack/ardana/ansible/
    ansible-playbook -i hosts/localhost config-processor-run.yml -e encrypt="<encryption key>" -e rekey=""
    ansible-playbook -i hosts/localhost ready-deployment.yml
  4. Change directories:

    cd ~/scratch/ansible/next/ardana/ansible
  5. Then for a fresh TLS install run:

    ansible-playbook -i hosts/verb_hosts site.yml
  6. Or, to reconfigure an existing system run:

    ansible-playbook -i hosts/verb_hosts ardana-reconfigure.yml

7.4.1 Testing Edit source

On the one of the rabbitmq nodes you can list the clients and their TLS status by running:

$ sudo rabbitmqctl -q list_connections ssl state ssl_protocol user name

You will see output like this where true indicates the client is using TLS for the connection, and false, as shown here, indicates the connection is over TCP:

Listing connections ...

rmq_barbican_user       false

Other indicators will be rabbit_use_ssl = True in the Oslo messaging section of client configurations. The list of clients that support TLS are as follows:

  • Barbican

  • Ceilometer

  • Cinder

  • Designate

  • Eon

  • Glance

  • Heat

  • Ironic

  • Keystone

  • Monasca

  • Neutron

  • Nova

  • Octavia

7.5 Troubleshooting TLS Edit source

7.5.1 Troubleshooting TLS certificate errors when running playbooks with a limit Edit source

Has the deployer been restarted after the original site installation or is this a new deployer? If so, TLS certificates need to be bootstrapped before a playbook is run with limits. You can do this by running the following command.

cd ~/scratch/ansible/next/ardana/ansible
ansible-playbook -i hosts/verb_hosts tls-reconfigure.yml --limit TLS-CA

7.5.2 Certificate Update Failure Edit source

In general, if a certificate update fails, it is because of the following: Haproxy has not restarted or the Trust chain is not installed. This is the certificate of the CA that signed the server certificate.

7.5.3 Troubleshooting trust chain installation Edit source

It is important to note that while SUSE OpenStack Cloud 8 allows you to add new trust chains, it would be better if you add all the required trust chains during the initial deploy. Trust chain changes can impact services.

However, this does not apply to certificates. There is a certificate-related issue whereby haproxy is not restarted if certificate content has been changed but the certificate file name remained the same. If you are having issues and you have replaced the content of existing CA file with new content, create another CA file with a new name. Also make sure the CA file has a .crt extension.

Do not update both certificate and the CA together. Add the CA first and then run a site deploy. Then update the certificate and run tls-reconfigure, FND-CLU-stop, FND-CLU-start and then ardana-reconfigure. If you know which playbook failed, rerun it with -vv to get detaled error information. The configure, HAproxy restart, and reconfigure steps are included in Section 7.2, “TLS Configuration”.

You can run the following commands to see if client libraries see the CA you have added:

~/scratch/ansible/next/ardana/ansible$ ansible -i hosts/verb_hosts FND-STN -a 'sudo keytool -list -alias \
    debian:username-internal-cacert-001.pem -keystore /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/cacerts -storepass changeit'
  padawan-ccp-c0-m1-mgmt | FAILED | rc=1 >>
  sudo: keytool: command not found

  padawan-ccp-comp0001-mgmt | FAILED | rc=1 >>
  sudo: keytool: command not found

  padawan-ccp-comp0003-mgmt | FAILED | rc=1 >>
  sudo: keytool: command not found

  padawan-ccp-comp0002-mgmt | FAILED | rc=1 >>
  sudo: keytool: command not found

  padawan-ccp-c1-m1-mgmt | success | rc=0 >>
  debian:username-internal-cacert-001.pem, May 9, 2016, trustedCertEntry,
  Certificate fingerprint (SHA1): E7:B2:6E:9E:00:FB:86:0F:E5:46:CD:B8:C5:67:13:53:4E:3D:8F:43

  padawan-ccp-c1-m2-mgmt | success | rc=0 >>
  debian:username-internal-cacert-001.pem, May 9, 2016, trustedCertEntry,
  Certificate fingerprint (SHA1): E7:B2:6E:9E:00:FB:86:0F:E5:46:CD:B8:C5:67:13:53:4E:3D:8F:43

  padawan-ccp-c1-m3-mgmt | success | rc=0 >>
  debian:username-internal-cacert-001.pem, May 9, 2016, trustedCertEntry,
  Certificate fingerprint (SHA1): E7:B2:6E:9E:00:FB:86:0F:E5:46:CD:B8:C5:67:13:53:4E:3D:8F:43

Java client libraries are used by Monasca, so compute nodes will not have them. So the first three errors are expected. Check that the fingerprint is correct by checking the CA:

~/scratch/d002-certs/t002$ openssl x509 -in example-CA.crt -noout -fingerprint
  SHA1 Fingerprint=E7:B2:6E:9E:00:FB:86:0F:E5:46:CD:B8:C5:67:13:53:4E:3D:8F:43

If they do not match, there likely was a name collision. Add the CA cert again with a new file name. If you get Monasca errors but find that the fingerprints match, try stopping and restarting Monasca.

ansible-playbook -i hosts/verb_hosts monasca-stop.yml
ansible-playbook -i hosts/verb_hosts monasca-start.yml

7.5.4 Expired TLS Certificates Edit source

Use the following steps to re-create expired TLS certificates for MySQL Percona clusters.

  1. Determine if the TLS certificates for MySQL / Percsona have expired.

    ardana > cd /etc/mysql/
    ardana > openssl x509 -noout -enddate -in control-plane-1-mysql-internal-cert.pem
     Not After : Jul 24 12:24:17 2021 GMT
  2. Regenerate the TLS certificates on the deployer.

    ardana > cd ~/scratch/ansible/next/hos/ansible
    ardana > ansible-playbook -i hosts/verb_hosts tls-reconfigure.yml --limit DEPLOYER_HOST
  3. Distribute the regenerated TLS certificates to the MySQL Percona clusters.

    ardana > cd ~/scratch/ansible/next/hos/ansible
    ardana > ansible-playbook -i hosts/verb_hosts --extra-vars "mysql_certs_needs_regeneration=true" tls-percona-reconfigure.yml
  4. Verify Percona cluster status on a controller node

    ardana > sudo mysql -e 'show status'

Use the following steps to re-create expired TLS certificates for RabbitMQ.

  1. Determine if SSL certificate for RabbitMQ is expired

    root # cd /etc/rabbitmq
    root # openssl x509 -noout -text -in control-plane-1-rabbitmq.pem | grep After
    Not After : Nov 6 15:15:38 2018 GMT
  2. Regenerate the TLS certificates on the deployer.

    ardana > cd ~/scratch/ansible/next/hos/ansible
    ardana > ansible-playbook -i hosts/verb_hosts tls-reconfigure.yml --limit DEPLOYER_HOST
  3. Reconfigure RabbitMQ. Certificate will be re-created if the input model is correct.

    ardana > cd ~/scratch/ansible/next/ardana/ansible
    ardana > ansible-playbook -i hosts/verb_hosts --extra-vars "rabbitmq_tls_certs_force_regeneration=true" rabbitmq-reconfigure.yml

7.5.5 Troubleshooting certificates Edit source

Certificates can fail in SUSE OpenStack Cloud 8 due to the following.

  • Trust chain issue. This is dealt with in the previous section

  • Wrong certificate: Compare the fingerprints. If they differ, then you have a wrong certificate somewhere.

  • Date range of the certificate is either in the future or expired: Check the dates and change certificates as necessary, observing the naming cautions above.

  • TLS handshake fails because the client does not support the ciphers the server offers. It is possible that you reused a certificate created for a different network model. Make sure the request file found under info/cert_req/ are used to create the certificate. If not, the service VIP names may not match.