GrandPa
GrandPa

Reputation: 504

How to make tomcat to pick new certificates without restarting it

We have web application where SSL certificate gets expired every 100 days and renewed automatically. We have to restart server whenever it happens to pick the newly renewed certificate. Is there any way tomcat java process can automatically pick up the new certificates whenever certificate get renewed. We have thousands of machines in our cluster.

Upvotes: 2

Views: 4190

Answers (3)

P.J.
P.J.

Reputation: 19

Try to use the Manager App:

  1. Install Tomcat Manager Application (if not yet installed).
  2. Create Tomcat user e.g. "sslAdmin" with password "sslAdminPassword" – in file conf/tomcat-users.xml in section <tomcat-users> add the flollowing two lines (if not yet exists):
<role rolename="manager-script"/>
<user username="sslAdmin" password="sslAdminPassword" roles="manager-script" />
  1. Start or restart Tomcat
  2. From this moment, you can reload SSL configuration without restarting the whole service from command line by the following command (see Reload TLS configuration):
curl -u sslAdmin:sslAdminPassword http://localhost:8080/manager/text/sslReload

Note, that for the above example, Tomcat must use the port 8080.

Upvotes: 1

abinash sahoo
abinash sahoo

Reputation: 177

If u have embeded tomcat then u can use tomcat api to reload all certificate. Check : How do I force tomcat to reload trusted certificates? The easiest way is read the keystore programmatically, get a SSL context from that and use it to make connection.

private SSLContext buildSslSocketContext() {

        logger.info("Started checking for certificates and if it finds the certificates will be loaded…..");

        String keyStoreLoc = //KEYSTORE LOCATION;
        String password = //KEYSTORE_PASSWORD;
        SSLContext context = null;
        
        try {
            // Create a KeyStore containing our trusted CAs
            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            InputStream in = null;

            try {
                in = new FileInputStream(keyStoreLoc);
                keystore.load(in,password.toCharArray());
            }catch(Exception e) {
                logger.error("Unable to load keystore "+e.getMessage());
            }finally {
                if(in != null) {
                    in.close(); 
                }               
            }

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keystore);

            // Create an SSLContext that uses our TrustManager
            context = SSLContext.getInstance("TLS");
            context.init(null, tmf.getTrustManagers(), null);
            logger.info("Completed loading of certificates.");

        } catch (Exception e) {
            logger.error("unable to create ssl context "+e.getMessage());
        }
        return context;
    } 

    ClientBuilder clientBuilder =  null;

        try {
            SSLContext sslContext = buildSslSocketContext();
            clientBuilder = ClientBuilder.newBuilder();
            if (sslContext != null) {
                clientBuilder.sslContext(sslContext);
            } else {
                logger.info("SSL conext is missing");
            }
            client = clientBuilder.build(); //use this client to make  http connection
        }catch(Exception e) {
            logger.error("unable to get ssl conext for client :"+e.getMessage());
        }

Upvotes: 1

Akshat Gupta
Akshat Gupta

Reputation: 11

Yes, there is a way to load certificates automatically with the help of code. All you have to do is download the certificate from the host and import that certificate into the keystore which the Connector(can be found in server.xml) of the Tomcat Server is pointing to. This can be done with the help of a tool known as keytool.

keytool -importcert -file mycertfile.pem -keystore keystore.jks -alias "Alias" -storepass <PASSWORD>

Once the certificate is added into the keystore you can initialize a SSLContext and pass it to make other subsequent calls from your server.

SSLContext sslContext = SSLContexts.custom()
            .loadTrustMaterial(new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws 
CertificateException {
                    return true;
                }
            })
            .loadKeyMaterial(<Keystore-loaded with certificate>,<password of the keystore>)
            .build();

Config config = Config.newConfig();
config.withSSLContext(sslContext);`

This config object can be passed as a parameter to the function .withConfig(config) to create the client calls.

Upvotes: 1

Related Questions