Tomcat 9 Docker容器使用PKCS12证书时SSL连接异常求助
核心原因
官方tomcat:9镜像不支持通过你设置的KEYSTORE_PATH、KEYSTORE_PASSWORD等环境变量自动配置SSL,这些变量一般是第三方自定义Tomcat镜像的扩展特性。默认情况下,官方镜像的Tomcat未启用SSL Connector,导致8443端口要么未监听,要么未配置SSL证书,从而出现握手失败、无证书返回的错误。
排查步骤
验证容器内Tomcat的SSL配置
进入运行中的容器,查看默认的server.xml:docker exec -it <你的容器ID或名称> cat /usr/local/tomcat/conf/server.xml你会发现SSL相关的
<Connector>块处于注释状态,Tomcat并未启用SSL监听。确认证书文件有效性
在宿主机验证挂载的PKCS12证书是否正常:openssl pkcs12 -info -in /home/parikshit/certs/server.p12输入密码
pskp后,若能正常显示证书和密钥信息,说明证书本身无问题;若报错,需重新生成有效证书。检查证书挂载权限
确保宿主机上的server.p12文件权限允许容器内的Tomcat用户(默认用户为tomcat)读取:chmod 644 /home/parikshit/certs/server.p12 # 可选:设置文件所属用户与容器内一致 chown 1000:1000 /home/parikshit/certs/server.p12
解决方案
方案1:自定义server.xml并挂载
- 从容器中复制默认的
server.xml到宿主机:docker cp <容器ID>:/usr/local/tomcat/conf/server.xml ./server.xml - 编辑
server.xml,取消SSL Connector的注释,并修改配置匹配你的证书信息:<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="/usr/local/tomcat/keystore.p12" type="RSA" certificateKeystorePassword="pskp" certificateKeystoreType="PKCS12" certificateKeyPassword="pskp" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"/> </SSLHostConfig> </Connector> - 修改启动命令,挂载自定义的
server.xml:docker run \ -p 8443:8443 \ -v /home/parikshit/certs/server.p12:/usr/local/tomcat/keystore.p12 \ -v $(pwd)/server.xml:/usr/local/tomcat/conf/server.xml \ tomcat:9
方案2:构建自定义Tomcat镜像(适合长期使用)
基于官方tomcat:9镜像,添加启动脚本自动解析环境变量并修改server.xml,实现类似你最初期望的环境变量配置SSL的功能。示例Dockerfile:
FROM tomcat:9 COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] CMD ["catalina.sh", "run"]
entrypoint.sh脚本可使用sed命令替换server.xml中的SSL配置参数,读取环境变量的值注入到配置中。
验证修复
启动容器后,再次执行openssl s_client -connect localhost:8443,若能正常显示证书信息、完成握手,则问题解决。此时用curl访问也会正常(若证书是自签名的,需添加-k参数忽略证书验证:curl -k https://localhost:8443)。
内容的提问来源于stack exchange,提问作者PSKP

