SSL/TLS traffic from client applications

Key features:

  • Client applications may invoke services using SSL/TLS
  • Services can be also optionally secured with client certificates
  • Traffic to a Zato cluster is always terminated at the cluster's HAProxy load-balancer which may optionally re-encrypt it using its own crypto material while communicating with servers it fronts for
  • Load-balancer passes SSL/TLS-related information to servers as a set of custom HTTP headers that are always available to services through their self.wsgi_environ dictionary

Tasks described in this chapter

  • Configuring a cluster to accept SSL/TLS connections without client certificates
  • Configuring a cluster to optionally accept SSL/TLS client certificates
  • Configuring a cluster to require SSL/TLS client certificates
  • Configuring channels to require specific fields in client certificates

Accepting SSL/TLS connections - no client certificates

In Dashboard, open the load-balancer's configuration in source code view and add the following entry at the end of the file.

This will make the load-balancer bind to 0.0.0.0:21223 using a private key and certificate stored in a file whose path is /key-and-cert.pem:

    frontend front_tls_no_client_certs

        mode http
        default_backend bck_http_plain
        option forwardfor
        reqadd X-Forwarded-Proto:\ https

        acl has_x_forwarded_proto req.fhdr(X-Forwarded-Proto) -m found
        http-request deny if has_x_forwarded_proto

        bind 0.0.0.0:21223 ssl crt /key-and-cert.pem

Accepting SSL/TLS connections - client certificates optional

In Dashboard, open the load-balancer's configuration in source code view and add the following entry at the end of the file.

This will make the load-balancer bind to 0.0.0.0:31223 with a private key and certificate from /key-and-cert.pem. Additionally, if a connecting application presents any client certificate at all its trust path will be established using CA certificate(s) from /ca-certs.pem.

Requests will be rejected if the client certificate cannot be validated against the CA certificates but if there is no client certificate at all, the request will be allowed in.

  frontend front_tls_optional_client_certs

    mode http
    default_backend bck_http_plain
    option forwardfor
    reqadd X-Forwarded-Proto:\ https

    acl has_x_forwarded_proto req.fhdr(X-Forwarded-Proto) -m found
    http-request deny if has_x_forwarded_proto

    bind 0.0.0.0:31223 ssl crt /key-and-cert.pem verify optional ca-file /ca-certs.pem

Accepting SSL/TLS connections - client certificates required

In Dashboard, open the load-balancer's configuration in source code view and add the following entry at the end of the file.

This will make the load-balancer bind to 0.0.0.0:41223 using a private key and certificate stored in a file whose path is /key-and-cert.pem.

Any connections not using client TLS certificates will be rejected. If a connection does use a client certificate, the certificate will be validated against the CA certificates specified in ca-file.

  frontend front_tls_required_client_certs

    mode http
    default_backend bck_http_plain
    option forwardfor
    reqadd X-Forwarded-Proto:\ https

    acl has_x_forwarded_proto req.fhdr(X-Forwarded-Proto) -m found
    http-request deny if has_x_forwarded_proto

    bind 0.0.0.0:41223 ssl crt /key-and-cert.pem verify required ca-file /ca-certs.pem

Requiring specific fields in client certificates

It is possible to configure TLS channel security definitions to reject incoming requests unless one or more fields, including a fingerprint, are matched. That way Zato can verify not only that a certificate signed off by a known CA was used but also that it was a particular certificate out of possibly many more produced by that CA.

The feature requires the load-balancer to pass fields extracted out of a client certificate to servers that in turn make decision whether the fields suffice or not, i.e. whether there is a match or not.

Note that the client certificate is always validated with CA certificates specified in ca-file no matter if servers additionally require any specific fields or not.

The load-balancer's TLS config must contain either the verify optional or verify required flag, as in the example below which delivers to servers the following fields in custom HTTP headers:

  • The certificate's fingerprint in X-Zato-TLS-Fingerprint
  • The certificate subject's common name (CN) in X-Zato-TLS-Common-Name

The format is X-Zato-TLS-Name where Name is the name of the field that a security definition requires - all fields are always uppercased regardless of how they are spelled out in the load-balancer's configuration.

All the fields the load-balancer can extract, such as ssl_c_sha1, are provided in HAProxy's documentation.

  frontend front_tls_fields

    mode http
    default_backend bck_http_plain
    option forwardfor
    reqadd X-Forwarded-Proto:\ https

    acl has_x_forwarded_proto req.fhdr(X-Forwarded-Proto) -m found
    http-request deny if has_x_forwarded_proto

    bind 0.0.0.0:51223 ssl crt /key-and-cert.pem verify optional ca-file /ca-certs.pem

    http-request set-header X-Zato-TLS-Fingerprint %{+Q}[ssl_c_sha1,hex]
    http-request set-header X-Zato-TLS-Common-Name %{+Q}[ssl_c_s_dn(CN)]

Assuming a client certificate with the following fields ..

    $ openssl x509 -text -in client.pem -fingerprint | grep -E 'Subject:|Finger'
    Subject: C=AU, CN=Client4/emailAddress=Client4
    SHA1 Fingerprint=03:D5:F9:BB:B6:00:3E:86:29:82:3D:6F:81:1D:70:C8:9F:04:0C:2F
    $

.. the load-balancer's configuration allows one to require particular fields on input now, such as below, for certificate pinning:

Note that the certificate's fingerprint will not contain semicolons unlike in the output from openssl.