在 Tomcat 8.5+ 中给虚拟主机(<Host>)配置 SSL,核心是在 443/8443 端口的 HTTPS Connector 里用 <SSLHostConfig> 为每个域名绑定独立证书,实现多域名 HTTPS 共存(SNI)。下面是完整可直接复制的配置方案。
一、准备工作(证书格式)
Tomcat 8.5+ 推荐两种证书格式,优先用 PEM(直接用
.crt/.key),也可用 PKCS12/PFX 或 JKS。1. PEM 格式(最推荐,直接用证书文件)
- 证书文件:
domain.crt(含公钥 + 中间证书链) - 私钥文件:
domain.key(无密码) - 存放路径:
$CATALINA_HOME/conf/ssl/(建议新建目录)
2. PKCS12/PFX 格式(CA 常提供)
- 证书文件:
domain.pfx - 密码:证书导出时设置的密码
3. JKS 格式(Java 传统,需用 keytool 转换)
bash
运行
# PEM 转 JKS(示例)
keytool -importkeystore -srckeystore domain.pfx -srcstoretype PKCS12 -destkeystore domain.jks -deststoretype JKS
二、核心配置(server.xml)
1. 启用 HTTPS 连接器(8443/443)
在
<Service> 内添加或修改 <Connector>,开启 SSLEnabled="true",并配置多个 <SSLHostConfig> 对应不同虚拟主机。xml
<!-- 1. HTTP 80 端口,自动重定向到 HTTPS -->
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443" />
<!-- 2. HTTPS 443 端口(生产用),支持多虚拟主机 SSL -->
<Connector port="443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS">
<!-- ============================================== -->
<!-- 虚拟主机 1:www.site1.com -->
<SSLHostConfig hostName="www.site1.com">
<Certificate
type="RSA"
certificateFile="conf/ssl/site1.crt"
certificateKeyFile="conf/ssl/site1.key"
certificateChainFile="conf/ssl/site1_chain.crt" /> <!-- 中间证书链(可选) -->
</SSLHostConfig>
<!-- ============================================== -->
<!-- 虚拟主机 2:www.site2.com -->
<SSLHostConfig hostName="www.site2.com">
<Certificate
type="RSA"
certificateFile="conf/ssl/site2.crt"
certificateKeyFile="conf/ssl/site2.key" />
</SSLHostConfig>
<!-- ============================================== -->
<!-- 默认 SSL 配置(匹配不到 hostName 时用) -->
<SSLHostConfig hostName="_default_">
<Certificate
type="RSA"
certificateFile="conf/ssl/default.crt"
certificateKeyFile="conf/ssl/default.key" />
</SSLHostConfig>
</Connector>
2. 配置虚拟主机(<Host>)
在
<Engine> 内定义虚拟主机,与 <SSLHostConfig> 的 hostName 一一对应Apache Tomcat。xml
<Engine name="Catalina" defaultHost="localhost">
<!-- 默认主机 -->
<Host name="localhost" appBase="webapps" autoDeploy="true">
</Host>
<!-- 虚拟主机 1:www.site1.com -->
<Host name="www.site1.com" appBase="D:/site1" unpackWARs="true" autoDeploy="true">
<!-- 可在此添加 IP 限制、用户认证等(同之前的访问权限配置) -->
</Host>
<!-- 虚拟主机 2:www.site2.com -->
<Host name="www.site2.com" appBase="D:/site2" unpackWARs="true" autoDeploy="true">
</Host>
</Engine>
三、PKCS12/PFX 格式配置示例
如果你的证书是 .pfx 格式,替换 <Certificate> 如下:
xml
<SSLHostConfig hostName="www.site1.com">
<Certificate
type="RSA"
certificateKeystoreFile="conf/ssl/site1.pfx"
certificateKeystorePassword="your_pfx_password"
certificateKeystoreType="PKCS12" />
</SSLHostConfig>
四、JKS 格式配置示例
xml
<SSLHostConfig hostName="www.site1.com">
<Certificate
type="RSA"
certificateKeystoreFile="conf/ssl/site1.jks"
certificateKeystorePassword="your_jks_password"
certificateKeystoreType="JKS" />
</SSLHostConfig>
五、配置生效与验证
- 保存 server.xml,将证书文件放入
conf/ssl/。 - 重启 Tomcat。
- 验证:
- 访问
https://www.site1.com和https://www.site2.com,应显示安全锁。 - 查看日志:
logs/catalina.out,排查证书路径 / 密码错误。 - 用浏览器开发者工具(Security 标签)查看证书是否正确加载。
- 访问
六、常见问题
- 证书不匹配:确保 <SSLHostConfig hostName> 与证书 Common Name (CN) 或 Subject Alternative Name (SAN) 完全一致。
- 端口 443 无法启动:Linux 下需用 root 权限启动(或配置
authbind);Windows 需关闭占用 443 的程序(如 IIS)。 - 旧版 Tomcat(8.0 及以下):不支持 <SSLHostConfig>,需用 APR/OpenSSL 或单个证书配置。
七、完整模板(直接复制)
xml
<Service name="Catalina">
<!-- HTTP 80 -->
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443" />
<!-- HTTPS 443 多虚拟主机 SSL -->
<Connector port="443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
SSLEnabled="true"
scheme="https"
secure="true">
<SSLHostConfig hostName="www.site1.com">
<Certificate
type="RSA"
certificateFile="conf/ssl/site1.crt"
certificateKeyFile="conf/ssl/site1.key" />
</SSLHostConfig>
<SSLHostConfig hostName="www.site2.com">
<Certificate
type="RSA"
certificateFile="conf/ssl/site2.crt"
certificateKeyFile="conf/ssl/site2.key" />
</SSLHostConfig>
</Connector>
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"></Host>
<Host name="www.site1.com" appBase="D:/site1"></Host>
<Host name="www.site2.com" appBase="D:/site2"></Host>
</Engine>
</Service>