1
0
mirror of https://github.com/taigrr/nats.docs synced 2025-01-18 04:03:23 -08:00

GitBook: [master] 213 pages modified

This commit is contained in:
Ginger Collison 2021-06-29 16:54:35 +00:00 committed by gitbook-bot
parent 6bf426d5a6
commit 594da549b3
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
2 changed files with 147 additions and 166 deletions

View File

@ -1,53 +1,48 @@
# JetStream in Leaf Nodes ---
description: Using JetStream on Leaf Nodes
---
# Leaf Nodes
If you want to see a demonstration of the full range of this functionality, check out our [video](https://youtu.be/0MkS_S7lyHk) If you want to see a demonstration of the full range of this functionality, check out our [video](https://youtu.be/0MkS_S7lyHk)
One of the use cases for a NATS server configured as a [leaf node](/nats-server/configuration/leafnodes) is to provide a local NATS network even when the connection to a hub or the cloud is down. One of the use cases for a NATS server configured as a [leaf node](../nats-server/configuration/leafnodes/) is to provide a local NATS network even when the connection to a hub or the cloud is down. To support such a disconnected use case with JetStream, independent JetStream islands are also supported and available through the same NATS network.
To support such a disconnected use case with JetStream, independent JetStream islands are also supported and available through the same NATS network.
The general issue with multiple, independent JetStreams, accessible from the same client is that you need to be able to tell them apart. The general issue with multiple, independent JetStreams, accessible from the same client is that you need to be able to tell them apart. As an example, consider a leaf node with a non-clustered JetStream in each server. You connect to one of them, but which JetStream responds when you use the JetStream API `$JS.API.>` ?
As an example, consider a leaf node with a non-clustered JetStream in each server.
You connect to one of them, but which JetStream responds when you use the JetStream API `$JS.API.>` ?
To disambiguate between servers, the option `domain` was added to the JetStream configuration block. To disambiguate between servers, the option `domain` was added to the JetStream configuration block. When using it, follow these rules: Every server in a cluster and super cluster needs to have the same domain name. This means that domain names can only change between two servers if they are connected via a leaf node connection. As a result of this the JetStream API `$JS.API.>` will also be available under a disambiguated name `$JS.<domain>.API.>`. Needless to say, domain names need to be unique.
When using it, follow these rules:
Every server in a cluster and super cluster needs to have the same domain name. There are reasons to connect system accounts on either end of your leaf node connection. You probably don't want to connect your cloud and edge device system accounts, but you might connect them when the only reason keeping you from using a super cluster are firewall rules.
This means that domain names can only change between two servers if they are connected via a leaf node connection.
As a result of this the JetStream API `$JS.API.>` will also be available under a disambiguated name `$JS.<domain>.API.>`. There are reasons to connect system accounts on either end of your leaf node connection. You probably don't want to connect your cloud and edge device system accounts, but you might connect them when the only reason keeping you from using a super cluster are firewall rules. The benefits are: 1\) monitoring of all connected nats-servers 2\) nats-account-resolver working on the entire network 3\) extended JetStream cluster
Needless to say, domain names need to be unique.
There are reasons to connect system accounts on either end of your leaf node connection. You probably don't want to connect your cloud and edge device system accounts, but you might connect them when the only reason keeping you from using a super cluster are firewall rules. The benefits are: 1\) monitoring of all connected nats-servers 2\) nats-account-resolver working on the entire network 3\) extended JetStream cluster
There are reasons to connect system accounts on either end of your leaf node connection.
You probably don't want to connect your cloud and edge device system accounts, but you might connect them when the only reason keeping you from using a super cluster are firewall rules.
The benefits are: The benefits are:
1) monitoring of all connected nats-servers
2) nats-account-resolver working on the entire network
3) extended JetStream cluster
When `domain` is set, JetStream-related traffic on the system account is suppressed. * Monitoring of all connected nats-servers
This is what causes JetStream not to be extended. * nats-account-resolver working on the entire network
* extended JetStream cluster
In addition, traffic on `$JS.API.>` is also suppressed. When `domain` is set, JetStream-related traffic on the system account is suppressed. This is what causes JetStream not to be extended.
This causes clients to use the local JetStream that is available in the nats-servers they are connected to.
To communicate with another JetStream, that JetStream's unique domain specific prefix `$JS.<domain>.API` needs to be specified.
Please be aware that each domain is an independent name space. In addition, traffic on `$JS.API.>` is also suppressed. This causes clients to use the local JetStream that is available in the nats-servers they are connected to. To communicate with another JetStream, that JetStream's unique domain specific prefix `$JS.<domain>.API` needs to be specified.
Meaning, inside the same account it is legal to use the same stream name in different domains.
Furthermore, regular message flow is not restricted. Please be aware that each domain is an independent name space. Meaning, inside the same account it is legal to use the same stream name in different domains.
Thus, if the same subject is subscribed to by different streams in the same account in different domains, as long as the underlying leaf node was connected at the time, each stream will store the message.
This can be resolved by using the same account but use different subjects in each domain or use different accounts in each domain or [isolate accounts](https://youtu.be/0MkS_S7lyHk?t=1151) used in leaf nodes.
> *Known issue*: if you have more than one JetStream enabled leaf node in a different cluster, the cluster you connect to also needs JetStream enabled and a domain set. Furthermore, regular message flow is not restricted. Thus, if the same subject is subscribed to by different streams in the same account in different domains, as long as the underlying leaf node was connected at the time, each stream will store the message. This can be resolved by using the same account but use different subjects in each domain or use different accounts in each domain or [isolate accounts](https://youtu.be/0MkS_S7lyHk?t=1151) used in leaf nodes.
> *Known issue*: when you intend to extend a central JetStream, by not supplying a domain name in leaf nodes, that central JetStream needs to be in clustered mode.
> _Known issue_: if you have more than one JetStream enabled leaf node in a different cluster, the cluster you connect to also needs JetStream enabled and a domain set.
>
> _Known issue_: when you intend to extend a central JetStream, by not supplying a domain name in leaf nodes, that central JetStream needs to be in clustered mode.
## Configuration ## Configuration
Below is the config needed to connect two JetStream enabled servers via a leaf node connection. Below is the config needed to connect two JetStream enabled servers via a leaf node connection. In the example, the system accounts are connected for demonstration purposes \(you do not have to do that\).
In the example, the system accounts are connected for demonstration purposes (you do not have to do that).
### `accounts.conf` Imported by Both Servers ### `accounts.conf` Imported by Both Servers
```txt ```text
accounts { accounts {
SYS: { SYS: {
users: [{user: admin, password: admin}] users: [{user: admin, password: admin}]
@ -60,11 +55,11 @@ accounts {
system_account: SYS system_account: SYS
``` ```
### `hub.conf` ### `hub.conf`
To be started with `nats-server -c hub.conf`: To be started with `nats-server -c hub.conf`:
```txt ```text
port: 4222 port: 4222
server_name: hub-server server_name: hub-server
jetstream { jetstream {
@ -81,7 +76,7 @@ include ./accounts.conf
To be started with `nats-server -c leaf.conf`: To be started with `nats-server -c leaf.conf`:
```txt ```text
port: 4111 port: 4111
server_name: leaf-server server_name: leaf-server
jetstream { jetstream {
@ -121,8 +116,11 @@ Because the system account is connected, you can obtain the JetStream server rep
╰─────────────┴─────────────┴────────┴─────────┴───────────┴──────────┴───────┴────────┴──────┴─────────┴─────────╯ ╰─────────────┴─────────────┴────────┴─────────┴───────────┴──────────┴───────┴────────┴──────┴─────────┴─────────╯
``` ```
Create a stream named `test` subscribing to subject `test` in the JetStream domain the program is connected to. Create a stream named `test` subscribing to subject `test` in the JetStream domain, the program is connected to. As a result, this stream will be created in the domain hub which is the domain of the server listening on `localhost:4222`.
As a result, this stream will be created in the domain hub which is the domain of the server listening on `localhost:4222`.
Create a stream named `test` subscribing to subject `test` in the JetStream domain the program is connected to. As a result, this stream will be created in the domain hub which is the domain of the server listening on `localhost:4222`.
Create a stream named `test` subscribing to subject `test` in the JetStream domain the program is connected to. As a result, this stream will be created in the domain hub which is the domain of the server listening on `localhost:4222`.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 stream add > nats --server nats://acc:acc@localhost:4222 stream add
@ -166,8 +164,11 @@ State:
Active Consumers: 0 Active Consumers: 0
``` ```
To create a stream in a different domain while connected somewhere else, just provide the `js-domain` argument. To create a stream in a different domain while connected somewhere else, just provide the `js-domain` arguement. While connected to the same server as before, now the stream is created in `leaf`.
While connected to the same server as before, now the stream is created in `leaf`.
To create a stream in a different domain while connected somewhere else, just provide the `js-domain` argument. While connected to the same server as before, now the stream is created in `leaf`.
To create a stream in a different domain while connected somewhere else, just provide the `js-domain` argument. While connected to the same server as before, now the stream is created in `leaf`.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 stream add --js-domain leaf > nats --server nats://acc:acc@localhost:4222 stream add --js-domain leaf
@ -213,14 +214,12 @@ State:
Publish a message so there is something to retrieve. Publish a message so there is something to retrieve.
``` ```text
> nats --server nats://acc:acc@localhost:4222 pub test "hello world" > nats --server nats://acc:acc@localhost:4222 pub test "hello world"
13:33:17 Published 11 bytes to "test" 13:33:17 Published 11 bytes to "test"
``` ```
Because both streams subscribe to the same subject, each one now reports one message. Because both streams subscribe to the same subject, each one now reports one message. This is done to demonstrate the issue. If you want to avoid that, you need to either use different subjects, different accounts, or one isolated account.
This is done to demonstrate the issue.
If you want to avoid that, you need to either use different subjects, different accounts, or one isolated account.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 stream report --js-domain leaf > nats --server nats://acc:acc@localhost:4222 stream report --js-domain leaf
@ -244,13 +243,15 @@ Obtaining Stream stats
├────────┼─────────┼───────────┼──────────┼───────┼──────┼─────────┼──────────┤ ├────────┼─────────┼───────────┼──────────┼───────┼──────┼─────────┼──────────┤
│ test │ File │ 0 │ 1 │ 45 B │ 0 │ 0 │ │ │ test │ File │ 0 │ 1 │ 45 B │ 0 │ 0 │ │
╰────────┴─────────┴───────────┴──────────┴───────┴──────┴─────────┴──────────╯ ╰────────┴─────────┴───────────┴──────────┴───────┴──────┴─────────┴──────────╯
``` ```
### Copying across domains via `source` or `mirror` ### Copying across domains via `source` or `mirror`
In order to copy a stream from one domain into another, specify the JetStream domain when creating a `mirror`. #### Copying across domains via `source` or `mirror`
If you want to connect a leaf to the hub and get commands, even when the leaf node connection is offline, mirroring a stream located in the hub is the way to go.
### Copying across domains via `source` or `mirror`
In order to copy a stream from one domain into another, specify the JetStream domain when creating a `mirror`. If you want to connect a leaf to the hub and get commands, even when the leaf node connection is offline, mirroring a stream located in the hub is the way to go.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 stream add --js-domain hub --mirror test > nats --server nats://acc:acc@localhost:4222 stream add --js-domain hub --mirror test
@ -295,8 +296,7 @@ State:
Active Consumers: 0 Active Consumers: 0
``` ```
Similarly, if you want to aggregate streams located in any number of leaf nodes use `source`. Similarly, if you want to aggregate streams located in any number of leaf nodes use `source`. If the streams located in each leaf are used for the same reasons, it is recommended to aggregate them in the hub for processing via `source`.
If the streams located in each leaf are used for the same reasons, it is recommended to aggregate them in the hub for processing via `source`.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 stream add --js-domain hub --source test > nats --server nats://acc:acc@localhost:4222 stream add --js-domain hub --source test
@ -342,10 +342,7 @@ State:
Active Consumers: 0 Active Consumers: 0
``` ```
`source` as well as `mirror` take a copy of the messages. `source` as well as `mirror` take a copy of the messages. Once copied, accessing the data is independent of the leaf node connection being online. Copying this way also avoids having to run a dedicated program of your own. This is the recommended way to exchange persistent data across domains.
Once copied, accessing the data is independent of the leaf node connection being online.
Copying this way also avoids having to run a dedicated program of your own.
This is the recommended way to exchange persistent data across domains.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 stream report --js-domain hub > nats --server nats://acc:acc@localhost:4222 stream report --js-domain hub
@ -371,25 +368,27 @@ Obtaining Stream stats
╰─────────────────────┴────────┴──────────────┴───────────────┴────────┴─────┴───────╯ ╰─────────────────────┴────────┴──────────────┴───────────────┴────────┴─────┴───────╯
``` ```
### Cross account & domain import ### Cross account & domain import
All of the above happened in the same account. #### Cross account & domain import
To share domain access across accounts the `account.conf` from above needs to be modified and the server restarted or reloaded.
This example exports the consumer API as well as a delivery subject which is used by the internal push consumer created by `source` and `mirror`. ### Cross account & domain import
All of the above happened in the same account. To share domain access across accounts the `account.conf` from above needs to be modified and the server restarted or reloaded. This example exports the consumer API as well as a delivery subject which is used by the internal push consumer created by `source` and `mirror`.
In support of another example on how to share a durable consumer for client access across domains and accounts, the `NEXT` and `ACK` API are exported as well. In support of another example on how to share a durable consumer for client access across domains and accounts, the `NEXT` and `ACK` API are exported as well.
On import, the JetStream API prefix `$JS.hub.API` is renamed to `JS.test@hub.API`. On import, the JetStream API prefix `$JS.hub.API` is renamed to `JS.test@hub.API`. This is to, once more, disambiguate which JetStream a client in the importing account might want to interact with. When using domains, the general recommendation is to export the domain-specific API `$JS.<domain>.API` as this allows you to pin the export to a particular domain.
This is to, once more, disambiguate which JetStream a client in the importing account might want to interact with.
When using domains, the general recommendation is to export the domain specific API `$JS.<domain>.API` as this allows you to pin the export to a particular domain.
Furthermore, the delivery subject is extended on import. On import, the JetStream API prefix `$JS.hub.API` is renamed to `JS.test@hub.API`. This is to, once more, disambiguate which JetStream a client in the importing account might want to interact with. When using domains, the general recommendation is to export the domain specific API `$JS.<domain>.API` as this allows you to pin the export to a particular domain.
This is to allow for easier export into multiple accounts.
This example also exports the absolute minimum necessary. On import, the JetStream API prefix `$JS.hub.API` is renamed to `JS.test@hub.API`. This is to, once more, disambiguate which JetStream a client in the importing account might want to interact with. When using domains, the general recommendation is to export the domain specific API `$JS.<domain>.API` as this allows you to pin the export to a particular domain.
It is possible to give access to the entire consumer API `$JS.hub.API.CONSUMER.>` or the entire API in a domain `$JS.hub.API.>` or the entire API `$JS.API.>` wherever the importing client connects.
```txt Furthermore, the delivery subject is extended on import. This is to allow for easier export into multiple accounts.
This example also exports the absolute minimum necessary. It is possible to give access to the entire consumer API `$JS.hub.API.CONSUMER.>` or the entire API in a domain `$JS.hub.API.>` or the entire API `$JS.API.>` wherever the importing client connects.
```text
accounts { accounts {
SYS: { SYS: {
users: [{user: admin, password: admin}] users: [{user: admin, password: admin}]
@ -430,11 +429,7 @@ system_account: SYS
#### Copying via `source` and `mirror` #### Copying via `source` and `mirror`
Once the servers have been restarted or reloaded, a `mirror` can be created as follows (same applies to `source`): Once the servers have been restarted or reloaded, a `mirror` can be created as follows \(same applies to `source`\): On import from a different account the renamed prefix `JS.acc@hub.API` is provided. In addition, the delivery subject name is extended to also include the importing domain and stream. This makes it unique to that particular import. If every delivery prefix follows the pattern `<static type>.<exporting account>.<exporting domain>.<importing account>.<importing domain>.<importing domain>.<importing stream name>` overlaps caused by multiple imports are avoided.
On import from a different account the renamed prefix `JS.acc@hub.API` is provided.
In addition, the delivery subject name is extended to also include the importing domain and stream.
This makes it unique to that particular import.
If every delivery prefix follows the pattern `<static type>.<exporting account>.<exporting domain>.<importing account>.<importing domain>.<importing domain>.<importing stream name>` overlaps caused by multiple imports are avoided.
```bash ```bash
> nats --server nats://import_mirror:import_mirror@localhost:4222 stream add --js-domain hub --mirror aggregate-test-leaf > nats --server nats://import_mirror:import_mirror@localhost:4222 stream add --js-domain hub --mirror aggregate-test-leaf
@ -503,10 +498,9 @@ Obtaining Stream stats
╰──────────────────────────────┴────────┴────────────────┴─────────────────────┴────────┴─────┴───────╯ ╰──────────────────────────────┴────────┴────────────────┴─────────────────────┴────────┴─────┴───────╯
``` ```
#### Direct access of a durable pull consumer #### Direct access of a durable pull consumer
The modified `accounts.conf` also includes a separate import for an existing pull consumer. The modified `accounts.conf` also includes a separate import for an existing pull consumer. Let's create a consumer by the name `dur` in the stream `aggregate-test-leaf` in the account `acc`.
Let's create a consumer by the name `dur` in the stream `aggregate-test-leaf` in the account `acc`.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 consumer add --js-domain hub > nats --server nats://acc:acc@localhost:4222 consumer add --js-domain hub
@ -572,9 +566,9 @@ Obtaining Stream stats
╰──────────┴──────┴────────────┴──────────┴─────────────┴─────────────┴─────────────┴───────────┴─────────────╯ ╰──────────┴──────┴────────────┴──────────┴─────────────┴─────────────┴─────────────┴───────────┴─────────────╯
``` ```
To retrieve the messages stored in the domain `hub` using `nats` while connected to the leaf node, provide the correct stream and durable name as well as the API prefix `JS.acc@hub.API` To retrieve the messages stored in the domain `hub` using `nats` while connected to the leaf node, provide the correct stream and durable name as well as the API prefix `JS.acc@hub.API`
``` ```text
nats --server nats://import_client:import_client@localhost:4111 consumer next aggregate-test-leaf dur --js-api-prefix JS.acc@hub.API nats --server nats://import_client:import_client@localhost:4111 consumer next aggregate-test-leaf dur --js-api-prefix JS.acc@hub.API
[17:44:16] subj: test / tries: 1 / cons seq: 1 / str seq: 1 / pending: 0 [17:44:16] subj: test / tries: 1 / cons seq: 1 / str seq: 1 / pending: 0
@ -600,8 +594,7 @@ Acknowledged message
╰──────────┴──────┴────────────┴──────────┴─────────────┴─────────────┴─────────────┴───────────┴─────────────╯ ╰──────────┴──────┴────────────┴──────────┴─────────────┴─────────────┴─────────────┴───────────┴─────────────╯
``` ```
This works similarly when writing your own client. This works similarly when writing your own client. To avoid waiting for the ack timeout, a new message is sent on `test` from where it is copied into `aggregate-test-leaf`.
To avoid waiting for the ack timeout, a new message is sent on `test` from where it is copied into `aggregate-test-leaf`.
```bash ```bash
> nats --server nats://acc:acc@localhost:4222 pub test "hello world 2" > nats --server nats://acc:acc@localhost:4222 pub test "hello world 2"
@ -610,7 +603,7 @@ To avoid waiting for the ack timeout, a new message is sent on `test` from where
The client is connected to the leaf node and receives the message just sent. The client is connected to the leaf node and receives the message just sent.
``` ```text
./main nats://import_client:import_client@localhost:4111 ./main nats://import_client:import_client@localhost:4111
starting starting
&{Sequence:{Consumer:3 Stream:3} NumDelivered:1 NumPending:0 Timestamp:2021-06-28 17:51:05.186878 -0400 EDT Stream:aggregate-test-leaf Consumer:dur} &{Sequence:{Consumer:3 Stream:3} NumDelivered:1 NumPending:0 Timestamp:2021-06-28 17:51:05.186878 -0400 EDT Stream:aggregate-test-leaf Consumer:dur}
@ -619,70 +612,67 @@ nats: timeout
^Cnats: timeout ^Cnats: timeout
``` ```
There the API prefix is communicated with setting the option `nats.APIPrefix("JS.acc@hub.API")` when obtaining the JetStream object. There the API prefix is communicated with setting the option `nats.APIPrefix("JS.acc@hub.API")` when obtaining the JetStream object. Because the API access is limited, the subscribe call provides the option `nats.Bind("aggregate-test-leaf", "dur")` which prevents calls to infer the stream and durable name.
Because the API access is limited, the subscribe call provides the option `nats.Bind("aggregate-test-leaf", "dur")` which prevents calls to infer the stream and durable name.
```go ```go
package main package main
import ( import (
"fmt" "fmt"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"time" "time"
"github.com/nats-io/nats.go" "github.com/nats-io/nats.go"
) )
func main() { func main() {
nc, err := nats.Connect(os.Args[1], nats.Name("JS test")) nc, err := nats.Connect(os.Args[1], nats.Name("JS test"))
defer nc.Close() defer nc.Close()
if err != nil { if err != nil {
fmt.Printf("nats connect: %v\n", err) fmt.Printf("nats connect: %v\n", err)
return return
} }
js, err := nc.JetStream(nats.APIPrefix("JS.acc@hub.API")) js, err := nc.JetStream(nats.APIPrefix("JS.acc@hub.API"))
if err != nil { if err != nil {
fmt.Printf("JetStream: %v\n", err) fmt.Printf("JetStream: %v\n", err)
if js == nil { if js == nil {
return return
} }
} }
s, err := js.PullSubscribe("", "dur", nats.Bind("aggregate-test-leaf", "dur")) s, err := js.PullSubscribe("", "dur", nats.Bind("aggregate-test-leaf", "dur"))
if err != nil { if err != nil {
fmt.Printf("PullSubscribe: %v\n", err) fmt.Printf("PullSubscribe: %v\n", err)
return return
} }
shutdown := make(chan os.Signal, 1) shutdown := make(chan os.Signal, 1)
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM) signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
fmt.Printf("starting\n") fmt.Printf("starting\n")
for { for {
select { select {
case <-shutdown: case <-shutdown:
return return
default: default:
if m, err := s.Fetch(1, nats.MaxWait(time.Second)); err != nil { if m, err := s.Fetch(1, nats.MaxWait(time.Second)); err != nil {
fmt.Println(err) fmt.Println(err)
} else { } else {
if meta, err := m[0].Metadata(); err == nil { if meta, err := m[0].Metadata(); err == nil {
fmt.Printf("%+v\n", meta) fmt.Printf("%+v\n", meta)
} }
fmt.Println(string(m[0].Data)) fmt.Println(string(m[0].Data))
if err := m[0].Ack(); err != nil { if err := m[0].Ack(); err != nil {
fmt.Printf("ack error: %+v\n", err) fmt.Printf("ack error: %+v\n", err)
} }
} }
} }
} }
} }
``` ```
A push subscriber will need a similar setup. A push subscriber will need a similar setup. It will require the `ACK` subject. However, instead of exporting/importing the `NEXT` subject, the delivery subject shown for source/mirror needs to be used.
It will require the `ACK` subject.
However, instead of exporting/importing the `NEXT` subject, the delivery subject shown for source/mirror needs to be used.

View File

@ -2,13 +2,11 @@
_Supported since NATS Server version 2.3_ _Supported since NATS Server version 2.3_
[OCSP Stapling](https://en.wikipedia.org/wiki/OCSP_stapling) is honored by default for certificates that have [OCSP Stapling](https://en.wikipedia.org/wiki/OCSP_stapling) is honored by default for certificates that have the [status\_request Must-Staple flag](https://datatracker.ietf.org/doc/html/rfc6961).
the [status_request Must-Staple flag](https://datatracker.ietf.org/doc/html/rfc6961).
When a certificate is configured with OCSP Must-Staple, the NATS Server will fetch staples from the configured OCSP responder URL When a certificate is configured with OCSP Must-Staple, the NATS Server will fetch staples from the configured OCSP responder URL that is present in a certificate. For example, given a certificate with the following configuration:
that is present in a certificate. For example, given a certificate with the following configuration:
```text
```
[ ext_ca ] [ ext_ca ]
... ...
authorityInfoAccess = OCSP;URI:http://ocsp.example.net:80 authorityInfoAccess = OCSP;URI:http://ocsp.example.net:80
@ -16,39 +14,33 @@ tlsfeature = status_request
... ...
``` ```
The NATS server will make a request to the OCSP responder to fetch a new staple which will then be presented to The NATS server will make a request to the OCSP responder to fetch a new staple which will then be presented to any TLS connection that is accepted by the server during the TLS handshake.
any TLS connection that is accepted by the server during the TLS handshake.
OCSP Stapling can be explicitly enabled or disabled in the NATS Server by setting the following flag in the NATS configuration file at the top-level: OCSP Stapling can be explicitly enabled or disabled in the NATS Server by setting the following flag in the NATS configuration file at the top-level:
```hcl ```text
ocsp: false ocsp: false
``` ```
**Note**: When OCSP Stapling is disabled, the NATS Server will not request staples even if the certificate has **Note**: When OCSP Stapling is disabled, the NATS Server will not request staples even if the certificate has the Must-Staple flag.
the Must-Staple flag.
## Advanced Configuration ## Advanced Configuration
By default, the NATS Server will be running in OCSP `auto` mode. In this mode the server will only fetch By default, the NATS Server will be running in OCSP `auto` mode. In this mode the server will only fetch staples when the Must-Staple flag is configured in the certificate.
staples when the Must-Staple flag is configured in the certificate.
There are other OCSP modes that control the behavior as to whether OCSP should be enforced and the server
should shutdown if the certificate runs with a revoked staple:
| Mode | Description | Server shutdowns when revoked |
| --------- | ---- | ----- |
| auto | Enables OCSP Stapling when the certificate has the must staple/status_request flag | No |
| must | Enables OCSP Staping when the certificate has the must staple/status_request flag | Yes |
| always | Enables OCSP Stapling for all certificates | Yes |
| never | Disables OCSP Stapling even if must staple flag is present (same as `ocsp: false`) | No |
For example, in the following OCSP configuration, the mode is set to `must`. This means that staples will be fetched only for certificates There are other OCSP modes that control the behavior as to whether OCSP should be enforced and the server should shutdown if the certificate runs with a revoked staple:
that have the Must-Staple flag enabled as well, but in case of revocation the server will shutdown rather than run with a revoked staple.
In this configuration, the `url` will also override the OCSP responder URL that may have been configured in
the certificate.
```hcl | Mode | Description | Server shutdowns when revoked |
| :--- | :--- | :--- |
| auto | Enables OCSP Stapling when the certificate has the must staple/status\_request flag | No |
| must | Enables OCSP Staping when the certificate has the must staple/status\_request flag | Yes |
| always | Enables OCSP Stapling for all certificates | Yes |
| never | Disables OCSP Stapling even if must staple flag is present \(same as `ocsp: false`\) | No |
For example, in the following OCSP configuration, the mode is set to `must`. This means that staples will be fetched only for certificates that have the Must-Staple flag enabled as well, but in case of revocation the server will shutdown rather than run with a revoked staple.
In this configuration, the `url` will also override the OCSP responder URL that may have been configured in the certificate.
```text
ocsp { ocsp {
mode: must mode: must
url: "http://ocsp.example.net" url: "http://ocsp.example.net"
@ -56,8 +48,8 @@ ocsp {
``` ```
If staples are always required, regardless of the configuration of the certificate, you can enforce the behavior as follows: If staples are always required, regardless of the configuration of the certificate, you can enforce the behavior as follows:
```hcl ```text
ocsp { ocsp {
mode: always mode: always
url: "http://ocsp.example.net" url: "http://ocsp.example.net"
@ -66,21 +58,20 @@ ocsp {
## Caching of Staples ## Caching of Staples
When a `store_dir` is configured in the NATS Server, the directory will be used to cache staples on disk When a `store_dir` is configured in the NATS Server, the directory will be used to cache staples on disk to allow the server to resume in case of restarts without having to make another request to the OCSP responder if the staple is still valid.
to allow the server to resume in case of restarts without having to make another request to the OCSP responder
if the staple is still valid. ```text
```hcl
ocsp: true ocsp: true
store_dir: "/path/to/store/dir" store_dir: "/path/to/store/dir"
tls { tls {
cert_file: "configs/certs/ocsp/server-status-request-url.pem" cert_file: "configs/certs/ocsp/server-status-request-url.pem"
key_file: "configs/certs/ocsp/server-status-request-url-key.pem" key_file: "configs/certs/ocsp/server-status-request-url-key.pem"
ca_file: "configs/certs/ocsp/ca-cert.pem" ca_file: "configs/certs/ocsp/ca-cert.pem"
timeout: 5 timeout: 5
} }
``` ```
If JetStream is enabled, then the same `store_dir` will be reused and disk caching will be automatically enabled. If JetStream is enabled, then the same `store_dir` will be reused and disk caching will be automatically enabled.