【问题标题】:why tomcat looks .root/keystore for let's encrypt为什么 tomcat 看起来 .root/keystore 让我们加密
【发布时间】:2017-10-05 09:00:49
【问题描述】:

我在 Ubuntu 16.04 中安装了 Tomcat 8.0.45。我使用 let's encrypt 生成的证书启用了 HTTPS 连接器。它就像一个魅力。但是今天 Tomcat 无法启动 HTTPS 连接器!

我通过以下链接生成证书:https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-16-04

我在 catalina.out 中得到的错误是:

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

但我不需要在 /root/.keystore 中添加任何内容,因为我使用 Let's Encrypt!为什么tomcat要找这个目录?

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>

【问题讨论】:

    标签: java tomcat https


    【解决方案1】:

    据我所知,您需要将证书放入 jks 密钥库,因为 Tomcat 只接受来自密钥库的证书,因此 Tomcat 会忽略您的配置参数并在默认路径中搜索密钥库。

    Tomcat 目前仅在 JKS、PKCS11 或 PKCS12 格式的密钥库(see tomcat documentation) 上运行

    see documentation for importing certificates into keystore

    另外来自tomcat网站:

    当 Tomcat 启动时,我收到类似“java.io.FileNotFoundException: {some-directory}/{some-file} not found”的异常。 一个可能的解释是 Tomcat 无法找到它正在查找的密钥库文件。默认情况下,Tomcat 期望密钥库文件在运行 Tomcat 的用户主目录中命名为 .keystore(可能与您的相同,也可能不同:-)。如果 keystore 文件在其他任何地方,则需要在 Tomcat 配置文件中的元素中添加 keystoreFile 属性

    【讨论】:

    • 感谢您的回答。当我使用现有的 PEM 文件创建 JKS 文件时,它起作用了。我在letsencrypt社区中找到了它。链接为:community.letsencrypt.org/t/…
    • Tomcat WITH APR(又名 Tomcat-Native)使用 PEM 文件。由于连接器没有指定使用哪个实现,Tomcat 会自动选择;可能 APR 曾经工作过,但因为你的踪迹显示 Nio 而有什么东西破坏了它;您的日志中可能应该有一些东西。见tomcat.apache.org/tomcat-8.0-doc/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 2020-05-25
    相关资源
    最近更新 更多