Importing LetsEncrypt into Java and Glassfish

I made this shell script to automate the import of the newly renewed/created certificates into the Java Keytool and Glassfish.
Any pointers or ideas for improvements. Specifically if anyone know how to query for the password rather than hardcoding it.
Modify the four variables as needed.

#!/bin/sh

DOMAIN=<DOMAIN.tld>
KEYSTOREPW=<changeIt>
GFDOMAIN=<PathToGlassFishDomain>
LIVE=/etc/letsencrypt/live/$DOMAIN

mkdir etc
cd etc

sudo openssl pkcs12 -export -in $LIVE/cert.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name myalias -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias myalias -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore keystore.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo keytool -list -keystore keystore.jks -storepass $KEYSTOREPW

sudo cp -f keystore.jks $GFDOMAIN/config/

sudo service glassfish stop
sudo service glassfish start

cd ..
sudo rm -rf etc
1 Like

After configure the commands below, GF arises this error in server.log:

[#|2016-04-15T14:25:15.676-0400|WARNING|glassfish3.1.2|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=102;_ThreadName=Thread-2;|GRIZZLY0007: SSL support could not be configured!
java.io.IOException: injection failed on com.sun.enterprise.security.ssl.SSLUtils.secSupp with class com.sun.enterprise.server.pluggable.SecuritySupport
        at com.sun.grizzly.util.net.jsse.JSSE14SocketFactory.init(JSSE14SocketFactory.java:188)
        at com.sun.grizzly.config.SSLConfigHolder.initializeSSL(SSLConfigHolder.java:363)
        at com.sun.grizzly.config.SSLConfigHolder.configureSSL(SSLConfigHolder.java:241)
        at com.sun.grizzly.config.GrizzlyEmbeddedHttps$LazySSLInitializationFilter.execute(GrizzlyEmbeddedHttps.java:202)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
        at java.lang.Thread.run(Thread.java:745)

Seems that this algorithm solves the problem:

https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm

do not forget to merge two jks-files (default keystore.jks with s1as alias and new one created from the link above)

I followed the tutorial above and created the keystore.jks for the new certificate, but the console login failed. I checked the link you shared but didn't know how to apply it correctly.
First in the tutorial link they mentioned NAME, can i set it with any name or should it be a specific name. Also how can i merge the newly created keystore.jks with the existing one in the domain config directory?

Thanks in advance

Hi @Sergey and @musterio,

I did this script to install cert LetsEncrypt into GF/Payara:

DOMAIN=mydomain.com
KEYSTOREPW=mypass
KEYSTOREPWGF=changeit
GF_HOME=/sistemas/payara41
GFDOMAIN=$GF_HOME/glassfish/domains/domain1/

wget -O - https://get.acme.sh | sh
source /root/.bashrc

acme.sh --issue --dns -d $DOMAIN
echo Create IN A and TXT value entries in my DNS server for $DOMAIN
read
acme.sh --renew -d $DOMAIN

cd /root/.acme.sh/$DOMAIN
cp $GFDOMAIN/config/keystore.jks .
cp $GFDOMAIN/config/cacerts.jks .
cp $GFDOMAIN/config/keystore.jks $GFDOMAIN/config/keystore-orig.jks
cp $GFDOMAIN/config/cacerts.jks $GFDOMAIN/config/cacerts-orig.jks

openssl pkcs12 -export -in $DOMAIN.cer -inkey $DOMAIN.key -out cert_and_key.p12 -name myname -CAfile ca.cer -caname root -password pass:$KEYSTOREPW
keytool --noprompt -importkeystore -destkeystore keystore.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias myname -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPWGF -destkeypass $KEYSTOREPWGF
keytool --noprompt -import -noprompt -trustcacerts -alias root -file fullchain.cer -keystore keystore.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPWGF -destkeypass $KEYSTOREPWGF
openssl pkcs12 -export -in fullchain.cer -inkey $DOMAIN.key -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
keytool --noprompt -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPWGF -destkeypass $KEYSTOREPWGF
openssl pkcs12 -export -in fullchain.cer -inkey $DOMAIN.key -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
keytool --noprompt -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPWGF -destkeypass $KEYSTOREPWGF
keytool -list -keystore keystore.jks -storepass $KEYSTOREPWGF
cp -f keystore.jks $GFDOMAIN/config/

keytool --noprompt -importkeystore -destkeystore cacerts.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias myname -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPWGF -destkeypass $KEYSTOREPWGF
keytool --noprompt -import -noprompt -trustcacerts -alias root -file fullchain.cer -keystore cacerts.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPWGF -destkeypass $KEYSTOREPWGF
keytool -list -keystore cacerts.jks -storepass $KEYSTOREPWGF
cp -f cacerts.jks $GFDOMAIN/config/

ls -al $GFDOMAIN/config/*.jks

Now, you must restart GF/Payara41 to get new cert configs.

how i would probably go about this in production

A) Create a hash of the password (in openssl outside of the script)
B) ask user for password read -s -p "Password: " mypassword
C) hash and compare password if hashes match let user go and use the script

Not a big fan of storing passwords in plaintext. Its good to verify the user has the right password.

hello and thanks for the reply, well i am using glassfish without payara, I tried your shell script but it didn't work correctly. I am new to glassfish and ssl, so i am having a hard time figuring things out. When i ran the script of @Grandt it worked correctly with the needed ssl website and the certificate s1as is trusted, but when i try to login to the glassfish console it fails throwing this error in the log

[2016-10-21T17:45:19.665-0400] [glassfish 4.1] [SEVERE] [org.glassfish.admingui] [tid: _ThreadID=43 _ThreadName=admin-listener(5)] [timeMillis: 1477086319665] [levelValue: 1000] [[
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
restRequest: endpoint=https://localhost:4848/management/domain/anonymous-user-enabled
attrs={}
method=GET]]

so is it possible to point at how to solve this specific issue

Hello again, i solved the login issue. The main reason for invalid console login was that the keystore.jks being update while the cacerts.jks remained the same. So i took the old bash, then made the same keytool imports to a new file called cacerts.jks and replaced it with the current ones in glassfish domain config backing up the original files

#!/bin/sh

#replace [##] with the correct value

#Alias of the certificate
NAME=[##]
#The current domain registered in letsencrypt
DOMAIN=[##]
#The keystore password, default is (changeit)
KEYSTOREPW=[##]
#Glassfish server location e.g. /home/glassfish/domains/domain1
GFDOMAIN=[##]
LIVE=/etc/letsencrypt/live/$DOMAIN

mkdir etc
cd etc

sudo openssl pkcs12 -export -in $LIVE/cert.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name $NAME -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias $NAME -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore keystore.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW


sudo openssl pkcs12 -export -in $LIVE/cert.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name $NAME -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias $NAME -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore cacerts.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo keytool -list -keystore keystore.jks -storepass $KEYSTOREPW
sudo keytool -list -keystore cacerts.jks -storepass $KEYSTOREPW

if [ ! -f $GFDOMAIN/config/keystore-orig.jks ]; then
echo "Backing up original files..."
sudo cp -f $GFDOMAIN/config/keystore.jks $GFDOMAIN/config/keystore-orig.jks
sudo cp -f $GFDOMAIN/config/cacerts.jks $GFDOMAIN/config/cacerts-orig.jks
fi

echo "Updating certificates..."
sudo cp -f keystore.jks $GFDOMAIN/config/keystore.jks
sudo cp -f cacerts.jks $GFDOMAIN/config/cacerts.jks

cd ..

sudo rm -rf etc

service glassfish restart

hope this helps

2 Likes

@musterio That actually solve the problem about login on admin/console, but now i can’t login to google auth api, it give the error:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification

Edit: The problem is that you should not just create an cacerts.jks with just the same contents of keystore.jks, it should contains informations about all certificate vendors, to solve it, i downloaded the most recent cacert file from mozilla, and imported it in cacerts.jks together with what you already did…

#!/bin/sh

#replace [##] with the correct value

#Alias of the certificate
NAME=[##]
#The current domain registered in letsencrypt
DOMAIN=[##]
#The keystore password, default is (changeit)
KEYSTOREPW=[##]
#Glassfish server location e.g. /home/glassfish/domains/domain1
GFDOMAIN=[##]
LIVE=/etc/letsencrypt/live/$DOMAIN

mkdir etc
cd etc

sudo openssl pkcs12 -export -in $LIVE/cert.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name $NAME -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias $NAME -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore keystore.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW


sudo openssl pkcs12 -export -in $LIVE/cert.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name $NAME -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias $NAME -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore cacerts.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW


# ====== Download latest list of cacert and import it into the cacerts.jks ========== #

wget https://curl.haxx.se/ca/cacert.pem --no-check-certificate -O cacert.pem

PEM_FILE=cacert.pem
KEYSTORE=cacerts.jks
# number of certs in teh PEM file
CERTS=$(grep 'END CERTIFICATE' $PEM_FILE| wc -l)

# For every cert in the PEM file, extract it and import into the JKS keystore
# awk command: step 1, if line is in the desired cert, print the line
#              step 2, increment counter when last line of cert is found
for N in $(seq 0 $(($CERTS - 1))); do
  ALIAS="${PEM_FILE%.*}-$N"
  cat $PEM_FILE |
    awk "n==$N { print }; /END CERTIFICATE/ { n++ }" |
    keytool -noprompt -import -trustcacerts \
            -alias $ALIAS -keystore $KEYSTORE -storepass $KEYSTOREPW
done

# ==================================================================================== #


sudo keytool -list -keystore keystore.jks -storepass $KEYSTOREPW
sudo keytool -list -keystore cacerts.jks -storepass $KEYSTOREPW

if [ ! -f $GFDOMAIN/config/keystore-orig.jks ]; then
echo "Backing up original files..."
sudo cp -f $GFDOMAIN/config/keystore.jks $GFDOMAIN/config/keystore-orig.jks
sudo cp -f $GFDOMAIN/config/cacerts.jks $GFDOMAIN/config/cacerts-orig.jks
fi

echo "Updating certificates..."
sudo cp -f keystore.jks $GFDOMAIN/config/keystore.jks
sudo cp -f cacerts.jks $GFDOMAIN/config/cacerts.jks

cd ..

sudo rm -rf etc

service glassfish restart
3 Likes

Thanks you guys, you saved a lot of my time :+1:!

Those scripts are actually quite bloated. I tried to do a minimalistic version of a LetsEncrypt/GlassFish import. Basically you only need to do two things:

  1. Import the certificate private key into a .jks keystore with aliases both for glassfish-instance as well as s1as.
  2. Add the certificate to the trusted certificates in the trust store.

In total that should get you a keystore with 2 entries and a truststore with only one entry. No need to import trusted certificates into keystore.jks or private keys intro cacerts.jks.

#!/bin/sh
LIVE=##usually /etc/letsencrypt/live/YOURDOMAIN or wherever you store cert.pem and privkey.pem##
NAME=##SOMENAME##
KEYSTORE=keystore.jks
TRUSTSTORE=cacerts.jks
KEYSTOREPW=changeit

# Import certificate private key into keystore.
rm $KEYSTORE

for alias in glassfish-instance s1as
do
    openssl pkcs12 -export \
        -in $LIVE/cert.pem \
        -inkey $LIVE/privkey.pem \
        -name $alias \
        -password pass:$KEYSTOREPW \
        -out cert.p12

    keytool -importkeystore \
        -srckeystore cert.p12 \
        -srcstoretype PKCS12 \
        -srcstorepass $KEYSTOREPW \
        -destkeystore $KEYSTORE \
        -destkeypass $KEYSTOREPW \
        -deststorepass $KEYSTOREPW \
        -alias $alias
done

rm cert.p12

keytool -list -keystore $KEYSTORE -storepass $KEYSTOREPW

# Import certificate into trust store.
rm $TRUSTSTORE

keytool -import -noprompt -trustcacerts \
    -alias $NAME \
    -file $LIVE/cert.pem \
    -srcstorepass $KEYSTOREPW \
    -destkeypass $KEYSTOREPW \
    -deststorepass $KEYSTOREPW \
    -keystore $TRUSTSTORE

keytool -list -keystore $TRUSTSTORE -storepass $KEYSTOREPW

Finally, copy keystore.jks and cacerts.jks into your domain’s config folder.

If you want the server to trust external authorities then add the boxed part of @DarkSupremo’s answer. But for most applications this should not be needed.

Keep in mind that you might have to reenable secure admin and restart yout server afterwards:

@oppium You use cert.pem instead of fullchain.pem when executing the openssl command. This causes the following issues:

  • Incomplete chain when testing with SSL Labs
  • Google Chrome for Android does not trust the certifcate

See also:

Thank you so much. Your edit sure did fix a lot of errors I was getting with my glassfish 4.1 especially not being able to login after following the @Grandt steps.

Thanks for the updated script, it works like a charm now but there is a problem. Whenever i open the https website on my android device the browser shows me this message “your connection to this site is not private” that marks this website as an unsecured website although when i load the website on pc browsers or ios safari it works fine. How can we fix this issue?

well the first step would be a full description of the issue

for example what version of android etc

troubleshooting issues requires good information and high level problem descriptions aren’t usually enough to go on

If you search android certificate issues on this forum there is a common theme amongst different web servers that is usually the first step to check

Andrei

This is usually a result of leaving out the required intermediate certificate, although it looks like part of this thread was about how to include the intermediate certificate, so maybe it’s less likely that you failed to configure it.

I suggest checking your server with

https://www.ssllabs.com/ssltest/

to see if it finds any misconfiguration either in the certificate chain or in the ciphersuite options.

Hello Again,

Sorry for the late response, i tried changing the script so that it uses fullchain.pem instead of chain.pem and the issue with the rest of the browsers was resolved:

#!/bin/sh

#Alias of the certificate
echo 'Please enter the alias of the certificate: e.g. (shortwebname)'
read NAME
#The current domain registered in letsencrypt such as www.mydomain.com
echo 'Please enter the domain name: e.g. (www.mydomain.com)'
read DOMAIN
#The keystore password, default is (changeit)
echo 'Please enter the keystore password: default is (changeit)'
read KEYSTOREPW
#Letsencrypt live directory location
LIVE=/etc/letsencrypt/live/$DOMAIN
#Glassfish server location e.g. /opt/glassfish4/glassfish/domains/domain1
echo 'Please enter the web server root directory: e.g. (/opt/payara41)'
read GFROOT

if [ -d "$LIVE" ]; then 
	if [ -d "$GFROOT" ]; then   

sudo mkdir temp-ssh
cd temp-ssh

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name $NAME -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias $NAME -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore keystore.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW


sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out cert_and_key.p12 -name $NAME -CAfile $LIVE/chain.pem -caname root -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -alias $NAME -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW
sudo keytool -import -noprompt -trustcacerts -alias root -file $LIVE/chain.pem -keystore cacerts.jks -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name glassfish-instance -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias glassfish-instance -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW

sudo openssl pkcs12 -export -in $LIVE/fullchain.pem -inkey $LIVE/privkey.pem -out pkcs.p12 -name s1as -password pass:$KEYSTOREPW
sudo keytool -importkeystore -destkeystore cacerts.jks -srckeystore pkcs.p12 -srcstoretype PKCS12 -alias s1as -srcstorepass $KEYSTOREPW -deststorepass $KEYSTOREPW -destkeypass $KEYSTOREPW


# ====== Download latest list of cacert and import it into the cacerts.jks ========== #

sudo wget https://curl.haxx.se/ca/cacert.pem --no-check-certificate -O cacert.pem

PEM_FILE=cacert.pem
KEYSTORE=cacerts.jks
# number of certs in teh PEM file
CERTS=$(grep 'END CERTIFICATE' $PEM_FILE| wc -l)

# For every cert in the PEM file, extract it and import into the JKS keystore
# awk command: step 1, if line is in the desired cert, print the line
#              step 2, increment counter when last line of cert is found
for N in $(seq 0 $(($CERTS - 1))); do
  ALIAS="${PEM_FILE%.*}-$N"
  echo $ALIAS
  cat $PEM_FILE |
    awk "n==$N { print }; /END CERTIFICATE/ { n++ }" |
    keytool -noprompt -import -trustcacerts \
            -alias $ALIAS -keystore $KEYSTORE -storepass $KEYSTOREPW
done

# ==================================================================================== #


sudo keytool -list -keystore keystore.jks -storepass $KEYSTOREPW
sudo keytool -list -keystore cacerts.jks -storepass $KEYSTOREPW

if [ ! -f $GFROOT/glassfish/domains/domain1/config/keystore-orig.jks ]; then
echo "Backing up original files..."
sudo cp -f $GFROOT/glassfish/domains/domain1/config/keystore.jks $GFROOT/glassfish/domains/domain1/config/keystore-orig.jks
sudo cp -f $GFROOT/glassfish/domains/domain1/config/cacerts.jks $GFROOT/glassfish/domains/domain1/config/cacerts-orig.jks
fi

echo "Updating certificates..."
sudo cp -f keystore.jks $GFROOT/glassfish/domains/domain1/config/keystore.jks
sudo cp -f cacerts.jks $GFROOT/glassfish/domains/domain1/config/cacerts.jks

cd ..

sudo rm -rf temp-ssh

sudo $GFROOT/bin/asadmin enable-secure-admin;

sudo $GFROOT/bin/asadmin stop-domain;

sudo $GFROOT/bin/asadmin start-domain;
	else
		echo 'Wrong web server location...'
	fi
else
	echo 'Wrong domain name. Please make sure that certbot is installed and this domain is found in: /etc/letsencrypt/live/'
fi

Please check the script out and if there is any change needed please reply.

Thanks alot for your help

Thank you so much for this !!! I know this thread is old, but after hours of playing with glassfish and letsencrypt, googling for hours on end, trying a ton of options, killing the server entirely :)) eventually only your script helped me !!