Setting up a HTTPS Restlet Webserver


For all of our services (such as Haplogrep), we are using Restlet on server side. This blog entry summarizes the necessary steps to set up a working HTTPS Restlet Server with a valid certificate and a trusted connection. Check out the Github Repo for the source code!

Set up a Java Keystore

  • In a first step, a new Java Keystore needs to be created using the keytool of JDK (use at least Java 7 for this):
 
    keytool -genkey -alias <your-alias> -keyalg RSA -keysize 2048 -keypass <your-passwd> -storepass <your-passwd> -keystore <your-keystore.jks>
  • Now, generate a new certificate signing request (CSR) and send it your certificate authority (CA). Alternatively, the CSR can also be self-signed.
 
keytool -keystore <your-keystore.jks> -certreq -alias <your-alias> -keyalg RSA -keysize 2048 -file <signing-request.csr>
  • Import the received root / intermediate webserver certificate files (CRTs) from your CA like this (I received two files):
 
keytool -import -alias intermed -keystore <your-keystore.jks> -trustcacerts -file <intermed.crt>
keytool -import -alias <your-alias-from-the-csr> -file <received-file.crt> -trustcacerts -keystore <your-keystore.jks>

Create a Restlet Webapp (Updated on Nov 24)

Now it’s time to integrate your certificate into your Restlet App as described here. The running example can be found here.

 

public class SampleServer {

	public static void main(String[] args) {

		// Create a new Component.
		Component component = new Component();

		// Add a new HTTP server listening on port 8080
		Server server = component.getServers().add(Protocol.HTTP, 8080);

		// Add your HTTPS specifications
		String file = "location-to-your-file";
		String keystorePwd = "your-password";
		String keyPwd = "your-password";
		File keystoreFile = new File(file);

		if (keystoreFile.exists()) {

			component.getServers().add(Protocol.HTTPS, 4443);
			Series<Parameter> parameters = server.getContext().getParameters();
			parameters.add("sslContextFactory",
					"org.restlet.engine.ssl.DefaultSslContextFactory");
			component
					.getContext()
					.getParameters()
					.add("enabledCipherSuites",
							"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"
									+ " TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
									+ " TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
									+ " TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
									+ " TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
									+ " TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
									+ " TLS_RSA_WITH_AES_256_CBC_SHA"
									+ " TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"
									+ " TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
									+ " TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"
									+ " TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
									+ " TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA");

			parameters.add("keyStorePath", keystoreFile.getAbsolutePath());
			parameters.add("keyStorePassword", keystorePwd);
			parameters.add("keyPassword", keyPwd);
			parameters.add("keyStoreType", "JKS");
			parameters.add("allowRenegotiate", "false");
		}

		component.getDefaultHost().attach(new Application() {
			@Override
			public Restlet createInboundRoot() {
				Router router = new Router();
				router.attach("/", Index.class);

				return router;
			}
		});

		// Start the component.
	component.start();
	
	}
}

Important Note

Keep in mind that your service should use the latest version of Restlet (currently 2.3) and Java 8 to avoid errors like this on Firefox (result: no connection can be established!):

 
SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message. (Error code: ssl_error_weak_server_ephemeral_dh_key)

or this one on Chrome (result: connection can be established but with warnings):

 
Your connection is encrypted with obsolete cryptography.
The connection is encrypted using AES_256_CBC, with SHA1 for message authentication and DHE_RSA as the key exchange mechanism.

This short tutorial should give you an up and running Restlet server and avoid many mistakes I did in the past. Contact me if something is unclear!

Related Posts

Haplogrep on GitHub

Imputation Scripts

NAR WebServer Issue Publication - mtDNA-Server

NAR WebServer Issue Publication - HaploGrep2

Hadoop Services for Everyone

This post shows how we combine the Hadoop Docker Image (CDH5) with our Hadoop workflow system Cloudgene. Due to Cloudgene's interface, new applications can be registered to Cloudgene and provided as a service to everyone.

Cloudgene, a Hadoop-As-A-Service approach

This post introduces the graphical Hadoop platform Cloudgene and shows how simple a Hadoop command line program (or a workflow of several programs) can be provided as a web service to everyone. Two services in Genetics based on Cloudgene are already available and showing promising success.

Creating a Docker Image for Hadoop MapReduce (CDH5)