skip to Main Content

It drives me nuts now.

I have created sym links to the PEM files. I made the PEM files readable for the tomcat user. I set the server.xml to use SSL. And the connector fails to start.

<Connector port="8443"
               protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="200"
               scheme="https"
               secure="true"
               SSLEnabled="true"
               clientAuth="false"
               sslProtocol="TLS"
               sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
               defaultSSLHostConfigName="mydomain.com"
    >
        <SSLHostConfig hostName="mydomain.com" protocols="+TLSv1,+TLSv1.1,+TLSv1.2">
            <Certificate
                certificateKeyFile="conf/privkey.pem"
                certificateFile="conf/cert.pem"
                certificateChainFile="conf/chain.pem"
                type="UNDEFINED"
            />
        </SSLHostConfig>
    </Connector>

I did try to change the type to RSA, to no avail. All I see in the log is:

02-Jan-2021 17:40:54.398 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-nio-8443"]
02-Jan-2021 17:40:54.466 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector[HTTP/1.1-8443]]
        org.apache.catalina.LifecycleException: Protocol handler initialization failed
                at org.apache.catalina.connector.Connector.initInternal(Connector.java:1013)
                ... some lines removed
                at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
        Caused by: java.lang.IllegalArgumentException
                at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:99)
                ... some lines are removed
                at org.apache.catalina.connector.Connector.initInternal(Connector.java:1010)
                ... 13 more
        Caused by: java.io.IOException
                at org.apache.tomcat.util.net.SSLUtilBase.getKeyManagers(SSLUtilBase.java:302)
                at org.apache.tomcat.util.net.openssl.OpenSSLUtil.getKeyManagers(OpenSSLUtil.java:98)
                at org.apache.tomcat.util.net.SSLUtilBase.createSSLContext(SSLUtilBase.java:247)
                at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:97)
                ... 20 more

I’ve checked the SSLUtilBase.java code (tomcat 9.0.33):

            if (certificate.getCertificateFile() == null) {
                throw new IOException(sm.getString("jsse.noCertFile"));
            }

I did try to copy the files instead of using sym links. No avail. Removed the comments from the cert files. No avail. It seems tomcat cannot find the files I’ve specified in the server.xml.

What do I miss?

2

Answers


  1. I had the same issue with Ubuntu 20.04 and Tomcat 9.0.52.

    Tomcat - server.xml - certificateKeyFile
    
    <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
                        <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    

    I also tried everything that you described above and I also was not able to make the Tomcat Connector with certificateKeyFile to work.

    Note, on RedHat Linux 7/8 it works fine though!!! I only got this issue in Ubuntu 20.04.

    The good news is it works fine in Ubuntu 20.04 if you use a keystore instead of the certificateKeyFile.

    You will need to create the keystore as the user that runs tomcat, in my case the user named "tomcat", then created the CSR using the keystore, issue the certificate, and imported the certificate into the keystore.

    –Create the keystore folder and grant the proper permissions:

    su - root
    mkdir /rhdata/sslcert
    chown -R tomcat:tomcat /rhdata/sslcert
    su - tomcat
    cd /rhdata/sslcert
    

    –Create the PKCS12 keystore (must do the previous step):

    su - tomcat
    /usr/lib/jvm/java-11-openjdk-amd64/bin/keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keystore /rhdata/sslcert/.keystore
    $ /usr/lib/jvm/java-11-openjdk-amd64/bin/keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -validity 3600 -keysize 2048 -keystore /rhdata/sslcert/.keystore
    Enter keystore password:  key$tom@2021
    $ /usr/lib/jvm/java-11-openjdk-amd64/bin/keytool --list --keystore /rhdata/sslcert/.keystore -storepass 'key$tom@2021'
    

    –Create the CSR:

    su - tomcat
    $ /usr/lib/jvm/java-11-openjdk-amd64/bin/keytool -certreq -keyalg RSA -alias tomcat -file /rhdata/sslcert/keytool_cert/certreq.csr -keystore /rhdata/sslcert/.keystore -storepass 'key$tom@2021'
    

    –Create the new certificate from the certificate authority using the CSR

    –Import the new certificate into the keystore:

    su - tomcat
    $ /usr/lib/jvm/java-11-openjdk-amd64/bin/keytool -import -alias tomcat -keystore /rhdata/sslcert/.keystore -storepass 'key$tom@2021' -file /rhdata/sslcert/keytool_cert/certnew.p7b
    $ /usr/lib/jvm/java-11-openjdk-amd64/bin/keytool -import -alias tomcat -keystore /rhdata/sslcert/.keystore -storepass 'key$tom@2021' -file /rhdata/sslcert/keytool_cert/certnew.cer
    

    –This is the new Tomcat connector:

    Tomcat - server.xml - keystore
    
    <Connector
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           port="8443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="/rhdata/sslcert/.keystore" keystorePass="key$tom@2021"
           clientAuth="false" sslProtocol="TLS"/>
    

    –Verify the new Tomcat server.xml file

    su - tomcat
    cd /usr/local/tomcat9/conf
    /usr/local/tomcat9/bin/configtest.sh
    

    –Then, stop/start Tomcat.

    su - root
    systemctl stop tomcat.service
    systemctl start tomcat.service
    systemctl status tomcat.service
    vi /usr/local/tomcat9/logs/catalina.out   <-- shall not have any errors!!!
    
    Login or Signup to reply.
  2. Whenever you use one of the deprecated properties on a connector, Tomcat creates an <SSLHostConfig> element with hostName="_default_" and a <Connector> element inside it. The error is caused by the lack of the certificateFile on this particular element.

    Remove the deprecated attributes (clientAuth, sslProtocol) from the <Connector> element and everything should work.

        <Connector port="8443"
                   protocol="org.apache.coyote.http11.Http11NioProtocol"
                   SSLEnabled="true"
                   sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
                   defaultSSLHostConfigName="mydomain.com">
            <SSLHostConfig hostName="mydomain.com" protocols="TLSv1+TLSv1.1+TLSv1.2">
                <Certificate
                    certificateKeyFile="conf/privkey.pem"
                    certificateFile="conf/cert.pem"
                    certificateChainFile="conf/chain.pem"
                    type="UNDEFINED"
                />
            </SSLHostConfig>
        </Connector>
    

    Remark: the sslProtocol attribute is a characteristic of JSSE and should always be left at the default value (TLS).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search