Tomcat yeniden başlatılmadan SSL sertifikasını yeniden yükleyebilir mi?


12

Tomcat'in SSL kimlik bilgileri için kullandığı anahtar deposunu güncelleyebilen bir arka plan işlemim var. Manuel yeniden başlatmaya gerek kalmadan Tomcat'in bunu otomatik olarak yeniden yüklemesini sağlamak istiyorum.

Tomcat'in yeniden başlatmadan bunu yeniden yüklemesi mümkün mü yoksa bunun yerine programlı bir yol var mı?

Yanıtlar:


6

Arka plan işleminiz tomcat'i otomatik olarak yeniden başlatabilse de, bunu otomatik olarak yapmanın bir yolu olduğuna inanmıyorum. Anahtar deposu yalnızca bir kez jvm başlatıldığında okunur. Anahtar deposunu periyodik olarak yeniden kontrol eden kendi işleyicinizi yazmanız gerekiyorsa, ancak kişisel olarak bunun internette herhangi bir örneğini bulamadım.


8

Tek tek Tomcat bağlayıcısını yeniden başlatabilirsiniz, yani jssecacert dosyanızı değiştirdikten sonra 8443 gibi bağlantı noktası yeniden başlatma mümkündür.

Sertifikaları ekledikten / sildikten sonra tomcat bağlayıcılarını yeniden başlatmak için kullandığım kodun tamamını / yöntemini burada bulabilirsiniz.

// Stop and restart the SSL connection so that the tomcat server will
// re-read the certificates from the truststore file.
public void refreshTrustStore() throws Exception 
{
    try 
    {
        //following line should be replaced based on where you get your port number. You may pass in as argument to this method
        String httpsPort = configurationManager.getHttpsPort();
        String objectString = "*:type=Connector,port=" + httpsPort + ",*";

        final ObjectName objectNameQuery = new ObjectName(objectString); 

        for (final MBeanServer server: MBeanServerFactory.findMBeanServer(null))
        {
            if (!server.queryNames(objectNameQuery, null).isEmpty())
            {
                MBeanServer mbeanServer = server;
                ObjectName objectName = (ObjectName) server.queryNames(objectNameQuery, null).toArray()[0];

                mbeanServer.invoke(objectName, "stop", null, null);

                // Polling sleep to reduce delay to safe minimum.
                // Use currentTimeMillis() over nanoTime() to avoid issues
                // with migrating threads across sleep() calls.
                long start = System.currentTimeMillis();
                // Maximum of 6 seconds, 3x time required on an idle system.
                long max_duration = 6000L;
                long duration = 0L;
                do
                {
                    try
                    {
                        Thread.sleep(100);
                    }
                    catch (InterruptedException e)
                    {
                        Thread.currentThread().interrupt();
                    }

                    duration = (System.currentTimeMillis() - start);
                } while (duration < max_duration &&
                        server.queryNames(objectNameQuery, null).size() > 0);

                // Use below to get more accurate metrics.
                String message = "TrustStoreManager TrustStore Stop: took " + duration + "milliseconds";
                logger.information(message);

                mbeanServer.invoke(objectName, "start", null, null);

                break;
            }
        }
    } 
    catch (Exception exception) 
    {
        // Log and throw exception
            throw exception
    }
}

1
Bu yalnızca bağlayıcı bindOnInit="false"seçenekle yapılandırılmışsa çalışır .
anilech

4

Şimdi bunu tomcat v8.5.24 ile başlamanın bir yolu var.

İki yöntem sundular:

  1. reloadSslHostConfig (String hostName) - belirli bir ana bilgisayarı yeniden yüklemek için
  2. reloadSslHostConfigs () - tümünü yeniden yükle

Çeşitli şekillerde çağrılabilirler:

  1. Jmx kullanma
  2. Yönetici hizmetini kullanma (tomcat v9.xx içinde)
  3. Özel protokol yaparak - araştırmalarımda bu şekilde buldum

1. ve 2. yolların ayrıntıları tomcat belgelerinde kolayca bulunabilir.

3. yolu nasıl kullanacağınızla ilgili ayrıntılar:

  1. Örneğin, istediğiniz protokolü genişleten bir sınıf yapın. Http11NioProtocol
  2. Gerekli yöntemleri geçersiz kılın ve varsayılan davranışı korumak için bunlara super çağırın
  3. ReloadSslHostConfigs yöntemini zaman zaman çağırmak için bu sınıfta bir iş parçacığı oluşturun
  4. Bu sınıfı bir kavanoza paketleyin ve bu kavanozu tomcat'in lib klasörüne koyun
  5. Bu özel tanımlı protokolü kullanmak için server.xml dosyasındaki bağlayıcıdaki protokolü düzenle

Örnek kodu aşağıda bulabilirsiniz:

Ana protokol sınıfı:

package com.myown.connector;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentMap;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.net.ssl.SSLSessionContext;

import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.AbstractJsseEndpoint;
import org.apache.tomcat.util.net.GetSslConfig;
import org.apache.tomcat.util.net.SSLContext;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SSLImplementation;
import org.apache.tomcat.util.net.SSLUtil;

public class ReloadProtocol extends Http11NioProtocol {

    private static final Log log = LogFactory.getLog(Http12ProtocolSSL.class);

    public ReloadProtocol() {
        super();
        RefreshSslConfigThread refresher = new 
              RefreshSslConfigThread(this.getEndpoint(), this);
        refresher.start();
    }

    @Override
    public void setKeystorePass(String s) {
        super.setKeystorePass(s);
    }

    @Override
    public void setKeyPass(String s) {
        super.setKeyPass(s);
    }

    @Override
    public void setTruststorePass(String p) {
        super.setTruststorePass(p);
    }

    class RefreshSslConfigThread extends Thread {

        AbstractJsseEndpoint<?> abstractJsseEndpoint = null;
        Http11NioProtocol protocol = null;

        public RefreshSslConfigThread(AbstractJsseEndpoint<?> abstractJsseEndpoint, Http11NioProtocol protocol) {
            this.abstractJsseEndpoint = abstractJsseEndpoint;
            this.protocol = protocol;
        }

        public void run() {
            int timeBetweenRefreshesInt = 1000000; // time in milli-seconds
            while (true) {
                try {
                        abstractJsseEndpoint.reloadSslHostConfigs();
                        System.out.println("Config Updated");
                } catch (Exception e) {
                    System.out.println("Problem while reloading.");
                }
                try {
                    Thread.sleep(timeBetweenRefreshesInt);
                } catch (InterruptedException e) {
                    System.out.println("Error while sleeping");
                }
            }
        }
   }
}

Server.xml dosyasındaki bağlayıcı protokol olarak şunu belirtmelidir:

<Connector protocol="com.myown.connector.ReloadProtocol"
 ..........

Bu yardımcı olur umarım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.