Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 89 additions & 12 deletions doc/api/quic.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,34 @@ added: v23.8.0

True if `endpoint.destroy()` has been called. Read only.

### `endpoint.setSNIContexts(entries[, options])`

<!-- YAML
added: REPLACEME
-->

* `entries` {object} An object mapping host names to TLS identity options.
Each entry must include `keys` and `certs`.
* `options` {object}
* `replace` {boolean} If `true`, replaces the entire SNI map. If `false`
(the default), merges the entries into the existing map.

Replaces or updates the SNI TLS contexts for this endpoint. This allows
changing the TLS identity (key/certificate) used for specific host names
without restarting the endpoint. Existing sessions are unaffected — only
new sessions will use the updated contexts.

```mjs
endpoint.setSNIContexts({
'api.example.com': { keys: [newApiKey], certs: [newApiCert] },
});

// Replace the entire SNI map
endpoint.setSNIContexts({
'api.example.com': { keys: [newApiKey], certs: [newApiCert] },
}, { replace: true });
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a good argument for the sni object form in the options, for performance & simplicity in the common case. I'm not so sure about the dynamic update method though?

We are eventually going to need a callback here (for dynamic cert generation, wildcard certificates, on-demand cert loading, etc). I would expect most setSNIContexts use cases would be subsumed by a SNICallback option, which means this method is largely redundant, and a callback would be more consistent with all our other TLS configuration anyway. Is there a use case I'm missing where this is API is preferable?

Not really opposed if you'd prefer to do this now and punt callbacks to later anyway, just want to make sure we're not aiming to implement this to replace SNI callbacks entirely, because I don't think it'll be sufficient.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, comes down to use cases. The current design keeps the implementation simple and easier to optimize. It's not immediately apparent if callbacks will definitely be needed later

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not immediately apparent if callbacks will definitely be needed later

It's a hard requirement for anywhere you need to generate certs on demand (where you don't know the cert subject until you read the SNI). That means localhost HTTPS setups for dev servers etc, mitm proxies (full disclosure - I make one of these), self-hosting homelabs, etc. If you don't know the hostnames involved before the connection arrives, you can't use the current API. Not a day 1 use case, but it'd be good to support this eventually.

Not strictly required but very useful for plenty of other cases, like wildcard certs (SNI is x.example.com, match that to a wildcard cert for *.example.com) or platforms with very large numbers of hosts available, or dynamic ACME setups where you need to read the cert from some store on demand.

Happy to avoid it for now if that helps, there's no long-term downside to this if it helps for now, but we will need a callback as well eventually.


### `endpoint.stats`

<!-- YAML
Expand Down Expand Up @@ -1120,15 +1148,16 @@ added: v23.8.0

The ALPN protocol identifier.

#### `sessionOptions.ca`
#### `sessionOptions.ca` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}

The CA certificates to use for sessions.
The CA certificates to use for client sessions. For server sessions, CA
certificates are specified per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.cc`

Expand All @@ -1143,15 +1172,16 @@ Specifies the congestion control algorithm that will be used

This is an advanced option that users typically won't have need to specify.

#### `sessionOptions.certs`
#### `sessionOptions.certs` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}

The TLS certificates to use for sessions.
The TLS certificates to use for client sessions. For server sessions,
certificates are specified per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.ciphers`

Expand All @@ -1163,15 +1193,16 @@ added: v23.8.0

The list of supported TLS 1.3 cipher algorithms.

#### `sessionOptions.crl`
#### `sessionOptions.crl` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}

The CRL to use for sessions.
The CRL to use for client sessions. For server sessions, CRLs are specified
per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.groups`

Expand All @@ -1193,7 +1224,7 @@ added: v23.8.0

True to enable TLS keylogging output.

#### `sessionOptions.keys`
#### `sessionOptions.keys` (client only)

<!-- YAML
added: v23.8.0
Expand All @@ -1205,7 +1236,8 @@ changes:

* Type: {KeyObject|KeyObject\[]}

The TLS crypto keys to use for sessions.
The TLS crypto keys to use for client sessions. For server sessions,
keys are specified per-identity in the [`sessionOptions.sni`][] map.

#### `sessionOptions.maxPayloadSize`

Expand Down Expand Up @@ -1288,15 +1320,56 @@ added: v23.8.0
Specifies the maximum number of milliseconds a TLS handshake is permitted to take
to complete before timing out.

#### `sessionOptions.sni`
#### `sessionOptions.servername` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {string}

The peer server name to target.
The peer server name to target (SNI). Defaults to `'localhost'`.

#### `sessionOptions.sni` (server only)

<!-- YAML
added: REPLACEME
-->

* Type: {Object}

An object mapping host names to TLS identity options for Server Name
Indication (SNI) support. This is required for server sessions. The
special key `'*'` specifies the default/fallback identity used when
no other host name matches. Each entry may contain:

* `keys` {KeyObject|KeyObject\[]} The TLS private keys. **Required.**
* `certs` {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}
The TLS certificates. **Required.**
* `ca` {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}
Optional CA certificate overrides.
* `crl` {ArrayBuffer|ArrayBufferView|ArrayBuffer\[]|ArrayBufferView\[]}
Optional certificate revocation lists.
* `verifyPrivateKey` {boolean} Verify the private key. Default: `false`.

```mjs
const endpoint = await listen(callback, {
sni: {
'*': { keys: [defaultKey], certs: [defaultCert] },
'api.example.com': { keys: [apiKey], certs: [apiCert] },
'www.example.com': { keys: [wwwKey], certs: [wwwCert], ca: [customCA] },
},
});
```

Shared TLS options (such as `ciphers`, `groups`, `keylog`, and `verifyClient`)
are specified at the top level of the session options and apply to all
identities. Each SNI entry overrides only the per-identity certificate
fields.

The SNI map can be replaced at runtime using `endpoint.setSNIContexts()`,
which atomically swaps the map for new sessions while existing sessions
continue to use their original identity.

#### `sessionOptions.tlsTrace`

Expand Down Expand Up @@ -1338,15 +1411,17 @@ added: v23.8.0

True to require verification of TLS client certificate.

#### `sessionOptions.verifyPrivateKey`
#### `sessionOptions.verifyPrivateKey` (client only)

<!-- YAML
added: v23.8.0
-->

* Type: {boolean}

True to require private key verification.
True to require private key verification for client sessions. For server
sessions, this option is specified per-identity in the
[`sessionOptions.sni`][] map.

#### `sessionOptions.version`

Expand Down Expand Up @@ -1715,3 +1790,5 @@ added: v23.8.0
<!-- YAML
added: v23.8.0
-->

[`sessionOptions.sni`]: #sessionoptionssni-server-only
Loading