Tomcat 7 SSL 失败
Posted
技术标签:
【中文标题】Tomcat 7 SSL 失败【英文标题】:Tomcat 7 SSL Failed 【发布时间】:2011-09-12 11:23:29 【问题描述】:我使用 Tomcat 7 并将启用 SSL 连接器。 实际上我已经编辑了这个 server.xml 文件的解决方案:
<Connector
clientAuth="true" port="8443" minSpareThreads="5" maxSpareThreads="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="$catalina.home/conf/server.jks"
keystoreType="JKS" keystorePass="password"
truststoreFile="$catalina.home/conf/server.jks"
truststoreType="JKS" truststorePass="password"
SSLVerifyClient="require" SSLEngine="on" SSLVerifyDepth="2" sslProtocol="TLS"
/>
但是我通过启动服务器得到了这个异常。
连接器属性 SSLCertificateFile 使用 SSL 时必须定义 四月。 无法初始化连接器 [连接器[HTTP/1.1-8443]]
我使用自己创建的密钥库。 有没有人有好的简单教程或好主意?
谢谢
附:我发布了我的实际 server.xml
<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8005" shutdown="SHUTDOWN">
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<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>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Define a SSL HTTP/1.1 Connector on port 8443
This connector uses the JSSE configuration, when using APR, the
connector should be using the OpenSSL style configuration
described in the APR documentation -->
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
<Connector
clientAuth="true" port="8443" minSpareThreads="5" maxSpareThreads="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="$catalina.home/conf/server.jks"
keystoreType="JKS" keystorePass="password"
truststoreFile="$catalina.home/conf/server.jks"
truststoreType="JKS" truststorePass="password"
SSLVerifyClient="require" SSLEngine="on" SSLVerifyDepth="2" sslProtocol="TLS"
/>
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" resolveHosts="false"/>
</Host>
</Engine>
</Service>
</Server>
【问题讨论】:
【参考方案1】:如果您使用 APR 连接器,则不能使用密钥库。它需要与 Apache 使用的证书格式相同。
编辑:如果您在 Linux 上运行 Debian 或 Ubuntu,您可以使用 ssl-cert
软件包生成一个自签名证书,该证书将与 http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Edit_the_Tomcat_Configuration_File 中记录的 APR 连接器一起使用(向下滚动到 APR 部分)。
编辑:试试这个作为你的server.xml
文件。我删除了一些 cmets 并注释掉了 APR 监听器。您的密钥库现在应该可以工作了。
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<!-- <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> -->
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<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>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
-->
<!-- Define a SSL HTTP/1.1 Connector on port 8443
This connector uses the JSSE configuration, when using APR, the
connector should be using the OpenSSL style configuration
described in the APR documentation -->
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
<Connector
clientAuth="true" port="8443" minSpareThreads="5" maxSpareThreads="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="$catalina.home/conf/server.jks"
keystoreType="JKS" keystorePass="password"
truststoreFile="$catalina.home/conf/server.jks"
truststoreType="JKS" truststorePass="password"
SSLVerifyClient="require" SSLEngine="on" SSLVerifyDepth="2" sslProtocol="TLS"
/>
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" resolveHosts="false"/>
</Host>
</Engine>
</Service>
</Server>
【讨论】:
我可以在没有密钥库的情况下创建 SSL 连接,还是可以使用我的密钥库实现 SSL 连接?我想在我的 Tomcat 上运行一个带有 SSL 传输层的 WebService。 您需要一个证书来创建 SSL 连接:如果您不使用 APR 连接器,您可以使用密钥库,或者如果您使用 APR 连接器,则必须使用 OpenSSL 格式的证书文件。更改您的server.xml
文件并删除您配置的 APR 侦听器,您将能够使用现有的密钥库。
你可以为server.xml做一个例子吗?我不知道我是如何实现的。
发布您的server.xml
文件,我将编辑我的答案以修改它。
我的第一个问题是编辑,现在包含 server.xml 文件。谢谢【参考方案2】:
Tomcat 中的 8443 端口默认用于 SSL 连接。
我建议你查看 SSL 的 tomcat 文档:http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
我发现还有一个链接可以立即解决您的问题:http://java.dzone.com/articles/setting-ssl-tomcat-5-minutes 这是一篇了不起的文章。请通过以解决问题。 希望这会有所帮助!
【讨论】:
【参考方案3】:注释掉这一行:
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
【讨论】:
因为我需要做的就是在 Windows 机器上进行测试,这是一个很好的临时解决方法。 这也适用于我。但是你能解释一下 AprLifecycleListener 的用途吗? 它用于 Apache 本机运行时,您必须从源代码编译的二进制文件。【参考方案4】:在 TOMCAT 上实现 SSL 有两种方式
(SSL的APR实现和SSL的JSSE实现)
不同之处在于 JDK 使用自己的 SSL 实现,而 APR 使用计算机上安装的内容,即大多数情况下使用 OpenSSL。
第一种方式 (jSSE) 使用 java
创建密钥库文件
(windows-os) in 命令提示 cmd [cd $JAVA_HOME/bin]
keytool -genkey -alias tomcat -keyalg RSA
(配置 Tomcat 的 SSL 连接器)在 (..\Tomcat 8.0\conf\server.xml)
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
scheme="https" URIEncoding="UTF-8"sslProtocol="TLS"keystorePass="yourPassword"
keystoreFile="locationofkeystorefile" keyAlias="youralias" clientAuth="false" />
使用 openssl 的第二种方式 (ARP)
使用 Java 创建 Keystore 文件
(配置 Tomcat 的 SSL 连接器)在 (..\Tomcat 8.0\conf\server.xml)
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
port="8443" clientAuth="false" sslProtocol="TLS"
SSLEnabled="true" maxThreads="150" scheme="https" secure="true"
SSLCertificateFile="/tmp/monitoringPortalCert.pem"
SSLCertificateKeyFile="/tmp/monitoringPortalKey.pem"
SSLPassword="hide"/>
有用的网址:
http://java.dzone.com/articles/setting-ssl-tomcat-5-minutes
http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
【讨论】:
【参考方案5】:禁用自动切换
这里有一个简单的自动机制在起作用。我建议您禁用它并明确选择所需的连接器。详情如下。
详情
您的连接器配置如下:
<Connector port="8443" protocol="HTTP/1.1"
这里的重要参数是“协议”部分。 Tomcat 7 documentation says this:(我的换行符)
protocol
设置协议以处理传入流量。
默认值为
HTTP/1.1
,它使用自动切换机制来选择基于阻塞Java 的连接器或基于APR/native 的连接器。如果
PATH
(Windows)或LD_LIBRARY_PATH
(在大多数unix系统上)环境变量包含Tomcat本机库,则将使用APR/本机连接器。如果找不到本机库,将使用基于 Java 的阻塞连接器。请注意,APR/本机连接器的 HTTPS 设置与 Java 连接器不同。
[...]
所以似乎正在使用自动切换并且它不起作用。原因在上面的最后一段中给出:我们正在自动切换并最终得到“APR”连接器。
那么这会发生:
-
APR 连接器具有称为
SSLCertificateFile
的强制参数。
我们没有在 server.xml 中提供该参数。
Tomcat 抱怨缺少参数。
选项
因此,为了解决此问题,您有多种选择:
关闭自动切换功能,将“HTTP/1.1”文本替换为所需的连接器。 保持自动开启并修复它。通过将所需参数添加到 server.xml。 保持自动开启并故意将其中断。只需删除“tomcat\bin\tcnative-1.dll”即可。这将在如果找不到本机库之后触发上面提到的部分。这是一个有点肮脏的解决方案。我在这里提到这一点并不是因为我认为这是一个好主意。但是因为我碰巧发现这是在我们的一台开发 Tomcat 机器上完成的。【讨论】:
以上是关于Tomcat 7 SSL 失败的主要内容,如果未能解决你的问题,请参考以下文章
curl:(35)错误:14077410:SSL例程:SSL23_GET_SERVER_HELLO:sslv3警报握手失败
javax.net.ssl.SSLHandshakeException:在 Android 7.0 中握手失败