TLS Certificates

NotifyBC supports HTTPS TLS to achieve end-to-end encryption. In addition, both server and client can be authenticated using certificates.

To enable HTTPS for server authentication only, you need to create two files

  • server/certs/key.pem - a PEM encoded private key
  • server/certs/cert.pem - a PEM encoded X.509 certificate chain

Use ConfigMaps on Kubernetes

Create key.pem and cert.pem as items in ConfigMap notify-bc, then mount the items under /home/node/app/server/certs similar to how config.local.js and middleware.local.js are implemented.

For self-signed certificate, run

openssl req -x509 -newkey rsa:4096 -keyout server/certs/key.pem -out server/certs/cert.pem -nodes -days 365 -subj "/CN=NotifyBC"

to generate both files in one shot.

Caution about self-signed cert

Self-signed cert is intended to be used in non-production environments only to authenticate server. In such environments to allow NotifyBC connecting to itself, environment variable NODE_TLS_REJECT_UNAUTHORIZED must be set to 0.

To create a CSR from the private key generated above, run

openssl req -new -key server/certs/key.pem -out server/certs/csr.pem

Then bring your CSR to your CA to sign. Replace server/certs/cert.pem with the cert signed by CA. If your CA also supplied intermediate certificate in PEM encoded format, say in a file called intermediate.pem, append all of the content of intermediate.pem to file server/certs/cert.pem.

Make a copy of self-signed server/certs/cert.pem

If you want to enable client certificate authentication documented below, make sure to copy self-signed server/certs/cert.pem to server/certs/ca.pem before replacing the file with the cert signed by CA. You need the self-signed server/certs/cert.pem to sign client CSR.

In case you created server/certs/key.pem and server/certs/cert.pem but don't want to enable HTTPS, create following config in src/config.local.js

module.exports = {
  tls: {
    enabled: false,
  },
};

Update URL configs after enabling HTTPS

Make sure to update the protocol of following URL configs after enabling HTTPS

Client certificate authentication

After enabling HTTPS, you can further configure such that a client request can be authenticated using client certificate. To do so, copy self-signed server/certs/cert.pem to server/certs/ca.pem. You will use your server key to sign client certificate CSR, and advertise server/certs/ca.pem as acceptable CAs during TLS handshake.

Assuming a client's CSR file is named myClientApp_csr.pem, to sign the CSR

openssl x509 -req -in myClientApp_csr.pem -CA server/certs/ca.pem -CAkey server/certs/key.pem -out myClientApp_cert.pem -set_serial 01 -days 365

Then give myClientApp_cert.pem to the client. How a client app supplies the client certificate when making a request to NotifyBC varies by client type. Usually the client first needs to bundle the signed client cert and client key into PKCS#12 format

openssl pkcs12 -export -clcerts -in myClientApp_cert.pem -inkey myClientApp_key.pem -out myClientApp.p12

To use myClientApp.p12, for cURL,

curl --insecure --cert myClientApp.p12 --cert-type p12 https://localhost:3000/api/administrators/whoami

For browsers, check browser's instruction how to import myClientApp.p12. When browser accessing NotifyBC API endpoints such as https://localhost:3000/api/administrators/whoami, the browser will prompt to choose from a list certificates that are signed by the server certificate.

In case you created server/certs/ca.pem but don't want to enable client certificate authentication, create following config in src/config.local.js

module.exports = {
  tls: {
    clientCertificateEnabled: false,
  },
};

TLS termination has to be passthrough

For client certification authentication to work, TLS termination of all reverse proxies has to be set to passthrough rather than offload and reload. This means, for example, when NotifyBC is hosted on OpenShift, router tls terminationopen in new window has to be changed from edge to passthrough.

NotifyBC internal request does not use client certificate

Requests sent by a NotifyBC node back to the app cluster use admin ip list authentication.