Resolves problems of [issue
#3773](https://github.com/nats-io/nats-server/issues/3773).
With this fix, NATS Server will locally determine it's own certificate's
issuer from either the configured server certificate (bundle of leaf
cert plus optional intermediate CA certs) or from the configured server
CA trust store, as follows:
1. The operator may provide the server's certificate issuer in the
second position of the server's certificate configuration (typically
`cert_file` but may be `cert_store` on the Windows platform). If a
candidate issuer is found here it is PKI validated as the actual issuer
of the server's cert else a hard error.
2. If not found in [1], NATS Server will seek to create at least one
verified chain with its configured trust store (typically `ca_file` but
could by the system trust store if not configured). It will derive the
issuer from the first verified chain. If no verified chain can be formed
it is a hard error.
This is similar to PR #4115 but for LeafNodes.
Compression mode can be set on both side (the accept and in remotes).
```
leafnodes {
port: 7422
compression: s2_best
remotes [
{
url: "nats://host2:74222"
compression: s2_better
}
]
}
```
Possible modes are similar than for routes (described in PR #4115),
except that when not defined we default to `s2_auto`.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
The new field `compression` in the `cluster{}` block allows to
specify which compression mode to use between servers.
It can be simply specified as a boolean or a string for the
simple modes, or as an object for the "s2_auto" mode where
a list of RTT thresholds can be specified.
By default, if no compression field is specified, the server
will use the s2_auto mode with default RTT thresholds of
10ms, 50ms and 100ms for the "uncompressed", "fast", "better"
and "best" modes.
```
cluster {
..
# Possible values are "disabled", "off", "enabled", "on",
# "accept", "s2_fast", "s2_better", "s2_best" or "s2_auto"
compression: s2_fast
}
```
To specify a different list of thresholds for the s2_auto,
here is how it would look like:
```
cluster {
..
compression: {
mode: s2_auto
# This means that for RTT up to 5ms (included), then
# the compression level will be "uncompressed", then
# from 5ms+ to 15ms, the mode will switch to "s2_fast",
# then from 15ms+ to 50ms, the level will switch to
# "s2_better", and anything above 50ms will result
# in the "s2_best" compression mode.
rtt_thresholds: [5ms, 15ms, 50ms]
}
}
```
Note that the "accept" mode means that a server will accept
compression from a remote and switch to that same compression
mode, but will otherwise not initiate compression. That is,
if 2 servers are configured with "accept", then compression
will actually be "off". If one of the server had say s2_fast
then they would both use this mode.
If a server has compression mode set (other than "off") but
connects to an older server, there will be no compression between
those 2 routes.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
New configuration fields:
```
cluster {
...
pool_size: 5
accounts: ["A", "B"]
}
```
The configuration `pool_size` in the example above means that this
server will create 5 routes to a remote server, assuming that that
server has the same `pool_size` setting.
Accounts (which are not part of the `accounts[]` configuration)
are assigned a specific route in this pool, and this will be the
same route on all servers in the cluster.
Accounts that are defined in the `accounts` field will each have
a dedicated route connection. This will allow suppression of the
account name in some of the route protocols, reducing bytes transmitted
which may increase performance.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
Code change:
- Do not start the processMirrorMsgs and processSourceMsgs go routine
if the server has been detected to be shutdown. This would otherwise
leave some go routine running at the end of some tests.
- Pass the fch and qch to the consumerFileStore's flushLoop otherwise
in some tests this routine could be left running.
Tests changes:
- Added missing defer NATS connection close
- Added missing defer server shutdown
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
Also had to change all references from `path.` to `filepath.` when
dealing with files, so that it works properly on Windows.
Fixed also lots of tests to defer the shutdown of the server
after the removal of the storage, and fixed some config files
directories to use the single quote `'` to surround the file path,
again to work on Windows.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
Currently, OCSP responses that aren't signed by the root CA will fail
with a verification error. This change allows intermediates, or
designated responders, to sign responses on behalf of the CA.
Updated some tests based on this change but also missing defer
connection close or server shutdown.
Fixed how the OCSP run go routine would shutdown, which would
never complete because grWG was not decremented by this go routine
prior to invoking s.Shutdown()
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
When trying to update NATS Streaming server dependencies with
latest NATS Server, I noticed that a TLS test was failing and
this was because the TLS configuration was manually set like this:
```
o := DefaultTestOptions
o.HTTPHost = "127.0.0.1"
o.HTTPSPort = -1
o.TLSConfig = &tls.Config{ServerName: "localhost"}
cert, err := tls.LoadX509KeyPair("configs/certs/server-cert.pem", "configs/certs/server-key.pem")
if err != nil {
t.Fatalf("Got error reading certificates: %s", err)
}
o.TLSConfig.Certificates = []tls.Certificate{cert}
```
Notice how the `cert.Leaf` is not parsed. This cause the NATS Server
OCSP code to fail when hasOCSPStatusRequest() is invoked with
a `nil` pointer.
My first approach was to add a `nil` check in hasOCSPStatusRequest()
and return `false` in that case.
But then I thought that maybe the correct approach is to parse the
leaf it it is not done in the provided TLS config?
It could be simply a case of fixing the test that I have in
NATS Streaming server repo, but a quick check in this repo's own
dependencies show that not setting the Leaf is something that may
happen in some cases. For instance here is how the Postgres library
build the certs: caa87158f5/ssl.go (L133)
As you can see, the leaf is not parsed here, so I am not sure if
having Leaf nil is valid or not.
The go doc regarding Leaf says:
```
// Leaf is the parsed form of the leaf certificate, which may be initialized
// using x509.ParseCertificate to reduce per-handshake processing. If nil,
// the leaf certificate will be parsed as needed.
Leaf *x509.Certificate
```
This is the last statement that made me chose the current approach of
parsing it if detected as `nil` instead of just ignoring a nil cert.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>