Thoughts of a software developer

18.05.2023 15:23 | Modified 18.05. 15:26
Example ssl keystore reloading with spring-boot and tomcat

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