TLS Authentication

The server can require TLS certificates from a client. When needed, you can use the certificates to:

  • Validate the client certificate matches a known or trusted CA
  • Extract information from a trusted certificate to provide authentication

Note: To simplify the common scenario of maintainers looking at the monitoring endpoint, verify and verify_and_map do not apply to the monitoring port.

The examples in the following sections make use of the certificates you generated locally.

Validating a Client Certificate

The server can verify a client certificate using a CA certificate. To require verification, add the option verify to the TLS configuration section as follows:

  1. tls {
  2. cert_file: "server-cert.pem"
  3. key_file: "server-key.pem"
  4. ca_file: "rootCA.pem"
  5. verify: true
  6. }

Or via the command line:

  1. nats-server --tlsverify --tlscert=server-cert.pem --tlskey=server-key.pem --tlscacert=rootCA.pem

This option verifies the client’s certificate is signed by the CA specified in the ca_file option. When ca_file is not present it will default to CAs in the system trust store. It also makes sure that the client provides a certificate with the extended key usage TLS Web Client Authentication.

Mapping Client Certificates To A User

In addition to verifying that a specified CA issued a client certificate, you can use information encoded in the certificate to authenticate a client. The client wouldn’t have to provide or track usernames or passwords.

To have TLS Mutual Authentication map certificate attributes to the user’s identity use verify_and_map as shown as follows:

  1. tls {
  2. cert_file: "server-cert.pem"
  3. key_file: "server-key.pem"
  4. ca_file: "rootCA.pem"
  5. # Require a client certificate and map user id from certificate
  6. verify_and_map: true
  7. }

Note that verify was changed to verify_and_map.

When present, the server will check if a Subject Alternative Name (SAN) maps to a user. It will search all email addresses first, then all DNS names. If no user could be found, it will try the certificate subject.

Note: This mechanism will pick the user it finds first. There is no configuration to restrict this.

  1. openssl x509 -noout -text -in client-cert.pem

Output

  1. Certificate:
  2. ...
  3. X509v3 extensions:
  4. X509v3 Subject Alternative Name:
  5. DNS:localhost, IP Address:0:0:0:0:0:0:0:1, email:email@localhost
  6. X509v3 Extended Key Usage:
  7. TLS Web Client Authentication
  8. ...

The configuration to authorize this user would be as follow:

  1. authorization {
  2. users = [
  3. {user: "email@localhost"}
  4. ]
  5. }

Use the RFC 2253 Distinguished Names syntax to specify a user corresponding to the certificate subject:

  1. openssl x509 -noout -text -in client-cert.pem

Output

  1. Certificate:
  2. Data:
  3. ...
  4. Subject: O=mkcert development certificate, OU=testuser@MacBook-Pro.local (Test User)
  5. ...

Note that for this example to work you will have to modify the user to match what is in your certificates subject. In doing so, watch out for the order of attributes!

The configuration to authorize this user would be as follows:

  1. authorization {
  2. users = [
  3. {user: "OU=testuser@MacBook-Pro.local (Test User),O=mkcert development certificate"}
  4. ]
  5. }

TLS Timeout

TLS timeout is described here.