-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hot Reload for TLS Keystore #15926
Comments
Sorry for the bump but it has been quite a while since this was opened. Any input on this would be greatly appreciated. Thanks in advance. |
I'm also interested in this feature. I think this could be enabled by vert.x. I've submitted PR eclipse-vertx/vert.x#4372 to resolve issue eclipse-vertx/vert.x#3780. I only implemented PEM files so far, not key stores, but I think same approach applies for key store files as well. If the feature could be accepted by vert.x, we'd would need Quarkus to pass certificate & key as file paths, instead of passing them by file content which is done currently. Here is a small change that would do that Nordix/quarkus@main...configure-certs-by-path. |
Is there any example on how can we do this? |
I have a working example here: GitHub - Reloading SSL with Quarkus It contains code snippets on how to provide your own ssl configuration and supply that to the underlying server (vertx) programatically. It also contains the tutorial of how to replicate it on your local dev environment. Basically you need to adjust your server configuration with a import io.quarkus.vertx.http.HttpServerOptionsCustomizer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.net.KeyCertOptions;
import io.vertx.core.net.TrustOptions;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import nl.altindag.server.service.FileBasedSslUpdateService;
import nl.altindag.ssl.SSLFactory;
import org.jboss.logging.Logger;
import java.nio.file.Path;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@ApplicationScoped
public class ServerConfig implements HttpServerOptionsCustomizer {
private final Logger LOGGER;
@Inject
public ServerConfig(Logger logger) {
LOGGER = logger;
}
@Override
public void customizeHttpsServer(HttpServerOptions options) {
var sslFactory = SSLFactory.builder()
.withSwappableIdentityMaterial()
.withIdentityMaterial(Path.of("/path/to/your/identity.jks"), "secret".toCharArray())
.withSwappableTrustMaterial()
.withTrustMaterial(Path.of("/path/to/your/truststore.jks"), "secret".toCharArray())
.build();
var sslUpdateService = new FileBasedSslUpdateService(sslFactory);
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(sslUpdateService::updateSslMaterial, 1, 1, TimeUnit.MINUTES);
LOGGER.info("Checking every minute for changes on the keystore and truststore files");
options.setSsl(true)
.setPort(8443)
.setKeyCertOptions(KeyCertOptions.wrap(sslFactory.getKeyManager().orElseThrow()))
.setTrustOptions(TrustOptions.wrap(sslFactory.getTrustManager().orElseThrow()));
HttpServerOptionsCustomizer.super.customizeHttpsServer(options);
}
} This is the output which I get:
In the example project I configured the server with an inital ssl configuration with an expiration date of somewhere in 2029. After updated the keystore it was shifted to 2031. The server is configured to scan the keystore files for any changes for every minute, however that can be changed to every hour, or every day or any other duration. The magic happens in the FileBasedSslUpdateService but that is not too difficult. It is just a service checking whether the keystores have been updated and if that is the case it will regenerate the SSLFactory and update the initial one. |
For anyone else having this issue. We are just now getting around to refactoring this for our Quarkus services and the first version would be similar to what @Hakky54 has done but we will try to contribute this to Quarkus in the near future so it is either an extension or simply a set of properties for the https connector. Because we have a lot of internal tasks in the backlog I don't know when we can do this but I'm hoping this can be done until the end of this year. |
Given that |
#34997 will add something generic. We can certainly welcome contributions to that once it's in main 😎 |
Happy to see some examples above. It would be great to see this functionality in Quarkus as other frameworks have it already today: https://spring.io/blog/2023/11/07/ssl-hot-reload-in-spring-boot-3-2-0/ |
Hello everyone,
I haven't been able to find anything regarding hot reloading of TLS keystores during Quarkus runtime. I understand that Quarkus is pretty static in its concept, so dynamic reloading of resources while in the production profile is probably out of scope without custom code.
Our current setup for TLS certificates is that we have short lived certificates, a few days vailidity, which are automatically reissued with newly generated passwords. Non Quarkus services based on Jetty have no problem reloading a newly issued keystore during runtime, we only had to write some glue code to detect keystore changes and then call the reload method on the SslContextFactory.
It's probably important to note that the PKCS12 keystore is residing in an external config directory each Quarkus service accesses. So the service accesses a path like ../config/tls.p12 to get to it's keystore from inside an uber jar.
What's also important to note is that the keystore path itself does not change it is simply checked using file system events so the aforementioned ../config/tls.p12 is simply replaced and new passwords are pushed to the config.
Our current workaround for this is to simply call System.exit when a keystore change is detected and the service gets restarted automatically. This works but it does cause alerts in our monitoring and since it happens every few days, it makes it hard from distinguishing these deliberate restarts from actual crashes.
The text was updated successfully, but these errors were encountered: