SSL/TLS configuration

Encrypt all API and Dashboard traffic, with your own certificate or a generated one.

Every part of a Zato environment that takes traffic has a TLS port next to its plain-text one - the API load balancer listens on 11224 next to 11223, the Dashboard on 8184 next to 8183, and the OpenAPI console on 8186 next to 8185, with the console's two ports changeable through Zato_Port_OpenAPI_Console and Zato_Port_OpenAPI_Console_SSL. All the TLS ports serve the same certificate: your own zato.pem if you mount one, or a certificate that the container generates on startup.

Publish 8184 and 11224, do not publish 8183 and 11223 - see Disable the plain-text ports.

Use your own SSL certificate

Create a PEM file called zato.pem whose contents are the concatenation of the server's certificate, any intermediate CA certificates and the private key, in that order. If your CA has no intermediate certificates, concatenate only the server's certificate and the private key:

  -----BEGIN CERTIFICATE-----
MIIFeTCCA2GgAwIBAgIUd/cKqWLuUNvn1
...
19f67nsJo8Cd6ESCTPFjQ/eX91jl+y7==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAA3gk
...
JScexp8NvHy850wldVG01wtYNdg37rg==
-----END PRIVATE KEY-----

Mount the file at /opt/hot-deploy/ssl/zato.pem in your startup scripts:

--mount type=bind,source=/path/to/zato.pem,target=/opt/hot-deploy/ssl/zato.pem

Make sure that the mounted file is owned by the user zato inside the container, not by root. Zato picks the certificate up automatically and port 11224 serves it with no further steps. To reach the Dashboard on port 8184 under a custom domain, additionally set the CSRF trusted origins.

Set CSRF trusted origins for the Dashboard

With your own certificate and a custom domain name, set the Zato_Dashboard_CSRF_Trusted_Origins environment variable so that the Dashboard accepts SSL requests for that domain. Without the variable, the Dashboard replies with "CSRF verification failed. Request aborted." when you access it over HTTPS on port 8184.

For instance, if your certificate uses CN=my.dashboard and the Dashboard's address is https://my.dashboard:8184, export:

docker run \
    -e Zato_Dashboard_CSRF_Trusted_Origins="https://my.dashboard:8184" \
    --mount type=bind,source=/path/to/zato.pem,target=/opt/hot-deploy/ssl/zato.pem \
    zatosource/zato-4.1

Require client certificates

Port 11224 can also verify the certificates that API clients present - this is the transport behind the mTLS security definitions that channels use.

Mount the CA that signs your clients' certificates as client-ca.pem:

--mount type=bind,source=/path/to/client-ca.pem,target=/opt/hot-deploy/ssl/client-ca.pem

When the file is present, port 11224 requests a client certificate during the handshake and verifies it against that CA. The certificate is optional by default - clients without one still connect, and each channel enforces its own mTLS definition.

To reject any client without a valid certificate at the handshake itself, set Zato_SSL_Client_Verify=required and do not publish 11223:

docker run \
    -e Zato_SSL_Client_Verify=required \
    --mount type=bind,source=/path/to/client-ca.pem,target=/opt/hot-deploy/ssl/client-ca.pem \
    zatosource/zato-4.1

Which client may call which channel is then decided by the channels' mTLS security definitions.

To accept certificates from more than one CA, concatenate the CA certificates into the one client-ca.pem file.

While client-ca.pem is mounted, port 11554 - the TLS port for HL7 MLLP - verifies the certificates of connecting senders against the same CA. Plain MLLP on port 11553 is unaffected.

The client CA file does not change the main server certificate - zato.pem or the generated certificate keeps serving the server side of the handshake, and the client CA file only adds the verification of clients.

Trust custom Certificate Authorities

If your backend APIs use certificates signed by a private Certificate Authority, Zato needs to trust that CA before it can call them - a common setup in enterprises with internal PKI.

Place the CA certificate in PEM format, for example my-ca.crt, on your host system and mount it under /usr/local/share/ca-certificates/ inside the container:

--mount type=bind,source=/path/to/my-ca.crt,target=/usr/local/share/ca-certificates/my-ca.crt

Then set the Zato_Update_CA_Certificates environment variable to True:

-e Zato_Update_CA_Certificates=True

To trust more than one CA, mount each certificate under /usr/local/share/ca-certificates/ with a different filename - the container adds every certificate from that directory to the system trust store when Zato_Update_CA_Certificates=True.

Disable the plain-text ports

Publish 8184 and 11224, do not publish 8183 and 11223:

docker run \
    -p 8183:8183 \   # Remove this line
    -p 8184:8184 \
    -p 11223:11223 \ # Remove this line
    -p 11224:11224 \
    zatosource/zato-4.1

With only 8184 and 11224 published, the Dashboard and your APIs accept SSL connections alone.

Generated certificates and SSL variables

Without a zato.pem file, Zato generates a self-signed certificate on startup and saves it to /opt/hot-deploy/ssl/auto.pem inside the container - each container generates its own certificate and private key on each start.

The following variables configure SSL behavior. Variables marked "Yes" in the "Auto-gen only" column apply only to generated certificates - Zato ignores them when you mount your own zato.pem. The other variables apply to all SSL connections regardless of where the certificate comes from.

VariableDefaultAuto-gen onlyDescription
Zato_SSL_Subject/C=US/ST=State/L=City/O=Organization/CN=localhostYesCertificate subject - the server's DNS name or IP
Zato_SSL_Subject_Alt_NamesubjectAltName=DNS:localhost,IP:127.0.0.1YesExtra DNS names and IPs on the certificate
Zato_SSL_Cert_Days3650YesValidity period in days
Zato_SSL_Key_AlgorithmecdsaYesKey algorithm, ecdsa or rsa
Zato_SSL_Key_Size4096YesKey size when the algorithm is RSA
Zato_SSL_Protocols(empty)---Minimum protocol, TLSv1.2 or TLSv1.3
Zato_SSL_Ciphers(empty)---Allowed cipher suites
Zato_SSL_DH_Params(empty)---Path to Diffie-Hellman parameters file
Zato_SSL_Extra_Options(empty)---Extra HAProxy SSL options, such as ALPN
Zato_SSL_Client_Verifyoptional---Set to required to reject clients without a valid certificate at the handshake - applies when client-ca.pem is mounted
Zato_Update_CA_CertificatesFalse---Set to True to add the certificates from /usr/local/share/ca-certificates/ to the system trust store

A generated certificate with a custom subject, extra names and a one-year lifetime:

docker run \
    -e Zato_SSL_Subject="/C=GB/ST=London/L=London/O=MyCompany/CN=api.mycompany.com" \
    -e Zato_SSL_Subject_Alt_Name="subjectAltName=DNS:api.example.com,IP:192.168.1.100" \
    -e Zato_SSL_Cert_Days=365 \
    zatosource/zato-4.1

Verify and rotate certificates

Before trusting a configuration, look at what the port really presents:

openssl s_client -connect api.example.com:11224 -servername api.example.com </dev/null

Three parts of the output are worth reading:

  • The certificate chain, and whether the CA that issued it is one that your clients trust
  • Verify return code: 0 (ok), or the reason it is not
  • The negotiated protocol and cipher

To see the expiry date alone:

openssl s_client -connect api.example.com:11224 </dev/null 2>/dev/null | openssl x509 -noout -dates

A certificate that expires stops the environment's TLS traffic, and the expiry date is known in advance - rotate the certificate before that date arrives:

  1. Obtain the new certificate and key, and concatenate them into a new zato.pem, in the same order as in the original file.
  2. Replace the mounted zato.pem with the new file.
  3. Restart the container - see starting and stopping servers.
  4. Confirm with openssl s_client that the port serves the new dates.
Note: Zato warns you before a certificate expires. The certificate expiry rule raises a warning by default 7 days ahead, provided the notification targets are configured - see alert rules. Raise the threshold if renewing a certificate takes you longer than 7 days.

See also

PageWhat it covers
Ports and networkPublish 8184 and 11224, do not publish 8183 and 11223
Environment variablesThe Zato_SSL_* family in the full reference
mTLSPer-channel enforcement of the client certificates that port 11224 verifies

Learn more