Running a Grails® 3 App With a Self-Signed SSL Certificate
June 28, 2017
Tags: #ssl #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
, wherenbits
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 the Grails framework (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 thekeyAlias
- 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