本地配置ssl证书
为了更好地在服务器上配置SSL证书,首先要熟悉一下流程。本地不需要类似阿里云的证书。使用Java的keytool帮助生成离线证书。
keytool -genkey -alias ceshi -storetype PKCS12 -keyalg RSA -keystore D:\Java\apache-tomcat-9.0.55-windows-x64\apache-tomcat-9.0.55\conf\https.keystore
该命令会在指向的地址位置生成一个名为https.keystore
的证书
进入该步骤后需要注意的密钥
需要记住,之后还要用的,名字与姓氏
要填域名即localhost
其他的随便填即可。
如下在指定的目录下生成了证书:
配置证书加密访问,对于http协议来说,80是默认端口,若项目在其他端口上则需要带上端口号http://localhost:8080
,对于https来说,443是默认端口号,若项目在其他端口上则也要带上端口号https://localhost:8443
。
接下来配置本地的https协议访问,已经生成了离线的证书,需要配置证书及监听的端口号,在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">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- 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" />
<!-- 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 Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html Define a non-SSL/TLS HTTP/1.1 Connector on port 8080 -->
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
<!--https测试-->
<!-- certificateKeystoreFile 用于指定证书所在的目录 ; certificateKeystorePassword 用于指定证书的密码; type是使用的加密算法-->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" schema="https" secure="true" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/https.keystore" certificateKeystorePassword="Xwh190823" type="RSA" />
</SSLHostConfig>
</Connector>
<!-- A "Connector" using the shared thread pool-->
<!-- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> -->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 This connector uses the NIO implementation. The default SSLImplementation will depend on the presence of the APR/native library and the useOpenSSL attribute of the AprLifecycleListener. Either JSSE or OpenSSL style configuration may be used regardless of the SSLImplementation selected. JSSE style configuration is used below. -->
<!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" type="RSA" /> </SSLHostConfig> </Connector> -->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 This connector uses the APR/native implementation which always uses OpenSSL for TLS. Either JSSE or OpenSSL style configuration may be used. OpenSSL style configuration is used below. -->
<!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" 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" certificateChainFile="conf/localhost-rsa-chain.pem" type="RSA" /> </SSLHostConfig> </Connector> -->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<!-- <Connector protocol="AJP/1.3" address="::1" port="8009" 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" />
</Host>
</Engine>
</Service>
</Server>
该文件是整个配置,我们看https部分:
<!--https测试-->
<!-- certificateKeystoreFile 用于指定证书所在的目录 ; certificateKeystorePassword 用于指定证书的密码; type是使用的加密算法-->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" schema="https" secure="true" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/https.keystore" certificateKeystorePassword="123456" type="RSA" />
</SSLHostConfig>
</Connector>
监听的端口为8443
,这个certificateKeystoreFile
配置项填你生成证书的位置,certificateKeystorePassword
这个填之前的密钥。就可以了!!!没错配置https就这么简单,只需要这就行就可以了,启动tomcat服务器即可。
keytool 错误: java.io.IOException: Invalid keystore format
在配置的过程中还遇到了一个问题keytool 错误: java.io.IOException: Invalid keystore format
,出现这个问题的原因时jdk版本问题,不要使用高本版的jdk,用jdk8就可以了,在构建https.keystore
是用的是jdk11导致tomcat一致报上面的错误,将jdk回退到jdk8之后就没问了。
配置完后进入bin目录开启tomcat服务器,通过http协议访问:http://localhost:8080
再通过https协议访问https://localhost:8443
如上图所示配置成功了,通过两个协议都可以访问。也可以进行其他的配置如修改为默认的端口号,这样就不需要每次添加端口号了,http协议是80,https协议是443。也可以配置跳转,将http协议访问的跳转到https协议上去即在web.xml
配置文件中添加:
<security-constraint>
<web-resource-collection >
<web-resource-name >SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
添加以上内容会自动从HTTP跳转到HTTPS。甚至可以在跳转项目时直接跳转到网站首页。
服务器上SSL证书配置
之前我们已经配置过本地或者离线的SSL证书,那么我们如何在服务器上配置SSL证书呢?原理和步骤与本地几乎相同。唯一的区别是外网需要提供外网的SSL证书。您可以从购买云服务器的网站免费下载证书,也可以通过第三方下载。不限于华为云、阿里云、腾讯云等。
接下来以阿里云为例。云服务器核心为CentOS7。 WEB服务器为Tomcat下载并配置SSL证书,开启HTTPS协议访问。
下载证书后有一个压缩包类型:
解压得到两个文件,一个是证书文件pfx
类型,一个是密码txt
类型:
和之前配置本地的方式一样主要就是配置https的证书,将解压的证书上传到服务的可见文件夹,记录该文件地址,配置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">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- 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" />
<!-- 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 Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html Define a non-SSL/TLS HTTP/1.1 Connector on port 8080 -->
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
<!--https测试-->
<!-- certificateKeystoreFile 用于指定证书所在的目录 ; certificateKeystorePassword 用于指定证书的密码; type是使用的加密算法-->
<!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" schema="https" secure="true" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="cert/6340408_www.qiyuanrenli.com.pfx" certificateKeystorePassword="zXOfVn8u" type="PKCS12" /> </SSLHostConfig> </Connector> -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/cert/6340408_www.qiyuanrenli.com.pfx" certificateKeystoreType="PKCS12" certificateKeystorePassword="zXOfVn8u" />
</SSLHostConfig>
</Connector>
<!-- A "Connector" using the shared thread pool-->
<!-- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> -->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 This connector uses the NIO implementation. The default SSLImplementation will depend on the presence of the APR/native library and the useOpenSSL attribute of the AprLifecycleListener. Either JSSE or OpenSSL style configuration may be used regardless of the SSLImplementation selected. JSSE style configuration is used below. -->
<!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" type="RSA" /> </SSLHostConfig> </Connector> -->
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 This connector uses the APR/native implementation which always uses OpenSSL for TLS. Either JSSE or OpenSSL style configuration may be used. OpenSSL style configuration is used below. -->
<!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" 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" certificateChainFile="conf/localhost-rsa-chain.pem" type="RSA" /> </SSLHostConfig> </Connector> -->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<!-- <Connector protocol="AJP/1.3" address="::1" port="8009" 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" />
</Host>
</Engine>
</Service>
</Server>
相同的核心配置就是这些行:
<!--https SSL证书-->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/cert/6340408.pfx" certificateKeystoreType="PKCS12" certificateKeystorePassword="-----" />
</SSLHostConfig>
</Connector>
certificateKeystoreFile
是上传的证书所在的位置,certificateKeystoreType
是证书的类型,不是所有证书都是fpx
类型,也要适当更改例如还有RSA
类型。certificateKeystorePassword
是证书密钥,打开下载的哪个txt
文档就可以看见密钥。
配置完成后,重启Tomcat服务器。 HTTP和HTTPS均可以成功访问。
如果配置了HTTPS并且仍然可以访问,请分析错误原因:
该网站为提供安全连接
如果浏览器出现这种情况,很大概率是证书配置有问题。检查是否有配置错误。
无法访问此网页
当浏览器出现此提示时,首先检查域名或IP是否正确,然后检查端口号。 http协议默认的tomcat是8080,配置时https协议监听的端口是8443。
3.服务器未响应
当浏览器显示这个提示时,可能是服务上的服务没有启动,端口被占用,或者防火墙没有打开端口。需要在云服务器的安全组中开放该端口。
最后要注意的是端口问题。如果您安装了防火墙工具,则必须打开所使用的端口。对于云服务器,进入安全组开放端口。如果你安装了Pagoda,还必须打开端口。