Running a Grails 3 App with a Self-Signed SSL certificate

28 Jun 2017

Tags: Grails, Deployment,

The Grails run-app command documentation describes how to use the -https flag to serve your app over HTTPS.

https - Start an HTTPS server (on port 8443 by default) alongside the main server. Just to be clear, the application will be accessible via HTTPS and HTTP. A self-signed key will be generated. Intended for development use only.

If you run the following command:

grails run-app -https // with HTTPS

Your app will be served at https://localhost:8443

However, as stated in the documentation, the https flag is intended for development use only. In real-world applications, an SSL certificate from a Certificate Authority, would be used to verify your application’s identity with clients. However, it is also possible to generate a self-signed certificate for testing purposes. A self-signed certificate doesn’t provide the identity protection that a CA offers, but the steps involved in configuring a self-signed certificate with your Grails app will be largely the same with a CA certificate.

Generate your self-signed SSL certificate

You can generate a self-signed certificate using the openssl command-line utility. This is installed by default on most Unix-based OS’s, and can be installed on Windows as well.

We can use openssl’s req command to create a self-signed certificate:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

We’re using several command options:

  • x509 This option outputs a self-signed certificate instead of a certificate request.
  • newkey This option creates a new certificate request and a new private key. rsa:nbits, where nbits is the number of bits, generates an RSA key nbits in size.
  • keyout This specifies the filename for the the newly created private key.
  • out This specifies the output filename to write the certificate
  • days When used with the -x509 option, days specifies the number of days to certify the certificate for. The default is 30.

You can learn about other req options by running man req

The previous command will prompt you to supply metadata about the certificate, such as Country, Organization, etc. Moreover, it will ask you to provide a PEM pass phrase. Enter a random password and keep it safe; we will need in the next step.

Now you have you self-signed certificate. Unfortunately Grails (and Spring Boot) doesn’t support the PEM format directly. Instead, we need to use the PKCS12 format for our keys. Fortunately, there is another openssl command to make the conversion:

openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 -name tomcat -caname root

Again, we’re using a few options:

  • export This option specifies that a PKCS#12 file will be created rather than parsed.
  • name This specifies the certificate entry for the certificate and private key. When we edit our application.yml file, we will use this name as the keyAlias
  • in This specifies filename of the PKCS#12 file to be parsed.
  • inkey File from which to read the private key.
  • caname This specifies the “friendly name” for other certificates

You can learn more about the pkcs121 command by running man pks12

Modify Grails Configuration to use the certificate

Update grails-app/conf/application.yml with the following lines:

server:
    port: 8443
    ssl:
        keyStore: /certificates/keystore.p12
        keyStorePassword: secret
        keyAlias: tomcat

You can read more about pkcs121 by running man pks12

Using Java KeyStores

If you are deploying your app to a container like Tomcat, you will need to use a Java KeyStore (JKS) to store your SSL certificate. We can use the keytool command-line utility (provided by Java) to create a JKS from our PKCS#12 keystore.

Use the importkeystore command to import and create the new keystore:

keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -srcalias tomcat -destkeystore keystore.jks -deststoretype jks -deststorepass secret -destalias tomcat
  • srckeystore Source keystore (in our case, keystore.p12)
  • srcstoretype Source keystore type
  • srcalias Certificate entry in the source keystore (in our case, “tomcat”)
  • destkeystore File name for the JKS
  • deststoretype Keystore type (JKS)
  • deststorepass Password for the JKS
  • destalias Certificate entry in the JKS

Now we can update our application.yml to use the JKS file instead of the PKCS#12 keystore.

server:
    port: 8443
    ssl:              
        enabled: true
        keyStore: /certificates/keystore.jks
        keyStorePassword: secret
        keyAlias: tomcat

Example:

Github Repository with a Grails sample application

Published on 28 Jun 2017