[Feature] SNI multi-domain certificate support for Proxy TLS
- Dominant language
- Java
- Stars
- 22.6k
- Forks
- 12k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 26
Description
### Is Your Feature Request Related to a Problem?
Currently RocketMQ Proxy supports only a **single certificate** model:
- `ProxyConfig` has only `tlsCertPath` / `tlsKeyPath` for a single cert/key pair
- gRPC and Remoting servers each build a single `SslContext`
- `TlsCertificateManager` only watches one cert/key pair for hot-reload
- No SNI (Server Name Indication) support at all
This makes it impossible to serve multiple top-level domains with different certificates on the same Proxy port.
### Describe the Solution You'd Like
Introduce **SNI (Server Name Indication)** support using Netty's `SniHandler`. The Proxy will inspect the TLS ClientHello's SNI hostname and dynamically select the corresponding certificate.
Key changes:
1. **New `TlsDomainConfig` POJO** — per-domain cert/key path configuration
2. **Extended `ProxyConfig`** — new `tlsDomainConfigs` map (domain pattern → config)
3. **New `TlsSniManager`** — manages multiple `SslContext` instances with wildcard matching
4. **Extended `TlsCertificateManager`** — watches multiple cert/key pairs independently
5. **gRPC `ProxyAndTlsProtocolNegotiator`** — uses `SniHandler` for SNI-aware TLS
6. **Remoting `NettyRemotingServer`** — `TlsModeHandler` uses `SniHandler` via `TlsContextProvider`
### Describe Alternatives You've Considered
The alternative is to run multiple Proxy instances, each with a different certificate, behind a reverse proxy (e.g. nginx) that handles SNI. However, this adds operational complexity and an extra network hop.
### Additional Context
**Configuration example:**
```yaml
# Existing config retained as default fallback
tlsCertPath: /path/to/default.crt
tlsKeyPath: /path/to/default.key
tlsCertWatchIntervalMs: 3600000
# New: domain-to-certificate mapping
tlsDomainConfigs:
"*.example.com":
certPath: /path/to/example.crt
keyPath: /path/to/example.key
"*.sample.org":
certPath: /path/to/sample.crt
keyPath: /path/to/sample.key
```
**Wildcard matching rules:**
- Exact match first
- Wildcard: `foo.example.com` matches `*.example.com`
- Bare domain: `example.com` matches `*.example.com`
- Multi-level (`a.b.example.com`) does NOT match `*.example.com`
- No match → fallback to default certificate
**Backward compatibility:** When `tlsDomainConfigs` is not configured, the behavior is identical to the current single-certificate model.
Contributor guide
Research direction
Start by tracing the existing single-certificate flow through ProxyConfig, TlsCertificateManager, ProxyAndTlsProtocolNegotiator, and NettyRemotingServer. Define the multi-domain configuration, certificate watching, SNI selection, wildcard rules, fallback behavior, and backward compatibility described in the issue; done means both gRPC and Remoting select the correct certificate and retain the current default behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, networking, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100