54 lines
5.5 KiB
Markdown
54 lines
5.5 KiB
Markdown
# Experimental post-quantum TLS key exchange (PQC)
|
|
|
|
**Version:** introduced in RustProxy 0.34.9; included in the 0.34.10 source candidate. **Default: off.** This is an experimental opt-in feature and not a production compatibility guarantee.
|
|
|
|
## What it does
|
|
|
|
Post-quantum cryptography (PQC) aims to protect key exchange from attackers with future quantum computing capabilities. **X25519MLKEM768** combines a conventional X25519 ephemeral key agreement with post-quantum **ML-KEM-768** in one TLS 1.3 *hybrid key-exchange group*. Both contributions protect the derived traffic secret. This is **not a TLS cipher suite**: AES-GCM or ChaCha20-Poly1305 and ordinary X.509 RSA/ECDSA certificates remain in use. It does not change certificate signatures to post-quantum algorithms, and does not make all parts of TLS quantum-safe.
|
|
|
|
When enabled, RustProxy uses the `aws-lc-rs` cryptography provider for selected incoming TLS policies, offering X25519MLKEM768 first and classical key-exchange groups as fallback. When disabled it keeps the existing `ring` TLS provider. The selected key exchange depends on client support and negotiation; turning the switch on does not imply every connection uses PQC. It does **not** change outbound/backend, update-check, certificate-automation or other HTTP client TLS settings.
|
|
|
|
For implementation details see [rustls defaults and PQC](https://rustls.dev/docs/rustls/manual/_05_defaults/index.html) and [X25519MLKEM768 rustls API](https://docs.rs/rustls/0.23.45/rustls/crypto/aws_lc_rs/kx_group/static.X25519MLKEM768.html).
|
|
|
|
## Enable
|
|
|
|
1. Make a configuration backup; ensure that **TLS 1.3** is enabled.
|
|
2. Open **Settings → TLS policy** and enable **Experimental post-quantum key exchange (PQC)**. Keep your current **cipher suite** list unless you have a specific reason to change it. The KEX group is enabled by the switch, **not** by adding X25519MLKEM768 to the cipher-suite textarea.
|
|
3. Select **Validate, save and apply**. The TLS status reports the configured key-exchange groups, not the group used by each individual connection.
|
|
4. Test HTTPS, HTTP/1.1, HTTP/2 and (if enabled) HTTP/3 on staging with a client that supports hybrid KEX, and with older clients that use classical KEX.
|
|
|
|
`post_quantum` is stored on the global policy (the default is false):
|
|
|
|
```json
|
|
{"tls": {"policy": {"tls12": true, "tls13": true, "cipher_suites": [], "post_quantum": true}}}
|
|
```
|
|
|
|
This fragment illustrates the `tls` field; do not replace your full configuration with it.
|
|
|
|
### Per-vhost behavior
|
|
|
|
A Vhost **inherits** the global TLS policy by default. If it has an explicit `tls_policy` override, the override may disable PQC, but it cannot enable PQC while the global setting is disabled. Existing overrides that do not contain `post_quantum` are treated as `false`, even after you enable PQC globally. HTTP/3 Vhosts require their override, if any, to match the global TLS policy exactly, including PQC. Update or remove conflicting overrides before enabling PQC on H3.
|
|
|
|
The administration TLS listener also uses the global policy when administration HTTPS is enabled. Open connections keep their negotiated keys; only **new handshakes** use the updated policy.
|
|
|
|
## Test negotiated group
|
|
|
|
Requires **OpenSSL 3.5+** with `X25519MLKEM768` support:
|
|
|
|
```bash
|
|
openssl s_client -connect example.com:443 -servername example.com \
|
|
-tls1_3 -groups X25519MLKEM768 -brief
|
|
```
|
|
|
|
Check for `Protocol version: TLSv1.3` and `Negotiated TLS1.3 group: X25519MLKEM768` (format depends on OpenSSL). Compare with a classic-only client using `-groups X25519` and test TLS 1.2 if it is enabled. For HTTP/3, also use an actual QUIC/H3 client and test with UDP blocked to verify fallback to H2/H1; `openssl s_client` does not test QUIC.
|
|
|
|
If your TLS connection ends at a CDN, load balancer or TLS-terminating proxy, the test shows **that intermediary**, not RustProxy. To check RustProxy, connect to its listener directly while preserving SNI, and verify its actual certificate.
|
|
|
|
## Caveats and rollback
|
|
|
|
- Hybrid handshakes are larger and can hit MTU/middlebox limits, especially over QUIC. Measure connection errors, handshake latency, memory and CPU under expected load. Some legacy clients and devices may reject hybrid negotiation.
|
|
- Enabling the switch changes the incoming TLS cryptographic provider to `aws-lc-rs`; some uncommon certificates, algorithms or hardware platforms may behave differently. `aws-lc-rs` requires a native C/C++ build toolchain; CMake may be needed for some build modes (non-FIPS commonly does not require it). The `ring` provider remains used where the switch is off and for existing outbound integrations.
|
|
- A non-empty cipher-suite allowlist must contain suites supported by the selected provider; invalid combinations are rejected. PQC requires TLS 1.3.
|
|
- For immediate rollback, **uncheck PQC in Settings → TLS policy and save**, and if necessary remove per-Vhost overrides that require PQC. Confirm new connections negotiate classic X25519. Existing sessions cannot renegotiate in place; close/reconnect them to retest. Keep the prior binary and backups available for a full rollback.
|
|
- **Release verification:** the PQC implementation inherited from 0.34.9 still requires native Cargo build, TLS handshake, QUIC interoperability and production load acceptance. Verify the provisionally updated `Cargo.lock` with `cargo metadata --locked` (and refresh it with Cargo if needed), then run `cargo check --all-targets`, `cargo test --all-targets`, `cargo build --release`, and protocol tests before deployment. See the release changelog and source verification notes.
|