Skip to main content
Version: 31.1.1

a9s SSL/TLS Service Plans

This topic provides usage guidance for SSL/TLS plans of a9s Data Services.

Providing your own key

By default - if no certificate authority (CA) certificate has been provided - a self-signed certificate is created. However, when creating or updating a data service instance using a SSL plan, it is possible to provide your own certificate, private key, and CA certificate.

caution

a9s Search: OpenSearch expects that the certificates' private keys are in the format PKCS#8. How to generate the correct certificates and keys is explained here.

info

a9s MySQL: MySQL 10.4 has a pre-defined structure on how it expects the different certificates. Due to this structure, it is not possible to provide your own certificate, private key, and CA certificate when using an a9s MySQL service instance.

Example node domain

*.node.dc1.consul

Example service domain

*.service.dc1.consul

Parameters to provide

You can use the -c parameter when using the CF CLI to specify x509 certificates. Use the cf create-service or cf update-service command with an escaped JSON string to do so. If you need to escape a PEM encoded x509 certificate file or private key you can do so using awk:

awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <path to your PEM-encoded certificate file>

The configuration options specified using the -c parameter are:

KeyValueDescription
cacrtA PEM-encoded x509 certificateThe CA certificate with which your certificate has been or will be signed.
wildcrtA PEM-encoded x509 certificateThe leaf certificate to be deployed to your service instance.
wildkeyA private keyThe private key for the certificate specified in wildcrt.

If you specify the wildcrt parameter, you must also specify the wildkey parameter and vice versa. If specified, it will be used in the service instance regardless of any other options. If you specify the cacrt option, it is expected to the be the certificate authority that signed the certificate in wildcrt.

Example

The following command creates an a9s Messaging service instance using an SSL plan and a x509 certificate:

$ cf create-service a9s-messaging37 a9s-messaging-single-nano-ssl msg1 -c '{"cacrt": "-----BEGIN CERTIFICATE-----\nMIIFbjCCA1YCCQCjw+EXPZsMZjANBgkqhkiG9w0BAQsFADB4MQswCQYDVQQGEwJE\nRTERMA8GA1UECAwIU2FhcmxhbmQxFTATBgNVBAcMDFNhYXJicnVlY2tlbjEWMBQG\nA1UECgwNYW55bmluZXMgR21iSDELMAkGA1UECwwCRFMxGjAYBgNVBAMMEXRlc3Qu\nYW55bmluZXMuY29tMCAXDTIyMDcyODEwMjk1OFoYDzIwNTAwODEwMTAyOTU4WjB4\nMQswCQYDVQQGEwJERTERMA8GA1UECAwIU2FhcmxhbmQxFTATBgNVBAcMDFNhYXJi\ncnVlY2tlbjEWMBQGA1UECgwNYW55bmluZXMgR21iSDELMAkGA1UECwwCRFMxGjAY\nBgNVBAMMEXRlc3QuYW55bmluZXMuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A\nMIICCgKCAgEA7KwHFPQrW9oqzheKK2Vo0TqEexlmN92v6u7Rn6FIZD4FFOPqyg9q\n1P/FQld3UUaMio6l7wxyCCzojB5cWpcBrWWb6Lcr4e0aXLOi8B6vVixKftZt0jcE\nQCv8nPHacYcHXw4LwhVMVedXvhwtLbopRVOuRdbdLkfWujew1gnafQ/C2+7ozv7Z\n/1ADXCREjQ4KlPnn1d87ZK7muR4TjZFEh0ZZ7gA3UjimywzQw8wCUIMBXDH8OInr\nYKHY4+yyq7oaliM68H7WYfJURSQZ/Zv1jVCYLs1AXXWMYSy4hnbzGdLrOfg62Lcc\noYrnJc6yV4e0xOXniCYCy9TxOD5kwXkm3yKO+adpD3TR7BqLCKG9KyN9Ih8vrQlC\ni4azZnMQ2EGlEDoV6wN35etEMocC4hB8TRUYQ1KY3TTVSKb9wPAn/4cAuh6F+cPK\nmq19D+z+PWlVaQHwPFwO2p2koTIycd6gjctHlGS/lAWPsoI1nnTtZ2u5PX3r5/B0\n144XuFTDNmI+7ch3jcggIU6hWcWd4qZ++UE1LltuhTGpzqPw/3Vt9TNSkTvpy8B/\nasZPKPZiDkwFsQQY385dtvkCobpJYNC3wtHnr/t4q+gklYR5mO4xMDgNf+bKjTuI\n0Iut0Aj+0uoJxFvTTfLM4EtPLlW2z7YPkY0A4+OaFV8LjPO1ZPyFyrMCAwEAATAN\nBgkqhkiG9w0BAQsFAAOCAgEAfLXs0mymh4jdUc/ghOdXQFkCqMg5E5wSWlfEgzC0\n8oJwAw4TLjynvrMpZtms6DWf0o63NtrNoQPMcJ6+R8oD3Vqn7Q7BDR+F+cKg2c0e\n44xocV5o5vX8xwZ63GScS+ZSIunGvP537XV5Lzyv3dI9e+qjs893mzgAO02ACT34\nTXlDn/bTKAmOOqRaj6yP2HsInCsJetB5pHi3R3buyy9DbAXt6qtt+eySv1U7JU81\nipMoUbv2PdLLfgfJOVGCldpduOwsyFTwHB78MBiT755QWBalYJ/sw47OaYSDFKCX\nmdO913OpXkUZfF3l4l/CkXEUsY6+pMSCoguwgwln3eVPfmNjqG4LtZGOgKMepmcG\nkRNSGsvVKXglcIsPgogkOxUf569FEK5kEtYw0cMn8MCrv358H1xUFXVcitSLKpGM\n3klsZ1tU/ZnwxbSLcuozHhd+YOjy9KSRmUZCA+ORKVhrweWpugbnv0ZRKzXGLC9a\ny1Rj//v5jWMiEAyZNjeSnCNfLx3jlovR3SjcnZZFrVidQi8cZCnAMzzVArnHi/FI\nxpkP5EAqh8q7DmrMY5X11eEuyCmbgPmjji/IVcOJ3NC9hZeOIiSazU3CvDEX6Blm\nmL/NTgnwTnQn5dKSahQgLtFaIve4VNP4aPFXgGdYScd6U8Luo34tD1EWg45kXnkG\nA38=\n-----END CERTIFICATE-----\n", "wildcrt": "-----BEGIN CERTIFICATE-----\nMIIEaTCCAlECCQCjNrxOOvCTgzANBgkqhkiG9w0BAQsFADB4MQswCQYDVQQGEwJE\nRTERMA8GA1UECAwIU2FhcmxhbmQxFTATBgNVBAcMDFNhYXJicnVlY2tlbjEWMBQG\nA1UECgwNYW55bmluZXMgR21iSDELMAkGA1UECwwCRFMxGjAYBgNVBAMMEXRlc3Qu\nYW55bmluZXMuY29tMB4XDTIyMDcyODEwMzE0N1oXDTM2MDQwNTEwMzE0N1owdTEL\nMAkGA1UEBhMCREUxETAPBgNVBAgMCFNhYXJsYW5kMRUwEwYDVQQHDAxTYWFyYnJ1\nZWNrZW4xFjAUBgNVBAoMDWFueW5pbmVzIEdtYkgxCzAJBgNVBAsMAkRTMRcwFQYD\nVQQDDA4qLmFueW5pbmVzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBALBfuvTiCfj0eJ03UaDLPT91qpZvsvKeML9TZ5C5MKG5kOp4GbAl+qcg9SEY\nouYD1niKfrpi2CN1iT7xVhJTQImSxfQO0GXumGlOz/PwCvBm2bTHBzBZl389sDGA\n6od00ailkv1On4DBfMD6okEWgWyWLZ8PdMDcat0SoKxwt4P4ddtvhtYNSNtiM7Po\nag1Lv0Ocha6B1kD8GbJY/murLrCW7ZBUF3i2p075imfEwJiu9U34t79rnPhzaHAX\nshL9VAEFidNAXahK4q2EudjFum+Bd5Ud0EdIfzz1Dn9EUYfFn0mPF+CCfIu1x8n6\nFOwz5Q/0+NRAIHAy9waB8vmP/e8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAwfkC\nH9e8eQX22gpzCp282YFbCq5Zl0eKONZ3hDm0G+ej1hVUIomKVrwJdz8fcYSf5KZw\nn95HuMPNL5w8SgJ3gR5ZNegWlNYL/sKhIk3NDSyv6helSs6dbufy2CMXg51jlpUp\nJWy4Xa4VLv5kPHxi5gZili4eYCh9Z97kxb8K6P3wXnUOhpyOj4LvzyIwXIxG7gXj\nfp0sQ5+GrlwBhNKnPnF3h8fWU4iQjiRp9hwixKO2uetyc3t47U4FBT4NyYuvGbR/\nVYlekHPCCFn7o31p1VJ/qYGqaMoZEfJZv6t2w9WMf4BpNXnyJ1TFCRSJ0QtZC35E\n4ZuHf9O4rVIBTQL0G7edHbXpxUh0au6uvk8Z0QtwDi8p+1gCg85DICUOmqPxALGi\nDzMjDApWMWyru5PeAC6BnVWuF/Gwhq46X4roQZJLke8eAIdYbptCAltuwlIz1foj\n2DsRESyzcyzk/wziSg3Ai42r1dEODcMd3Na0339EpdG/lbK4+hzPcC4Tv/iUH1Xh\nGnyuH+gi40+92VDSGbvFLTlb/alNBY3TWAjJMCrhE3WgcxVTdFkBS/gV3bPghhaw\nVL/2Nv7oTllDWwAZoJ/WKKu0s1a129iwIJ0xkK0NlDkY13DgTQIngZiXTi3Nq9ct\nB4O8e7EElIvg+68UN7u3nyGI9yzVHqoBHjzwIcw=\n-----END CERTIFICATE-----\n", "wildkey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAsF+69OIJ+PR4nTdRoMs9P3Wqlm+y8p4wv1NnkLkwobmQ6ngZ\nsCX6pyD1IRii5gPWeIp+umLYI3WJPvFWElNAiZLF9A7QZe6YaU7P8/AK8GbZtMcH\nMFmXfz2wMYDqh3TRqKWS/U6fgMF8wPqiQRaBbJYtnw90wNxq3RKgrHC3g/h122+G\n1g1I22Izs+hqDUu/Q5yFroHWQPwZslj+a6susJbtkFQXeLanTvmKZ8TAmK71Tfi3\nv2uc+HNocBeyEv1UAQWJ00BdqErirYS52MW6b4F3lR3QR0h/PPUOf0RRh8WfSY8X\n4IJ8i7XHyfoU7DPlD/T41EAgcDL3BoHy+Y/97wIDAQABAoIBAD8x7dD0dNJI9jaO\nrabJa6ajSH4ig6G+4ISNI9yNHkm0LaJ1ae7djNP5URuMskFsOppyNTofVIZQBN8S\npd5nCgbBGkB6Vl1PgjipToV/CsxcbcECVycR0uB6f/kc0eu7BaxBt0sfsrL1oPec\nViqwH6uCm9IUPack0v1nQT7IHFkiQwE9Sg8FDgXoUtaIbzb7oRd/dFStUap6lrvC\nNscjpItU0m9hdwTRUqjqv/Cg066TdYEFdtdL9F8oOtsu0Ix3SkQY3xkUS+9z0FZC\nljHOv3nzLIOBnn0BfXqy2am/evwkwOw8PzDp5RP6FStEWJgwzINvPD77fMrhy511\ndYhtDsECgYEA1jpMlKSYJ674z07Dqk1wuM/joY8EZHRVnp7kWtzOtHcRZjG1Ab/R\nzvEtDr09t1mgBHfC0xTFkzntTj3hTMuKNmqP0ycPL/k5HGdGyCuW7Al7JLweUlbN\nNEG/adxn5EI9QFjs7RmfVFDBlc8yUbwIZSmSyqb5b4fjB77I/6me+n8CgYEA0sPd\n8btgiQl0yZmAsu9hAnMbE3rPB/cfIWoYGN7KNY2xEuQKcW0v2z3th0td44KdxwiL\nlY26V1USzY/MbnHRBGOZw6WBQNSYw9TfjMN6XVv84KGXv7cM31rhsascvY7L+SX/\nKsk69jEQZaPlnRGsPoHkVOBgZnySlXpW6L0V5JECgYBhpVEir6Nq8yYV2CD3jzTC\nCIAJM9ccsqoUEvijMeJF/7++hQmsMnK/kM6o2Tk4SXHWl4AGFoG4Cb9Q2oPHLT9i\nblAAPt19UGvntmtc8gFotSmcJOLtRQNjvlQxPHVeZZLlsaLMr9Ef7W9PiZG2D68D\n7V8rX9ByNc4VybB0WCxOoQKBgQCo83fbyh/FWj4zSQjA52E1bH387Io/UVq0F27/\nqMAhk9apVQIGEMe3EPpyZPj7Yn4FyZTTKsyAK2MqQyZWNoid4xWknuxwwrs+6ErX\ndO+HHTEmBIM3nI4GEb0wBgHA9lIOA+Z7LtpD9eq1/18VvM/9P3SAkWjVXvDGQE6g\nvMpq8QKBgEaFtGhwuPe5/j6HsOJPvOgMPjM3LdQ18nO/NVDNQE8A0KftCdaioAy8\n5wGi2lDy1zmb+dZEMR9rEZpemNeE4jHSMOOPSwz4ZAhb2xpKymbtl/cwSrkiFeoh\n5SCm+DPRKOnxsj+NC4U9/Js8YwribuEI4MOdlOjM/hNxseDCEguE\n-----END RSA PRIVATE KEY-----\n"}'

Creating service instance msg1 in org organization / space test as user@example.com...
OK

Create in progress. Use 'cf services' or 'cf service msg1' to check operation status.

Using Intermediate Certificates

When using intermediate certificates (certificate chain) most a9s Data Services accept them being appended either to the certificate or to the wildcard certificate, in both cases the intermediate certificate can be chained in front or behind of the certificate/wildcard certificate.

However there is one exception: a9s Messaging. Due to the inner workings of RabbitMQ, a9s Messaging only accepts the intermediate certificates (certificate chain) when it is appended immediately after the wildcard certificate. This is shown in the example below:

$ cf create-service a9s-messaging37 a9s-messaging-single-nano-ssl msg1 \
-c "{\"cacrt\":\"<CA_CERTIFICATE>\",\"wildcrt\":\"<WILDCARD_CERTIFICATE><CHAIN_CERTIFICATE>\",\"wildkey\":\"<WILD_KEY>\"}"

Deleting your key

In order to delete a previously deployed certificate from your service instance, you can issue a command similar to the following:

cf update-service msg1 -c '{"wildcrt": "", "wildkey": "", "cacrt": ""}'

In this example, it is assumed the service instance is named msg1.

Using SSL in your apps

To use an a9s Data Service via SSL you will need to trust the certificate. One way to achieve this is to add the CA Certificate to the trusted CAs of your app. You will find a variable called cacrt in the credentials hash provided to your app via the VCAP_SERVICES environment variable.

For some organizations, such as those already operating internal CAs, it might be best to distribute a CA via a custom buildpack in conjunction with providing your own key.

RabbitMQ Go example

Here is a RabbitMQ example of how you might use cacrt in your apps.

RabbitMQ Ruby example

require 'json'
require 'bunny'

vcap_services = JSON.parse(ENV['VCAP_SERVICES'])
credentials = vcap_services['a9s-messaging37'][0]['credentials']
conn = Bunny.new(
credentials['uri'],
tls_ca_certificates: [credentials['cacrt']],
tls: true)

conn.start

Certificate Rotation

Leaf Certificate Rotation

As certificates for service instances with SSL plans expire, there is a need to rotate them regularly. The rotation of the customer-provided leaf certificate and its key can be done by following these steps:

# Set variables with the escaped content of the certificate and the key
INSTANCE_CRT=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_CERTIFICATE_PATH>`
INSTANCE_KEY=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_CERTIFICATE_KEY_PATH>`

# Use jq to create a json from the two variables and store it in another variable
JSON_STRING=$(jq -n --arg wildcrt "$INSTANCE_CRT" --arg wildkey "$INSTANCE_KEY" '$ARGS.named')

# Pass the created JSON as a parameter to CF command
cf update-service postgresql-cluster -c $JSON_STRING

Note that this will only work if the current CA certficate is valid and not expired. This process may cause some downtime in single deployments, as the service instances are updated with the certificate information. If the CA is still valid, there is no downtime on cluster deployments.

CA Certificate Rotation

To create CA certificates that can be used by CF services, some requirements must be followed. To be accepted as a valid certificate by CF, it should have Subject Alternative Names set, and it also should be created using SHA256.

To update the service we recommend to use the following method for a rotation with minimal downtime. First you should set the both CAs, the old and the new one together, along with the old leaf certificate on the service instance:

# Concatenate the CAs and set the variables with the needed certificates
INSTANCE_CACRT=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <OLD_CA_CERTIFICATE_PATH>`
INSTANCE_CACRT="$INSTANCE_CACRT\n`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_CA_CERTIFICATE_PATH>`"
INSTANCE_CRT=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <OLD_LEAF_CERTIFICATE_PATH>`
INSTANCE_KEY=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <OLD_LEAF_CERTIFICATE_KEY_PATH>`

# Build JSON string with the escaped certs
JSON_STRING=$(jq -n --arg wildcrt "$INSTANCE_CRT" --arg wildkey "$INSTANCE_KEY" --arg cacrt "$INSTANCE_CACRT" '$ARGS.named')

# Update CF service
cf update-service postgresql-cluster -c $JSON_STRING

After the service is set with both CAs, you should update it with the new leaf certificates:

# As we have the concatenated CAs already set, replace only the variables for certificate and key
INSTANCE_CRT=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_LEAF_CERTIFICATE_PATH>`
INSTANCE_KEY=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_LEAF_CERTIFICATE_KEY_PATH>`

# Generate the JSON and update the service
JSON_STRING=$(jq -n --arg wildcrt "$INSTANCE_CRT" --arg wildkey "$INSTANCE_KEY" --arg cacrt "$INSTANCE_CACRT" '$ARGS.named')
cf update-service postgresql-cluster -c $JSON_STRING

This step must be done along with the update of the client certificate files. No downtime is expected from the service instance perspective, but until all the nodes are updated with the new leaf certificates, the nodes not updated cannot connect to the service instances.

To finish the process we remove the old CA from the service configuration:

# Escape needed certificates and keys
INSTANCE_CACRT=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_CA_CERTIFICATE_PATH>`
INSTANCE_CRT=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_LEAF_CERTIFICATE_PATH>`
INSTANCE_KEY=`awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' <NEW_LEAF_CERTIFICATE_KEY_PATH>`

# Build JSON string with the escaped certs
JSON_STRING=$(jq -n --arg wildcrt "$INSTANCE_CRT" --arg wildkey "$INSTANCE_KEY" --arg cacrt "$INSTANCE_CACRT" '$ARGS.named')

# Update CF service
cf update-service postgresql-cluster -c $JSON_STRING

As all the nodes will already have the new certificates, no downtime is expected on this step. The certificate rotation is finished.