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
TCP
port80
of 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.com
with 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