Configuring for Production
Running a Nuts node in a production environment has additional requirements regarding security and data integrity compared to development or test environments. This page instructs how to configure your node for running in a production environment and what to consider.
Persistence
Make sure your storage configuration is set up to backup your node’s data and private keys.
HTTP Interface Configuration
By default all HTTP endpoints get bound to the default HTTP interface on :1323
.
You can configure endpoints to have alternative configuration (e.g. CORS, TLS, authentication) and/or be bound on an alternative port using the alt
property.
All configuration properties that apply to the http.default
HTTP interface are applicable to the alternative interface you configure as well (see the example below).
For production there are a few points to consider; enabling CORS, using alternative HTTP interfaces, and authentication.
Binding HTTP interfaces
Some HTTP endpoints are required to be accessible by the public and others only meant for administrator or your own XIS. You can determine the intended public by observing the first part of the URL:
Endpoints that start with
/public
should be accessible by the general public,/internal
is meant for XIS application integration and administrators.
It’s advisable to make sure internal endpoints aren’t reachable from public networks.
You can achieve this by binding it to a different port, by using a reverse proxy, or both.
Use the address
property of a HTTP binding to expose it on a different port:
http:
# The following is the default binding which endpoints are bound to,
# which don't have an alternative bind specified under ``alt``. Since it's a default it can be left out or
# be used to override the default bind address.
# If you specify an alt bind without address, it binds to the default HTTP interface, but
# the configuration of the default bind will NOT apply to the alt bind. If required, you need to repeat the config (e.g. cors/auth) for the alt bind.
default:
address: :1323
alt:
# The following binds all endpoints starting with ``/internal`` to ``internal.lan:1111``
internal:
address: internal.lan:1111
auth:
type: token_v2
authorizedkeyspath: /opt/nuts/authorized_keys
audience: nuts-node.example.com
# The following binds all endpoints starting with ``/public`` to ``:443`` and enables TLS for it
public:
address: :443
# Given we bind on port 443, we probably want to enable TLS for this endpoint
tls: server
# The following enables cross-domain requests (CORS) from irma.vendor.nl
cors:
origin:
- irma.vendor.nl
Cross Origin Resource Sharing (CORS)
In some deployments CORS can be required for the public IRMA authentication endpoints when the user-facing
authentication page is hosted on a (sub)domain that differs from Nuts Node’s IRMA backend. CORS can be enabled on a
specific HTTP interface by specifying the domains allowed to make CORS requests as cors.origin
(see the example above).
Although you can enable CORS on the default endpoint it’s not advised to do so in a production environment,
because CORS itself opens up new attack vectors on node administrators.
Authentication
You should secure some HTTP endpoints (notably /internal
) with authentication.
The Nuts node supports JWT Bearer Token authentication which can be enabled on any HTTP endpoint.
You can enable it by setting auth.type
(see example above) to token_v2
for the specific bind.
The specified path, and all its subpaths, will then require a JWT token generated by an external
process and signed with a trusted private/public keypair.
The optional auth.audience
parameter sets the expected audience value for JWT tokens. The default value for
this parameter is determined by the hostname configured on the nuts node, and thus administrators may wish to
explicitly set this parameter when using reverse proxies or under other circumstances where the known DNS name
of the nuts node differs from its hostname.
Users are authorized access to APIs by the administrator of the nuts node. The administrator must configure the
public key of API callers in an authorized_keys
file as specified in the auth.type.authorizedkeyspath
setting.
This file should contain one or more trusted keys, in the standard SSH format. ECDSA, Ed25519, and RSA (>=2048-bit) keys
are accepted. Each line in the file must contain the key-type, key-specification, and user name that is authorized,
for example ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH1VNKtThJiI6c5zjLn/6EjRq1PtfM4qw4HM71zivIVn john.doe@company.com
.
Note that this file should be a distinct authorized_keys
file from that used to grant console access to the
nuts node. API access and SSH access are two entirely different matters and we are simply using this well known
configuration file format. The nuts node does not integrate in any way with the SSH subsystem on the host OS.
The Nuts foundation provides a utility for generating JWT tokens on our GitHub. Unlike the legacy authentication method this tool does not need to be executed on the nuts node itself.
Alternatively, developers and integrators may choose to implement their own JWT generation process which must conform to the requirements described in Custom JWT Generation.
Generating Keys With OpenSSL
To generate an Ed25519 key with OpenSSL:
openssl genpkey -algorithm ed25519 -out /path/to/keyfile.pem
To generate an ECDSA key with OpenSSL:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-521 -pkeyopt ec_param_enc:named_curve -out /path/to/keyfile.pem
To generate an RSA key with OpenSSL:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out /path/to/rsa-private.pem
Generating Keys With SSH
To generate an Ed25519 key with using ssh-keygen:
ssh-keygen -t ed25519 -f /path/to/keyfile
To generate an ECDSA key using ssh-keygen:
ssh-keygen -t ecdsa -b 521 -f /path/to/keyfile
To generate an RSA key using ssh-keygen:
ssh-keygen -t rsa -b 4096 -f /path/to/keyfile
Legacy Authentication
This authentication method has been superceded and users should consider updating their deployments.
You might want to secure some HTTP endpoints (notably /internal
) with authentication.
The Nuts node supports JWT Bearer Token authentication which can be enabled on any HTTP endpoint.
You can enable it by setting auth.type
(see example above) to token
for the specific bind.
The specified path, and its all subpaths, will then require a JWT token generated by the Nuts node.
You can generate a token using the following command, which needs to be executed on the Nuts node itself:
nuts http gen-token admin 365
This command generates a token for a user named “admin” which is valid for 365 days. The user’s name is used for logging HTTP requests.
It outputs the token, which should be passed using --token
or --token-file
when performing CLI operations or as Authorization
Bearer token header for other clients, such as XIS applications.
You can also save it to a file named .nuts-client.cfg
in your user’s home directory, which will be read by CLI when no other token flags are passed.
See the server configuration and CLI command reference for more information.
Diagnostics
To aid problem diagnosis every node in a network should share some information about itself; the type and version of software it’s running,
which peers it is connected to and how long it’s been up. This helps others diagnosing issues when others experience communication problems with your, and other nodes.
Although discouraged, this can be disabled by specifying 0
for network.v2.diagnosticsinterval
.
Monitoring Harmful Activity
Deployment should monitor incoming traffic for potentially harmful activity, e.g. excessive amounts of valid requests, or requests that generate lots of errors. This could be caused by a malicious actor (trying to cause denial of service or trying to gain access to the system’s data), but it could also be caused by a bug in a client application (e.g. XIS/EHR) or a bug in the Nuts Node.
This is no different than monitoring access to any other valued system, so it can be solved using the existing tools to prevent (distributed) denial of service attacks and intrusion detection.
Special attention should be given to:
the
/public
HTTP endpoint (because it has no authentication and is used to access IRMA sessions),the gRPC interface (because it allows other nodes to read/write network transactions),
the
/n2n
(because it allows other to request access tokens for your systems)
Since the gRPC interface and /n2n
HTTP endpoint are authenticated using the TLS client certificate,
you can monitor (and potentially deny) access to these endpoint by identifying the exact client.