版本概述

Tomcat 7.x
已弃用
Tomcat 7 是较旧的版本,支持 Java 6/7,SSL 配置相对简单,但缺少一些现代安全特性。已于 2021 年停止维护。
⚠️ 注意: Tomcat 7 已停止维护,存在安全风险,强烈建议升级到 Tomcat 9 或 10。
Tomcat 8.x
稳定版本
Tomcat 8 支持 Java 7/8,引入了更好的 SSL/TLS 支持,包括对 TLS 1.2 的完整支持。配置方式与 Tomcat 7 类似。
Tomcat 9.x
推荐版本
Tomcat 9 支持 Java 8 及以上版本,支持 TLS 1.3,提供了更好的性能和安全性。是目前最广泛使用的版本。
✅ 推荐: Tomcat 9 是目前最稳定和推荐的版本,支持所有现代 SSL/TLS 特性。
Tomcat 10.x
当前版本
Tomcat 10 支持 Java 11 及以上版本,使用 Jakarta EE 9+(从 Java EE 迁移),提供最新的安全特性和性能优化。
⚠️ 重要: Tomcat 10 使用 Jakarta EE,与 Tomcat 9 及以下版本不兼容,迁移时需要修改代码。
Tomcat 版本 Java 版本要求 TLS 1.2 TLS 1.3 HTTP/2 状态
Tomcat 7.x Java 6/7 已弃用
Tomcat 8.x Java 7/8 ⚠️ 需配置 稳定
Tomcat 9.x Java 8+ 推荐
Tomcat 10.x Java 11+ 当前

证书格式转换

Tomcat 需要使用 Java 密钥库(.jks 或 .p12)格式的证书。如果您收到的是 .crt 和 .key 文件,需要先转换为密钥库格式。

使用 OpenSSL 转换为 PKCS12 格式

# # 合并证书链(如果需要)cat your_domain.crt intermediate_ca.crt > fullchain.crt # # 转换为 PKCS12 格式openssl pkcs12 -export -out your_domain.p12 -inkey your_domain.key -in fullchain.crt -name tomcat # # 系统会提示您设置密码,请妥善保管此密码

使用 keytool 转换为 JKS 格式(可选)

# # 从 PKCS12 转换为 JKSkeytool -importkeystore -srckeystore your_domain.p12 -srcstoretype PKCS12 -destkeystore your_domain.jks -deststoretype JKS # # 或者直接从证书和私钥创建 JKS(需要先转换为 PKCS12)
💡 提示: Tomcat 9+ 推荐使用 PKCS12 格式(.p12),因为 JKS 格式已被标记为废弃。Tomcat 10+ 仅支持 PKCS12 格式。

连接器配置

Tomcat 的 SSL 配置在 server.xml 文件中进行,需要配置 HTTPS 连接器。

基本 HTTPS 连接器配置

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" keystoreFile="/path/to/your_domain.p12" keystorePass="your_keystore_password" keystoreType="PKCS12" clientAuth="false" sslProtocol="TLS" />
📝 配置说明:
  • port:port:HTTPS 端口,默认 8443,生产环境建议使用 443
  • keystoreFile:keystoreFile:密钥库文件路径(绝对路径)
  • keystorePass:keystorePass:密钥库密码
  • keystoreType:keystoreType:密钥库类型,PKCS12 或 JKS
  • clientAuth:clientAuth:是否要求客户端证书,通常设为 false

版本配置差异

Tomcat 7.x 配置

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="/path/to/your_domain.jks" keystorePass="password" keystoreType="JKS" clientAuth="false" sslProtocol="TLS" />

Tomcat 8.x 配置

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" keystoreFile="/path/to/your_domain.p12" keystorePass="password" keystoreType="PKCS12" clientAuth="false" sslProtocol="TLS" />

Tomcat 9.x 配置(推荐)

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" keystoreFile="/path/to/your_domain.p12" keystorePass="password" keystoreType="PKCS12" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2,TLSv1.3" ciphers="TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" />

Tomcat 10.x 配置

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" keystoreFile="/path/to/your_domain.p12" keystorePass="password" keystoreType="PKCS12" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2,TLSv1.3" ciphers="TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" />
⚠️ 重要差异:
  • Tomcat 7 主要使用 JKS 格式,Tomcat 8+ 推荐使用 PKCS12
  • Tomcat 9+ 支持 TLS 1.3,需要明确配置 sslEnabledProtocols
  • Tomcat 10 仅支持 PKCS12 格式,不再支持 JKS
  • Tomcat 8.5+ 默认使用 NIO 协议,性能更好

密钥库管理

查看密钥库内容

# # 查看 PKCS12 密钥库keytool -list -v -keystore your_domain.p12 -storetype PKCS12 # # 查看 JKS 密钥库keytool -list -v -keystore your_domain.jks

修改密钥库密码

# # 修改 PKCS12 密钥库密码keytool -storepasswd -keystore your_domain.p12 -storetype PKCS12 # # 修改 JKS 密钥库密码keytool -storepasswd -keystore your_domain.jks

导入中间证书

# # 导入中间证书到 PKCS12keytool -import -trustcacerts -alias intermediate -file intermediate.crt -keystore your_domain.p12 -storetype PKCS12 # # 导入中间证书到 JKSkeytool -import -trustcacerts -alias intermediate -file intermediate.crt -keystore your_domain.jks

TLS 协议配置

启用 TLS 1.2 和 TLS 1.3(Tomcat 9+)

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" sslEnabledProtocols="TLSv1.2,TLSv1.3" sslProtocol="TLS" ... />

禁用不安全的协议

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" sslEnabledProtocols="TLSv1.2,TLSv1.3" sslProtocol="TLS" ... />
⚠️ 安全建议:
  • 禁用 SSLv2、SSLv3、TLSv1.0、TLSv1.1
  • 仅启用 TLS 1.2 和 TLS 1.3
  • 使用强加密套件
  • 定期更新 Tomcat 和 Java 版本

HTTP 到 HTTPS 重定向

使用 web.xml 配置重定向

<security-constraint> <web-resource-collection> <web-resource-name>Entire Application</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>

配置 HTTP 连接器重定向端口

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
💡 说明: 配置 redirectPort 后,当用户访问 HTTP 时,Tomcat 会自动重定向到 HTTPS 端口。

最佳实践

  • 使用 PKCS12 格式的密钥库(Tomcat 9+)
  • 将密钥库文件放在安全的位置,设置适当的文件权限(600)
  • 使用强密码保护密钥库
  • 仅启用 TLS 1.2 和 TLS 1.3
  • 使用强加密套件
  • 在生产环境使用标准 HTTPS 端口 443
  • 配置 HTTP 到 HTTPS 的自动重定向
  • 定期更新 Tomcat 和 Java 版本
  • 监控证书有效期,及时续期
  • 使用 HSTS 头增强安全性
  • 安全配置示例(Tomcat 9+)

    <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" keystoreFile="/etc/tomcat/ssl/your_domain.p12" keystorePass="${catalina.base}/conf/keystore.pass" keystoreType="PKCS12" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1.2,TLSv1.3" ciphers="TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" maxHttpHeaderSize="8192" />
    📝 说明:
    • 使用环境变量或外部文件存储密码,避免在配置文件中明文存储
    • 使用标准端口 443 需要 root 权限或配置端口转发
    • 配置强加密套件以提升安全性

    常见问题

    问题 1:证书格式错误

    错误: 错误信息:java.io.IOException: keystore was tampered with, or password was incorrect

    解决方案:

    1. 检查密钥库文件路径是否正确
    2. 确认密钥库密码是否正确
    3. 验证密钥库格式是否匹配(PKCS12 或 JKS)
    4. 使用 keytool -list 验证密钥库是否有效

    问题 2:端口被占用

    错误: 错误信息:Address already in use

    解决方案:

    1. 检查端口是否被其他进程占用:netstat -tulpn | grep 8443
    2. 修改 server.xml 中的端口号
    3. 停止占用端口的进程

    问题 3:TLS 握手失败

    错误: 错误信息:javax.net.ssl.SSLHandshakeException

    解决方案:

    1. 检查证书链是否完整(包含中间证书)
    2. 验证证书是否过期
    3. 确认启用的 TLS 协议版本是否匹配
    4. 检查加密套件配置

    问题 4:Tomcat 10 兼容性问题

    解决方案: 问题:从 Tomcat 9 升级到 Tomcat 10 后应用无法运行

    解决方案:

    1. Tomcat 10 使用 Jakarta EE,需要更新所有 javax.* 导入为 jakarta.*
    2. 更新所有依赖库到支持 Jakarta EE 的版本
    3. 重新编译和部署应用程序
    4. 如果无法迁移,建议继续使用 Tomcat 9