STRATO Ubuntu vServer上SpringBoot应用配置可信HTTPS方法咨询
硬前提说明:公开可信CA不会为纯IP地址签发证书,必须先将自己持有所有权的域名做A记录解析到这台vServer的公网IP,等解析生效后再走后续流程,否则永远无法获得浏览器默认信任的证书,自签证书的风险提示也无法消除。
1. 安装官方版本Certbot
系统apt源内置的Certbot版本老旧、依赖冲突多,是多数旧教程在新Ubuntu上失效的核心原因,直接用官方维护的snap版本安装即可:
- 先卸载旧版本避免冲突:
sudo apt remove -y certbot && sudo apt autoremove -y - 安装snapd(STRATO官方Ubuntu镜像默认预装,执行无报错即可):
sudo apt update && sudo apt install -y snapd - 安装Certbot并配置全局命令软链:
sudo snap install --classic certbot sudo ln -sf /snap/bin/certbot /usr/bin/certbot
2. 申请Let's Encrypt可信证书
申请前先确认服务器内部防火墙、STRATO后台的外部防火墙都放开了80端口的入站规则,临时停掉占用80端口的服务,执行standalone模式验证申请:sudo certbot certonly --standalone -d 替换为你解析到服务器的域名,例如api.example.com
执行后按提示填写邮箱,同意服务协议,选择不接收官方推广邮件即可。验证通过后,证书文件会自动存放在/etc/letsencrypt/live/你的域名/目录下,核心文件为fullchain.pem(完整证书链)、privkey.pem(私钥)。
3. 转换证书格式适配SpringBoot
SpringBoot原生支持PKCS12格式证书,无需生成老旧的JKS格式文件,直接用系统自带的openssl转换即可:
openssl pkcs12 -export \ -in /etc/letsencrypt/live/你的域名/fullchain.pem \ -inkey /etc/letsencrypt/live/你的域名/privkey.pem \ -out /opt/springboot/keystore.p12 \ -name tomcat \ -CAfile /etc/letsencrypt/live/你的域名/chain.pem \ -caname root \ -password pass:自定义一个密钥库密码,记下来后续配置要用
命令执行后会在/opt/springboot/目录生成p12格式密钥库,给运行SpringBoot应用的用户分配该文件的读权限,建议权限设置为600避免私钥泄露:sudo chmod 600 /opt/springboot/keystore.p12
4. 修改SpringBoot配置启用HTTPS
打开SpringBoot应用的配置文件(application.properties或application.yml),替换原有自签证书的配置项:
如果是properties格式:
# 可直接使用443标准HTTPS端口,若使用非root用户运行服务参考后续步骤配置低端口权限 server.port=443 server.ssl.enabled=true server.ssl.key-store-type=PKCS12 # 填写p12密钥库的绝对路径 server.ssl.key-store=/opt/springboot/keystore.p12 # 填写之前生成p12时设置的密码 server.ssl.key-store-password=你自定义的密钥库密码 server.ssl.key-alias=tomcat
如果是yml格式对应缩进调整即可。配置完成后重新打包jar包上传到服务器。
5. 配置非root用户的低端口监听权限(可选)
如果不用root用户运行jar包,普通用户默认无法监听1024以下的端口,执行以下命令给Java二进制分配端口权限即可,无需配置端口转发:sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which java))
6. 配置证书自动续期
Let's Encrypt证书有效期为90天,snap安装的Certbot默认已经配置了自动续期定时任务,只需要添加续期后的钩子脚本,自动转换新证书格式并重启SpringBoot服务即可:
新建钩子脚本/etc/letsencrypt/renewal-hooks/deploy/springboot-ssl.sh,写入以下内容:
#!/bin/bash # 重新转换新生成的证书为p12格式 openssl pkcs12 -export \ -in /etc/letsencrypt/live/你的域名/fullchain.pem \ -inkey /etc/letsencrypt/live/你的域名/privkey.pem \ -out /opt/springboot/keystore.p12 \ -name tomcat \ -CAfile /etc/letsencrypt/live/你的域名/chain.pem \ -caname root \ -password pass:你之前设置的密钥库密码 # 修正密钥库文件权限 chmod 600 /opt/springboot/keystore.p12 # 重启SpringBoot服务,如果你用systemd托管服务就替换为对应的服务名 systemctl restart your-springboot-service
给脚本添加执行权限:sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/springboot-ssl.sh
执行dry-run命令验证续期流程是否正常,无报错即配置完成:sudo certbot renew --dry-run
注意事项
- 配置完成后必须用HTTPS协议+域名访问后端接口,不要用IP+端口访问,否则依然会触发不安全提示——公开可信CA不签发IP地址证书,这是CA行业规则,没有绕过办法。
- 之前出现的HTTP后端与HTTPS前端连通失败是浏览器混合内容安全策略拦截导致,后端切到可信HTTPS后,前端将接口地址替换为对应的HTTPS域名地址即可正常连通,无需关闭浏览器安全设置。
- 如果不想让SpringBoot直接处理SSL流量,也可以在服务器上部署Nginx做反向代理,证书配置在Nginx层,SpringBoot只监听本地HTTP端口即可,这种方案运维成本更低,也是生产环境的常用部署方式。
- STRATO vServer有两层防火墙:服务器系统内部的ufw/iptables,还有STRATO控制台里的外部安全组,两个地方都要放开80(证书验证、续期用)、443(HTTPS用)端口的入站规则,否则会出现证书申请失败、外部无法访问HTTPS服务的问题。
内容的提问来源于stack exchange,提问作者rickymort

