mirror of
https://github.com/taigrr/nats.docs
synced 2025-01-18 04:03:23 -08:00
commit
240e09a125
@ -5,15 +5,19 @@ The server can require TLS certificates from a client. When needed, you can use
|
|||||||
* Validate the client certificate matches a known or trusted CA
|
* Validate the client certificate matches a known or trusted CA
|
||||||
* Extract information from a trusted certificate to provide authentication
|
* 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](../tls.md#Self-Signed-Certificates-for-Testing) locally.
|
||||||
|
|
||||||
## Validating a Client Certificate
|
## 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:
|
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:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
tls {
|
tls {
|
||||||
cert_file: "./configs/certs/server-cert.pem"
|
cert_file: "server-cert.pem"
|
||||||
key_file: "./configs/certs/server-key.pem"
|
key_file: "server-key.pem"
|
||||||
ca_file: "./configs/certs/ca.pem"
|
ca_file: "rootCA.pem"
|
||||||
verify: true
|
verify: true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -21,10 +25,12 @@ tls {
|
|||||||
Or via the command line:
|
Or via the command line:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> ./nats-server --tlsverify --tlscert=./test/configs/certs/server-cert.pem --tlskey=./test/configs/certs/server-key.pem --tlscacert=./test/configs/certs/ca.pem
|
> ./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.
|
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
|
## Mapping Client Certificates To A User
|
||||||
|
|
||||||
@ -34,9 +40,9 @@ To have TLS Mutual Authentication map certificate attributes to the user's ident
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
tls {
|
tls {
|
||||||
cert_file: "./configs/certs/server-cert.pem"
|
cert_file: "server-cert.pem"
|
||||||
key_file: "./configs/certs/server-key.pem"
|
key_file: "server-key.pem"
|
||||||
ca_file: "./configs/certs/ca.pem"
|
ca_file: "rootCA.pem"
|
||||||
# Require a client certificate and map user id from certificate
|
# Require a client certificate and map user id from certificate
|
||||||
verify_and_map: true
|
verify_and_map: true
|
||||||
}
|
}
|
||||||
@ -44,49 +50,52 @@ tls {
|
|||||||
|
|
||||||
> Note that `verify` was changed to `verify_and_map`.
|
> Note that `verify` was changed to `verify_and_map`.
|
||||||
|
|
||||||
There are two options for certificate attributes that can be mapped to user names. The first is the email address in the Subject Alternative Name \(SAN\) field of the certificate. While generating a certificate with this attribute is outside the scope of this document, you can view one with `openssl`:
|
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.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ openssl x509 -noout -text -in test/configs/certs/client-id-auth-cert.pem
|
$ openssl x509 -noout -text -in client-cert.pem
|
||||||
Certificate:
|
Certificate:
|
||||||
...
|
...
|
||||||
X509v3 extensions:
|
X509v3 extensions:
|
||||||
X509v3 Subject Alternative Name:
|
X509v3 Subject Alternative Name:
|
||||||
DNS:localhost, IP Address:127.0.0.1, email:derek@nats.io
|
DNS:localhost, IP Address:0:0:0:0:0:0:0:1, email:email@localhost
|
||||||
X509v3 Extended Key Usage:
|
X509v3 Extended Key Usage:
|
||||||
TLS Web Client Authentication
|
TLS Web Client Authentication
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
The configuration to authorize this user would be as follows:
|
The configuration to authorize this user would be as follow:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
authorization {
|
authorization {
|
||||||
users = [
|
users = [
|
||||||
{user: "derek@nats.io"}
|
{user: "email@localhost"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note: This configuration only works for the first email address if there are multiple emails in the SAN field.
|
Use the [RFC 2253 Distinguished Names](https://tools.ietf.org/html/rfc2253) syntax to specify a user corresponding to the certificate subject:
|
||||||
|
|
||||||
The second option is to use the RFC 2253 Distinguished Names syntax from the certificate subject as follows:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
$ openssl x509 -noout -text -in test/configs/certs/tlsauth/client2.pem
|
$ openssl x509 -noout -text -in client-cert.pem
|
||||||
Certificate:
|
Certificate:
|
||||||
Data:
|
Data:
|
||||||
...
|
...
|
||||||
Subject: OU=CNCF, CN=example.com
|
Subject: O=mkcert development certificate, OU=testuser@MacBook-Pro.local (Test User)
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 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:
|
The configuration to authorize this user would be as follows:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
authorization {
|
authorization {
|
||||||
users = [
|
users = [
|
||||||
{user: "CN=example.com,OU=CNCF"}
|
{user: "OU=testuser@MacBook-Pro.local (Test User),O=mkcert development certificate"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -4,15 +4,15 @@ The NATS server uses modern TLS semantics to encrypt client, route, and monitori
|
|||||||
|
|
||||||
| Property | Description |
|
| Property | Description |
|
||||||
| :--- | :--- |
|
| :--- | :--- |
|
||||||
| `ca_file` | TLS certificate authority file. |
|
|
||||||
| `cert_file` | TLS certificate file. |
|
| `cert_file` | TLS certificate file. |
|
||||||
|
| `key_file` | TLS certificate key file. |
|
||||||
|
| `ca_file` | TLS certificate authority file. When not present, default to the system trust store. |
|
||||||
| `cipher_suites` | When set, only the specified TLS cipher suites will be allowed. Values must match the golang version used to build the server. |
|
| `cipher_suites` | When set, only the specified TLS cipher suites will be allowed. Values must match the golang version used to build the server. |
|
||||||
| `curve_preferences` | List of TLS cipher curves to use in order. |
|
| `curve_preferences` | List of TLS cipher curves to use in order. |
|
||||||
| `insecure` | Skip certificate verification. |
|
| `insecure` | Skip certificate verification. **NOT Recommended** |
|
||||||
| `key_file` | TLS certificate key file. |
|
| `timeout` | TLS handshake [timeout](#TLS-Timeout) in fractional seconds. Default set to `0.5` seconds. |
|
||||||
| `timeout` | TLS handshake timeout in fractional seconds. Default set to 2 seconds. |
|
| `verify` | If `true`, require and [verify](auth_intro/tls_mutual_auth.md#Validating-a-Client-Certificate) client certificates. To support use by Browser, this option does not apply to monitoring. |
|
||||||
| `verify_and_map` | If `true`, require and verify client certificates and map certificate values for authentication purposes. |
|
| `verify_and_map` | If `true`, require and verify client certificates and [map](auth_intro/tls_mutual_auth.md#Mapping-Client-Certificates-To-A-User) certificate values for authentication purposes. Does not apply to monitoring either. |
|
||||||
| `verify` | If `true`, require and verify client certificates. |
|
|
||||||
|
|
||||||
The simplest configuration:
|
The simplest configuration:
|
||||||
|
|
||||||
@ -59,3 +59,97 @@ tls: {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Self Signed Certificates for Testing
|
||||||
|
|
||||||
|
Explaining [Public key infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure), [Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority) and [x509](https://tools.ietf.org/html/rfc5280) [certificates](https://en.wikipedia.org/wiki/Public_key_certificate) fall well outside the scope of this document.
|
||||||
|
So does an explanation on how to obtain a properly trusted certificates.
|
||||||
|
|
||||||
|
If anybody outside your organization needs to connect, get certs from a public certificate authority.
|
||||||
|
Think carefully about revocation and cycling times, as well as automation, when picking a CA.
|
||||||
|
If arbitrary applications inside your organization need to connect, use a cert from your in-house CA.
|
||||||
|
If only resources inside a specific environment need to connect, that environment might have its own dedicated automatic CA, eg in Kubernetes clusters, so use that.
|
||||||
|
|
||||||
|
**Only** for **testing** purposes does it makes sense to generate self signed certificates, even your own CA.
|
||||||
|
This is a **short** guide on how to do just that and what to watch out for.
|
||||||
|
|
||||||
|
> **DO NOT USE these certificates in production!!!**
|
||||||
|
|
||||||
|
### Problems With Self Signed Certificates
|
||||||
|
|
||||||
|
#### Missing in Relevant Trust Stores
|
||||||
|
|
||||||
|
As they should, these are **not trusted** by the system your server or clients are running on.
|
||||||
|
|
||||||
|
One option is to specify the CA in every client you are using.
|
||||||
|
In case you make use of `verify` and `verify_and_map` you need to specify `ca_file` in the server.
|
||||||
|
If you are having a more complex setup involving cluster, gateways or leaf nodes, `ca_file` needs to be present in `tls` maps used to connect to the server with self signed certificates.
|
||||||
|
While this works for server and libraries from the NATS eco system, you will experience issues when connecting with other tools such as your Browser.
|
||||||
|
|
||||||
|
Another option is to configure your system's trust store to include self signed certificate(s).
|
||||||
|
Which trust store needs to be configured depends on what you are testing.
|
||||||
|
* This may be your OS for server and certain clients.
|
||||||
|
* The runtime environment for other clients like Java, Python or Node.js.
|
||||||
|
* Your browser for monitoring endpoints and websockets.
|
||||||
|
|
||||||
|
Please check your system's documentation on how to trust a particular self signed certificate.
|
||||||
|
|
||||||
|
#### Missing Subject Alternative Name
|
||||||
|
|
||||||
|
Another common problem is failed [identity validation](https://tools.ietf.org/html/rfc6125).
|
||||||
|
The IP or DNS name to connect to needs to match a [Subject Alternative Name (SAN)](https://tools.ietf.org/html/rfc4985) inside the certificate.
|
||||||
|
Meaning, if a client/browser/server connect via tls to `127.0.0.1`, the server needs to present a certificate with a SAN containing the IP `127.0.0.1` or the connection will be closed with a handshake error.
|
||||||
|
|
||||||
|
### Creating Self Signed Certificates for Testing
|
||||||
|
|
||||||
|
The simplest way to generate a CA as well as client and server certificates is [mkcert](https://github.com/FiloSottile/mkcert).
|
||||||
|
This zero config tool generates and installs the CA into your **local** system trust store(s) and makes providing SAN straight forward.
|
||||||
|
Check it's [documentation](https://github.com/FiloSottile/mkcert/blob/master/README.md) for installation and your system's trust store.
|
||||||
|
Here is a simple example:
|
||||||
|
|
||||||
|
Generate a CA as well as a certificate, valid for use by `localhost` and the IP `::1`(`-cert-file` and `-key-file` overwrite default file names).
|
||||||
|
Then start a nats server using the generated certificate.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkcert -install
|
||||||
|
mkcert -cert-file server-cert.pem -key-file server-key.pem localhost ::1
|
||||||
|
nats-server --tls --tlscert=server-cert.pem --tlskey=server-key.pem -ms 8222
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you should be able to access the monitoring endpoint `https://localhost:8222` with your browser.
|
||||||
|
`https://127.0.0.1:8222` however should result in an error as `127.0.0.1` is not listed as SAN.
|
||||||
|
You will not be able to establish a connection from another computer either.
|
||||||
|
For that to work you have to provide appropriate DNS and/or IP [SAN(s)](#Missing-Subject-Alternative-Name)
|
||||||
|
|
||||||
|
To generate certificates that work with `verify` provide the `-client` option.
|
||||||
|
This will cause it to add an appropriate key usage for client authentication.
|
||||||
|
Please note that client refers to connecting process, not necessarily a NATS client.
|
||||||
|
Also add a SAN email for usage as user name in `verify_and_map`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkcert -client -cert-file client-cert.pem -key-file client-key.pem localhost ::1 email@localhost
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples in this document make use of the certificates generated so far.
|
||||||
|
To simplify examples using the CA certificate, copy `rootCA.pem` into the same folder where the certificates were generated.
|
||||||
|
To obtain the CA certificate's location use this command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkcert -CAROOT
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you are done testing, remove the CA from your **local** system trust store(s).
|
||||||
|
|
||||||
|
```
|
||||||
|
mkcert -uninstall
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can also use [openssl](https://www.openssl.org/) to [generate certificates](https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs).
|
||||||
|
This tool allows a lot more customization of the generated certificates.
|
||||||
|
It is a lot **more complex** and does **not manage** installation into the system trust store(s).
|
||||||
|
|
||||||
|
However, for inspecting certificates it is quite handy. To inspect the certificates from the above example execute these commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl x509 -noout -text -in server-cert.pem
|
||||||
|
openssl x509 -noout -text -in client-cert.pem
|
||||||
|
```
|
||||||
|
Loading…
x
Reference in New Issue
Block a user