1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
title: Mutual TLS (mTLS)
description: Require clients to present a certificate signed by a trusted CA on every HTTPS and QUIC connection.
Mutual TLS (mTLS) enforces two-way authentication: the server presents its
certificate to the client as usual, and the client must also present a
certificate signed by a CA that the server trusts. Connections that do not
present a valid client certificate are rejected at the TLS handshake layer,
before any HTTP traffic is exchanged.
Set `RWS_CONFIG_TLS_CLIENT_CA_FILE` to the path of a PEM file containing the
CA certificate (or certificate chain) whose signatures you trust:
```bash
export RWS_CONFIG_TLS_CLIENT_CA_FILE=/etc/ssl/client-ca.pem
```
```toml
tls_client_ca_file = "/etc/ssl/client-ca.pem"
```
No other configuration is needed. When this variable is set,
`create_tls_acceptor_from_vhosts()` builds a `WebPkiClientVerifier` and
attaches it to the `rustls::ServerConfig`. The same CA applies to both the
HTTPS (TCP/TLS) listener and the QUIC listener used for HTTP/3.
```rust
// src/tls/mod.rs (simplified)
let verifier = WebPkiClientVerifier::builder(Arc::new(root_store))
ServerConfig::builder()
```
The CA certificate is loaded into a `RootCertStore`. Every TLS `ClientHello`
that follows must include a certificate chain rooted in that store.
Create a self-signed CA and a client certificate signed by it:
```bash
openssl req -x509 -newkey rsa:4096 -keyout ca-key.pem -out ca.pem \
-days 3650 -nodes -subj "/CN=MyTestCA"
openssl req -newkey rsa:2048 -keyout client-key.pem -out client.csr \
-nodes -subj "/CN=test-client"
openssl x509 -req -in client.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out client.pem -days 365
```
```bash
curl --cert client.pem --key client-key.pem \
```
`--cacert cert.pem` tells curl to trust the server's self-signed certificate.
`--cert` / `--key` provide the client certificate and key that the server
validates against `client-ca.pem`.
mTLS applies globally to all connections on the TLS port. There is no per-route
or per-virtual-host granularity at the TLS layer; use application middleware
(e.g., `JwtLayer` or a custom `Middleware`) for finer-grained access control
within a single TLS session.
:::note[Plain HTTP connections]
mTLS only applies to TLS connections. Plain HTTP/1.1 connections (when no cert
is configured, or connections on a redirect port) are not affected.
:::