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.
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)
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?
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
@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
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:
Import the certificate private key into a .jks keystore with aliases both for glassfish-instance as well as s1as.
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.
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:
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?
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.
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.
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 !!