I couldn’t find an easy way to reload ssl keystore after tomcat start without restarting the application.
Inspired by this Stackoverflow answer, I decided to make a simple example with spring-boot using tomcat to do the reloading.
Simplified, the whole thing is here:
TomcatServletWebServerFactory tomcatFactory = (TomcatServletWebServerFactory) servletWebServerFactory;
Collection<TomcatConnectorCustomizer> customizers = tomcatFactory.getTomcatConnectorCustomizers();
...
DefaultSSLConnectorCustomizer customizer = (DefaultSSLConnectorCustomizer) tomcatConnectorCustomizer;
AbstractHttp11Protocol protocol = customizer.getProtocol();
protocol.reloadSslHostConfigs();
In application.properties, ssl config is:
server.port=8443
server.ssl.key-store=/tmp/cert/webservice_localhost-keystore.pkcs12
server.ssl.key-store-password=password
server.ssl.keyStoreType=PKCS12
server.ssl.protocol=TLS
server.ssl.enabled-protocols=TLSv1.2
In Application.java, following bean starts the whole thing by adding a new DefaultSSLConnectorCustomizer.
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addConnectorCustomizers(new DefaultSSLConnectorCustomizer());
return tomcat;
}
Then we have a service SSLRenewSertificateStoreService, in which we have the scheduled call for renewing the certificates.
@Scheduled(cron = "*/30 * * * * *")
public void reloadSertificateStore() {
tomcatUtil.reloadSSLHostConfig();
}
After starting the app with mvn clean spring-boot:run
, you can see when the current sertificate in use will stop being valid
$ openssl s_client -servername localhost -connect localhost:8443 2>/dev/null | openssl x509 -noout -dates
notBefore=May 17 18:03:51 2023 GMT
notAfter=May 15 18:03:51 2028 GMT
You can change the keystore (and sertificate in it) in /tmp/cert/webservice_localhost-keystore.pkcs12
and then see how the server load a new keystore and how the validity dates of the sertificates change. You can also do this in your browser by loading https://localhost:8443/
.
Link to github with the project: github