When using the nats account resolver and a JWT is not found, the client could
often get an i/o timeout error due to not receiving a timely response
before the account resolver fetch request times out. Now instead
of waiting for the fetch request to timeout, a resolver without JWTs
will notify as well that it could not find a matching JWT, waiting for a
response from all active servers.
Also included in this PR is some cleanup to the logs emitted by the
resolver.
Signed-off-by: Waldemar Quevedo <wally@nats.io>
Claims update message requires only payload to be passed,
but passing headers should not fail the request.
This change ensures we extract payload from raw message
before decoding it.
Before this change, passing claims update with headers
would return cryptic `expected x chunks` error.
Signed-off-by: Tomasz Pietrek <tomasz@nats.io>
This adds the ability to augment or override the NATS auth system.
A server will send a signed request to $SYS.REQ.USER.AUTH on the specified account. The request will contain client information, all client options sent to the server, and optionally TLS information and client certificates.
The external auth service will respond with an empty message if not authorized, or a signed User JWT that the user will bind to.
The response can change the account the client will be bound to.
Signed-off-by: Derek Collison <derek@nats.io>
This is only added if set by a user or account expiration claim.
It is represented as a duration til expiration vs absolute time which would involve time zone and clock sync issues.
Signed-off-by: Derek Collison <derek@nats.io>
Suppose an account is updated to have the following weighted mapping:
```
foo -> bar 40%
```
The server automatically adds foo -> foo at 60%. Sending messages
to "foo" will result in the expected distribution of 60% messages
going to "foo" and 40% going to bar.
However, if a successive update is pushed to the server(s):
```
foo -> bar 40%
foo -> baz 60%
```
The subject mapping should now be as described, that is, no more
mapping from "foo" to "foo" and 40% to bar and 60% to baz, however,
what was happening is that the server would always use the original
mapping.
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>
Scoped signing keys allow for optional values in allow rules
If an allow rule therefore gets removed because a tag is not present,
the removal needs to be compensated by adding in a deny >
Signed-off-by: Matthias Hanel <mh@synadia.com>
When a request for a system service like $SYS.REQ.ACCOUNT.*.CONNZ
is imported/exported we ensured that the requesting account is identical
to the account referenced in the subject.
In #3250 this check was extended from CONNZ to all $SYS.REQ.ACCOUNT.*.*
requests.
In general this check interferes with monitoring accounts that need
to query all other accounts, not just itself.
There the use case is that account A sends a request with account B
in the subject. The check for equal accounts prevents this.
This change removes the check to support these use cases.
Instead of the check, the default export now uses exportAuth
tokenPos to ensure that the 4th token is the importer account id.
This guarantees that an explicit export (done by user) can only import
for the own account.
This change also ensures that an explicit export is not overwritten
by the system.
This is not a problem when the export is public.
Automatic imports set the account id correctly and do not use wildcards.
To cover cases where the export is private, automatically added imports
are not subject a token check.
Signed-off-by: Matthias Hanel <mh@synadia.com>
ordering of templates got messed up by a map (now removed)
Also improved error message when template generation fails
Signed-off-by: Matthias Hanel <mh@synadia.com>
For security reasons we have introduced scoped signing keys to jwt.
They carry user permissions.
Wich is why jwt issued by those keys are not allowed to carry their own permission.
Instead they are copied from the signing key.
If the scoped signing key gets compromised, an attacker can only issue jwt with the permissions of the key.
With a plain signing key, an attacker can create arbitrary user with permissions.
Because user jwt creation is greatly simplified we added a single utility function to go/java/.net which issues user for such keys.
This is function is documented in ADR-14:
```
/**
* signingKey, is a mandatory account nkey pair to sign the generated jwt.
* accountId, is a mandatory public account nkey. Will return error when not set or not account nkey.
* publicUserKey, is a mandatory public user nkey. Will return error when not set or not user nkey.
* name, optional human readable name. When absent, default to publicUserKey.
* expiration, optional but recommended duration, when the generated jwt needs to expire. If not set, JWT will not expire.
* tags, optional list of tags to be included in the JWT.
*
* Returns:
* error, when issues arose.
* string, resulting jwt.
**/
IssueUserJWT(signingKey nkey, accountId string, publicUserKey string, name string, expiration time.Duration, tags []string) (error, string)
```
Currently the only downside of this is that the permissions are static and can't be tailored to the user.
This PR changes that by allowing the user pub/sub permissions to be parameterized with templates.
templates are for entire tokens only and include:
{{name()}} -> username
{{subject()}} -> user subject (nkey)
{{account-name()}} -> users account name
{{account-subject()}} -> user accoutn subject (nkey)
{{tag(arbitrary-prefix)}}
provided the tag "arbitrary-prefix:value" will result in "value"
provided the tags ["arbitrary-prefix:1", "arbitrary-prefix:2"] will result in two subjects "1" & "2"
If the resulting subject is not valid.
Say a tag is not present or name is not set.
This will result in an error for deny subjects
and result in no subject for allow subject.
Signed-off-by: Matthias Hanel <mh@synadia.com>
Signed-off-by: Matthias Hanel <mh@synadia.com>
- Remove code coverage from Travis and add it to a GitHub Action
that will be run as a nightly.
- Use tag builds to exclude some tests, such as the "norace" or
JS tests. Since "go test" does not support "negative" regexs, there
is no other way.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
- Updated tests that were checking for the error to include the limit
- Moved some tests above the benchmark ones
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This needs testing because stream move adjusts the replication factor
Because adjusting replication factor and moving is illegal, this case
does not need to be tested
In order to support one off configurations, added same modification
callout to super cluster as is used with cluster
Signed-off-by: Matthias Hanel <mh@synadia.com>
* Add a config modification callback to createJetStreamCluster
named createJetStreamClusterAndModHook allowing the generated config to
be altered prior to server start
Signed-off-by: Matthias Hanel <mh@synadia.com>
adds unit test to test this scenario
improves reporting of correct error
only show info for non existing tiers where streams exist
Signed-off-by: Matthias Hanel <mh@synadia.com>
If both servers sent a remote update of their local use,
the limit was hit. But that limit wass to small by 200
Signed-off-by: Matthias Hanel <mh@synadia.com>
* added max_ack_penind setting to js account limits
because of the addition, defaults now have to be set later (depend on
these new limits now)
also re-organized the code to closer track how stream create looks
Signed-off-by: Matthias Hanel <mh@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>
user and activation token did not honor the jwt value for all * on
connect.
activation token where not re evaluated when the export revoked a key.
In part this is a consistency measure so servers that already have an
account and servers that don't behave the same way.
in jwt activation token revocations are stored per export.
The server stored them per account, thus effectively merging
revocations. Now they are stored per export inside the server too.
fixes nats-io/nsc/issues/442
Signed-off-by: Matthias Hanel <mh@synadia.com>
The RootCAs was not properly set, which could prevent the server
to create a TLS connection to the account resolver with an error
such as:
```
x509: certificate signed by unknown authority
```
Resolves#1207
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
option name: resolver_pinned_accounts
Contains a list of public account nkeys.
Connecting user of leaf nodes need to be signed by this.
The system account will always be able to connect.
Signed-off-by: Matthias Hanel <mh@synadia.com>
Fixes#2415. We did a set instead of merge.
changes in `jwt_test.go` are to make the `createUserWithLimit` usable by my new test.
Signed-off-by: Matthias Hanel <mh@synadia.com>
Those tests don't really start the server, so the account resolver's
internal expiration routine would be left running.
Doing an explicit close solves this issue.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This allows a domain to be set in the JetStream server block that sets a domain name.
Once set this signals that any leafnode connections should operate as separate JetStream domains.
Each domain <NAME> is accessible via "$JS.<NAME>.API.>", even when connected to the same domain.
Also for mixed mode you can set a jetstream block now that defines a domain but specifies "enabled: false".
Signed-off-by: Derek Collison <derek@nats.io>
In a setup with shared system account and a cluster of leaf nodes,
the JS requests did not contain the origin cluster, which caused
assets to possibly be created in the HUB. With this change, the
assets will be created in the origin cluster.
Also, removed use of acc.JetStreamEnabled() but instead fail
start of the server if mqtt is enabled in standalone mode and JS
is not enabled. If JS is enabled, we will get proper error if
account has no JS enabled.
Signed-off-by: Ivan Kozlovic <ivan@synadia.com>