Linux - Let's Encrypt for Java Apps
Intro
Install certbot as mentioned in my previous post on Linux - Install Certbot.
By default, certbot retrieves a certificate and installs it immediately on the web server by adding an extra parameter, eg. --apache for Apache HTTP Server. For the case of Docker - Demo CAS Server, it is just enough to retrieve only a certificate. This is done by adding the certonly parameter to the command as follows:
1
certbot certonly
You need to make sure that the
TCPport80of the server is accessible from Let’s Encrypt servers and no other application is utilizing it.
This will spin up a temporary server on TCP port 80 to validate the authority of the domain to issue the required certificates. The installed Let’s Encrypt certificates in the /etc/letsencrypt/live directory on the file system.
Create Keystore file
To use a certificate in a Java application, the preferred way is to add it to a separate .keystore file. The Java Runtime Environment (JRE) ships with a tool called keytool to create certificates and manipulate key stores. Adding certificates to a keystore can be done by using OpenSSL and the keytool.
If the system doesn’t have JRE installed, you can install it by running the following command:
1
sudo apt install default-jre jq
Archive certificates to PKCS #12 file
Importing multiple public and private .pem certificates directly in a keystore is not supported by the keytool. Hence, it is necessary to add all .pem files to a PKCS 12 archive. This can be done by the OpenSSL tool with the following command:
1
2
3
4
5
6
7
8
openssl pkcs12 -export \
-in /etc/letsencrypt/live/cas.harryvasanth.com/cert.pem \
-inkey /etc/letsencrypt/live/cas.harryvasanth.com/privkey.pem \
-out /tmp/cas.harryvasanth.com.p12 \
-name cas.harryvasanth.com \
-CAfile /etc/letsencrypt/live/cas.harryvasanth.com/fullchain.pem \
-caname "Let's Encrypt Authority X3" \
-password pass:changeit
Change
cas.harryvasanth.comwith the custom FQDN of the target CAS server (or any Java application server).
Import PKCS #12 archive to the Keystore file
The next step is to import the certificates into a .keystore file.
1
2
3
4
5
6
7
8
9
keytool -importkeystore \
-deststorepass changeit \
-destkeypass changeit \
-deststoretype pkcs12 \
-srckeystore /tmp/cas.harryvasanth.com.p12 \
-srcstoretype PKCS12 \
-srcstorepass changeit \
-destkeystore /tmp/cas.harryvasanth.com.keystore \
-alias cas.harryvasanth.com
The keystore at location /tmp/cas.harryvasanth.com.keystore can now be used by the CAS server (or any Java application server).
Automate Keystore creation
Make the shell script to create keystore
Create a shell script /home/<user.name>/renew-cert-keystore.sh Here is an example:
1
2
touch /home/harry.vasanth/renew-cert-keystore.sh && \
chmod +x /home/harry.vasanth/renew-cert-keystore.sh
Add the following content to the script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env bash
IFS='
'
cd -P "$(dirname "$0")"
# Create keystore
echo "Refreshing '$(pwd)/cas.harryvasanth.com.keystore'"
openssl pkcs12 -export \
-in /etc/letsencrypt/live/cas.harryvasanth.com/cert.pem \
-inkey /etc/letsencrypt/live/cas.harryvasanth.com/privkey.pem \
-out /tmp/cas.harryvasanth.com.p12 \
-name cas.harryvasanth.com \
-CAfile /etc/letsencrypt/live/cas.harryvasanth.com/fullchain.pem \
-caname "Let's Encrypt Authority X3" \
-password pass:changeit
# User Keytool to import P12 to Keystore format
keytool -importkeystore \
-deststorepass changeit \
-destkeypass changeit \
-deststoretype pkcs12 \
-srckeystore /tmp/cas.harryvasanth.com.p12 \
-srcstoretype PKCS12 \
-srcstorepass changeit \
-destkeystore /tmp/cas.harryvasanth.com.keystore \
-alias cas.harryvasanth.com
# Move certificates to the current directory
echo "Copy '/tmp/cas.harryvasanth.com.keystore' to '$(pwd)/cas.harryvasanth.com.keystore'"
cp /tmp/cas.harryvasanth.com.keystore $(pwd)/cas.harryvasanth.com.keystore
Schedule the script to run periodically
The following line in crontab makes sure our script is executed every hour.
1
0 * * * * yes | bash /home/<user.name>/renew-cert-keystore.sh >> /var/log/renew-cert-keystore.log