actix-net
actix-net copied to clipboard
Support hot reloading of SSL credentials
It would be great if there were built-in support for hot reloading of SSL credentials, along with an example for how to do it.
Per @fafhrd91 at https://github.com/actix/actix-web/issues/754:
You just need to replace ssl acceptor. Restart is not required https://github.com/actix/actix-net/blob/master/actix-server/src/ssl/openssl.rs#L62
Looking at what it was (https://github.com/actix/actix-net/blob/3add90628f3871797794bbd727c5828ff661dc4f/actix-server/src/ssl/openssl.rs#L62 and https://github.com/actix/actix-net/blob/3add90628f3871797794bbd727c5828ff661dc4f/actix-server/src/ssl/rustls.rs#L64), seems to require a lot of set up...
Based on docs, seems that using a wrapped https://docs.rs/rustls/0.16.0/rustls/struct.ResolvesServerCertUsingSNI.html might be useful with interior mutability. Would need to use an rwlock to be able to work with it though, so might require some black magic currently.
in our reverse proxy we need to restart the server after adding a new domain or renewing a certificate. I'm really interested in implementing this feature. it's very easy in go as it accept cert resolver function.
I don't know about openssl, but this is already doable with rustls by implementing a custom CertResolver
, as an example we have the following thing :
pub struct CertResolver {
registered_keys: RwLock<BTreeMap<String, Arc<CertifiedKey>>>,
}
impl ResolvesServerCert for CertResolver {
fn resolve(&self, client_hello: ClientHello) -> Option<Arc<CertifiedKey>> {
let server_name = client_hello.server_name()?;
match self.registered_keys.read() {
Err(_) => None,
Ok(registered_keys) => registered_keys.get(server_name).cloned(),
}
}
}
Then you can use it when creating the server :
let resolver = Arc::new(CertResolver::default());
let config = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_cert_resolver(resolver);
let server = HttpServer::new(move || {
App::new()
})
.bind_rustls(listen_tls.clone(), config)
Then we have some code that update this cert resolver on some events (cert are not in filesystem), but i guess someone could definitely create a worker that listen to fs events and update this CertResolver