Create a self-signed certificate for SSL

Background

This article outlines how to create and install SSL keys, CSRs and self-signed certificate into Jetty.

Before you start

If you have received a certificate from an external source skip to the load keys and certificates section.

Generate SSL keys, CSRs and self signed certificates

The following section provides a brief tutorial of creating self-signed certificates via openssl. These steps detail how to generate private key files (.key), certificate signing request file (.csr) and webserver certificate file (.crt) using openssl.

Generate private key

This generates a file called server.key which contains a private key.

$ openssl genrsa -des3 -out server.key 1024

Generate a certificate signing request (CSR)

This generates a file called server.csr which is a certificate signing request.

$ openssl req -new -key server.key -out server.csr

Generate a self-signed SSL certificate

This creates a file called server.crt which is a self-signed certificate that is valid for one year.

$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Load keys and certificates

Once you have received a certificate from a CA or client (or a user generated one), it will need to be loaded into the JSSE keystore.

Loading certificates with keytool

Use keytool to load a certificate in PEM form to a keystore. For example, if you have a file called server.crt that contains the certificate the following command loads the certificate above into a custom JSSE keystore in $SEARCH_HOME/web/conf (There will already be a default keystore file in $SEARCH_HOME/web/conf).

$ keytool -keystore <installdir>/web/conf/custom-keystore -import -alias jetty -file server.crt

Configure Jetty to use a custom keystore

To make use of the custom-keystore generated in the previous section, do the following:

Funnelback v15.0 and newer

In Funnelback v15 and newer the search UI binds to both HTTP 80 and HTTPS 443 so you can just change jetty.ssl.* configs to refer to your keystore path and password. This can be done via global.cfg.

Add the following in global.cfg and then restart Jetty and check $SEARCH_HOME/log/ and check jetty logs for details of whether it succeeded or failed.

global.cfg

jetty.ssl.keymanager-password=password
jetty.ssl.keystore-path=web/conf/custom-keystore
jetty.ssl.keystore-password=password
jetty.ssl.truststore-path=web/conf/custom-keystore
jetty.ssl.truststore-password=password

Funnelback v14.2 and earlier

Copy $SEARCH_HOME/web/conf/customiseJettyServers.groovy_example to $SEARCH_HOME/web/conf/customiseJettyServers.groovy the edit as appropriate.

The following shows an example of how the customiseJettyServers.groovy file would be configured to use the custom-keystore.

Restart Jetty and check $SEARCH_HOME/log/ and check jetty logs for details of whether it succeeded or failed.

Example config of customiseJettyServers.groovy:

customiseJettyServers.groovy
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.server.Connector;

def Map<String, Server> customise(Map<String, Server> servers) {
    // This method can customise Jetty servers before they are started by Funnelback
    // We may normally use up to three servers
    //
    // "public" - deploys search interfaces from $SEARCH_HOME/wec/conf/contexts-http on jetty.search_port
    // "admin" - deploys search and admin interfaces from $SEARCH_HOME/wec/conf/contexts-https on jetty.admin_port
    //
    // If jetty.manifoldcf_port is set to a value, we also use
    // "manifoldcf" - deploys manifoldcf $SEARCH_HOME/wec/conf/contexts-manifoldcf on jetty.manifoldcf_port
    //
    // Further servers may be added, servers may be removed, or the configuration settings may be altered
    // as required.
    //
    // For example, to provide more time for the admin server to stop (default is 1000ms), the following could
    // uncommented.
    //
    // servers.get("admin").setStopTimeout(5000);
    //
    // The following example adds an SSL connector to the public search server (in addition to the standard HTTP one)
    //
     SslContextFactory sslContextFactory = new SslContextFactory();
     sslContextFactory.setKeyStorePath("/opt/funnelback/web/conf/custom-keystore");
     sslContextFactory.setKeyStorePassword("password");
     sslContextFactory.setTrustStorePath("/opt/funnelback/web/conf/custom-keystore");
     sslContextFactory.setTrustStorePassword("password");
     sslContextFactory.addExcludeProtocols("SSLv3"); // For POODLE
     ServerConnector sslConnector = new ServerConnector(servers.get("public"), sslContextFactory);
     sslConnector.setPort(443);
     servers.get("public").addConnector(sslConnector);

    // This method is expected to return the new map of servers to be started.
    return servers;