why tomcat looks .root/keystore for let's encrypt

Viewed 4778

I have Tomcat 8.0.45 installed in Ubuntu 16.04. I enabled HTTPS connector with the certificate which is generated by let's encrypt. It was working like a charm. But today Tomcat cannot start HTTPS connector!

I generated the certificate by following this link: https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04

The error I get in catalina.out is:

05-Oct-2017 08:53:13.473 SEVERE [main] org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore Failed to load keystore type JKS with path /root/.keystore due to /root/.keystore (No such file or directory)
 java.io.FileNotFoundException: /root/.keystore (No such file or directory)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
        at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
        at org.apache.tomcat.util.file.ConfigFileLoader.getInputStream(ConfigFileLoader.java:96)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:442)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:353)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:606)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:546)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:370)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:810)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:476)
        at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:120)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:960)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:568)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:871)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:581)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:604)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494)

05-Oct-2017 08:53:13.475 SEVERE [main] org.apache.coyote.AbstractProtocol.init Failed to initialize end point associated with ProtocolHandler ["http-nio-8443"]
 java.io.FileNotFoundException: /root/.keystore (No such file or directory)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
        at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
        at org.apache.tomcat.util.file.ConfigFileLoader.getInputStream(ConfigFileLoader.java:96)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:442)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:353)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:606)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:546)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:370)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:810)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:476)
        at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:120)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:960)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:568)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:871)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:581)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:604)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494)
05-Oct-2017 08:53:13.476 SEVERE [main] org.apache.catalina.core.StandardService.initInternal Failed to initialize connector [Connector[HTTP/1.1-8443]]
 org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8443]]
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:568)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:871)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:581)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:604)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494)
Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:962)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        ... 12 more
Caused by: java.io.FileNotFoundException: /root/.keystore (No such file or directory)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
        at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
        at org.apache.tomcat.util.file.ConfigFileLoader.getInputStream(ConfigFileLoader.java:96)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getStore(JSSESocketFactory.java:442)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeystore(JSSESocketFactory.java:353)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:606)
        at org.apache.tomcat.util.net.jsse.JSSESocketFactory.getKeyManagers(JSSESocketFactory.java:546)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:370)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:810)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:476)
        at org.apache.coyote.http11.AbstractHttp11JsseProtocol.init(AbstractHttp11JsseProtocol.java:120)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:960)
        ... 13 more

But I don't need to put anything in /root/.keystore because I use Let's Encrypt! Why tomcat is looking this directory?

server.xml

<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">

    <Connector protocol="HTTP/1.1"
               port="8443" 
               maxThreads="200"
               scheme="https" 
               secure="true" 
               SSLEnabled="true"
               SSLCertificateFile="/etc/letsencrypt/live/mysite.com/fullchain.pem"
               SSLCertificateKeyFile="/etc/letsencrypt/live/mysite.com/privkey.pem"
               SSLVerifyClient="optional" 
               SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"/>


    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost">

            <Realm className="org.apache.catalina.realm.LockOutRealm">
                <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>
1 Answers

As far as I know you need to put your certificates into a jks keystore because Tomcat only accepts certificates from within keystores so Tomcat is ignoring your configuration params and is searching for a keystore within the default path.

Tomcat currently operates only on JKS, PKCS11 or PKCS12 format keystores (see tomcat documentation)

see documentation for importing certificates into keystore

in addition from the tomcat website:

When Tomcat starts up, I get an exception like "java.io.FileNotFoundException: {some-directory}/{some-file} not found". A likely explanation is that Tomcat cannot find the keystore file where it is looking. By default, Tomcat expects the keystore file to be named .keystore in the user home directory under which Tomcat is running (which may or may not be the same as yours :-). If the keystore file is anywhere else, you will need to add a keystoreFile attribute to the element in the Tomcat configuration file

Related