This stores worker connection nonces within the database to ensure uniqueness of connections. Prior the connection required any attacker to be able to decrypt the incoming encrypted authentication message in order to replay (and if the attacker has access to the KMS you have bigger problems), but with this change even if an attacker does have access to the KMS key, they cannot reuse the same message. (If they're able to encrypt against the KMS key, they can still act as a worker with a new message, so this only really helps if they only have decryption capabilities.)
134 lines
6.3 KiB
Plaintext
134 lines
6.3 KiB
Plaintext
---
|
|
layout: docs
|
|
page_title: Connections/TLS
|
|
description: |-
|
|
How Boundary secures its connections
|
|
---
|
|
|
|
# TLS in Boundary
|
|
|
|
As a security product, Boundary has been designed from the ground up to ensure
|
|
its connections are secure. There are three types of connections in Boundary;
|
|
this page will describe how TLS works with each of them.
|
|
|
|
Some of the ways that Boundary uses TLS, e.g. for client-to-worker connections,
|
|
are different from most other products. It may not be readily apparent that user
|
|
configuration of TLS on the listening port of Workers is not only not required,
|
|
but more secure; however, when it comes to TLS, Boundary tries to provide high
|
|
security by default with simplicity of operation.
|
|
|
|
Details are in the individual sections below.
|
|
|
|
## Client-to-Controller TLS
|
|
|
|
Boundary's API access (that is, the Controller server defaulting to port 9200)
|
|
uses standard PKI. TLS is configured by providing a valid certificate (and
|
|
optionally CA certificate or chain) and clients must trust that CA chain. This
|
|
provides broad compatibility with a wide array of clients.
|
|
|
|
It is possible to require client certificates; see the configuration for
|
|
`listener` blocks to see the available TLS parameters.
|
|
|
|
## Worker-to-Controller TLS
|
|
|
|
The service exposed by the Controller to handle Worker requests takes
|
|
advantage of the [KMS](/docs/concepts/security/data-encryption) key designated
|
|
for `worker-auth` within Boundary's configuration file, which must point to the
|
|
same key on the KMS for both the Controller and the Worker. Security of the
|
|
connection relies on secure transmission of a single set of allowed TLS
|
|
parameters, which forms the entire allowable CA chain for the connection.
|
|
|
|
TLS establishment is performed as follows:
|
|
|
|
1. The Worker generates a TLS certificate acting as a self-contained chain, as
|
|
well as a nonce. The generated key type is currently Ed25519. The certificate is
|
|
valid for a total of 2.5 minutes: thirty seconds before the current time (to
|
|
allow for some minor clock drift) and two minutes after (to allow time to
|
|
establish the connection).
|
|
|
|
2. The Worker marshals the TLS chain and nonce and encrypts the resulting bytes
|
|
via the shared KMS. This value is marshaled and split into chunks.
|
|
|
|
3. The Worker establishes a TLS 1.3 connection to the Controller. The encrypted
|
|
value is transmitted to the Controller via the TLS ALPN field as numbered
|
|
chunks.
|
|
|
|
4. The Controller reads the chunks and reassembles them into the original
|
|
encrypted value.
|
|
|
|
5. The Controller decrypts this value via the shared KMS. If successful, the
|
|
Controller validates that the nonce is not known to ensure that this is not a
|
|
replay. The nonce value is checked against and stored into the database,
|
|
ensuring that nonce replay cannot occur across controllers.
|
|
|
|
6. The Controller uses the decrypted parameters to configures its TLS stack with
|
|
the same certificate and key.
|
|
|
|
7. The connection is mutually authenticated; on each end, only the single
|
|
self-signed CA certificate that was securely transmitted is configured as a
|
|
valid root CA for validation checking.
|
|
|
|
## Client-to-Worker TLS
|
|
|
|
Workers do not require any configuration for their client-facing listeners to
|
|
support a high degree of security. Instead, the TLS configuration to use is
|
|
determined dynamically via SNI, and the session is then mutually authenticated.
|
|
Here's how it works:
|
|
|
|
TLS establishment is performed as follows:
|
|
|
|
1. When the session is authorized, the Controller generates a TLS certificate
|
|
acting as a self-contained chain. This is similar to the Worker-to-Controller
|
|
flow above, but in this case the key is an Ed25519 key generated via
|
|
derivation from a base key within the Controller, which itself is protected
|
|
at rest via the "root" KMS for the scope that contains the target. The
|
|
derivation uses HKDF-SHA256 with the user ID and the session ID as inputs.
|
|
The lifetime of the certificate is tied to the lifetime of the session.
|
|
|
|
2. The certificate and private key (along with other session authorization data,
|
|
notably the session ID) are returned to the client as part of the output of an
|
|
`authorize-session` action against a target, in the form of a marshaled object.
|
|
The controller persists the certificate in the database, but not the private
|
|
key.
|
|
|
|
3. The client (that is, the `boundary connect` command) parses this session
|
|
authorization data and uses the certificate and private key to construct a TLS
|
|
stack. It then makes a TLS 1.3 connection to a Worker, passing the session ID as
|
|
the SNI value.
|
|
|
|
4. The worker sees the SNI value and makes a call to the Controller to fetch
|
|
session authorization information, keyed by the session ID.
|
|
|
|
5. The Controller looks for a session with the given ID and fetches the
|
|
information. Using the session ID and the user ID tied to the session, it
|
|
re-derives the private key and passes all of the information back to the Worker.
|
|
Notably, this may include a TOFU (Trust On First Use) token.
|
|
|
|
6. The Worker uses the given data to construct a TLS stack with the same
|
|
certificate and key.
|
|
|
|
7. The connection is mutually authenticated; on each end, only the single
|
|
self-signed CA certificate that was securely transmitted is configured as a
|
|
valid root CA for validation checking.
|
|
|
|
8. If successful, the client and Worker perform a handshake, where the client
|
|
passes a TOFU (Trust On First Use) value to the Worker. This value is derived
|
|
when the client is created; that is, when `boundary connect` is run. This allows
|
|
for a single client to make multiple connections within a session, without the
|
|
credentials being usable via a different client:
|
|
|
|
- If the worker was not given a TOFU token in step 5, the worker submits the
|
|
value to the Controller. The Controller verifies (via a database transaction)
|
|
that the session has not had a different TOFU token submitted prior and stores
|
|
it. Otherwise it's rejected, and so is the connection, as a possible replay
|
|
attack.
|
|
|
|
- If the Worker was given a TOFU token in step 5, it checks to see whether the
|
|
token values match. If not, the connection is rejected as a possible replay
|
|
attack.
|
|
|
|
In the future, to support other client paradigms, we may support user
|
|
configuration of the Worker's client-facing TLS. In this model, the shared
|
|
certificate/private key would instead act as credentials for the session,
|
|
similar to a username/password.
|