配置 SSL 证书

自从学着折腾服务器一来,其实一直有想过配置 https。毕竟如果将自己服务器的任何服务以 http 网址的形式分享出去,各类浏览器都会给出大大的安全警告,非常不好看。但是一方面自己对计算机网络的知识有限,一方面又嫌麻烦,所以一直都没很强的动机去学习配置 https 证书的事情。

但是在今年 3.25 的时候,我的数据库被境外黑客入侵并勒索了,好在备份比较完善,所以没有造成太大损失。后来复盘中发现在几个很严重的安全隐患

  • MySQL 的 docker 端口直接暴露在公网上
  • MySQL 的密码设置太简单
  • 在访问 MySQL 及其他各类服务时都是直接使用 http 进行访问的,密码直接以明文传输。

前两个安全隐患其实都好解决,最后一个就需要我学习一下 https 证书的配置了。

一直使用 FreeSSL 提供的 CA 服务,为我所有的 https 网站颁发证书,使用的命令也非常直白

acme.sh/acme.sh --issue -d example.senyao.org  --dns dns_dp --server https://acme.freessl.cn/v2/DV90/directory/example

然后直接在 Nginx 中配置好对应的 cer 和 key 即可。这么做一直都没什么问题,直到最近突然发现我使用的 Navidrome 客户端「音流」无法连接上我的 Navidrome 服务器,无法正常播放音乐和获取音乐的专辑封面等。经过排查,发现音流 1.3.0 版本能正常连接,更新到 1.3.2 后突然就不行了。

为了解决此问题,我在 GitHub 上向音流的开发者提了 issue,开发者也非常热心地帮我做了进一步排查,他指出音流的 1.3.2 版本正在逐步切换到新的 http 客户端,应该是新客户端无法识别证书颁发者导致的。

使用测试工具检查我的域名 music.senyao.org 后有提示

我和音流开发者一致认为,可能是我的 SSL 证书配置存在问题,所以需要重新检查并配置我的 SSL 证书


我决定放弃 FreeSSL,采用更为常见和规范的 Let’s Encropy 作为我的证书 CA,然后继续使用我已经安装的 acme.sh 作为客户端。我的域名挂靠在 Cloudflare 上,而 acme.sh 本身是支持 Cloudflare 的 DNS 验证的。

首先,将 Let’s Encrypt 设置为 acme.sh 的默认 CA,即

acme.sh --set-default-ca  --server  letsencrypt 

然后准备通过 Cloudflare 做 DNS 验证。首先获取 Cloudflare 的相关密钥和 Token。在 Cloudflare 的 Overview 中右侧栏有 API 这一栏,可以获取到 Zone ID 和 Account ID

然后在 Cloudflare-右上角 My Profile- API Tokens,创建一个编辑区域 DNS,并且保存好对应的 Token。

最后回到命令行,配置环境变量并申请证书

export CF_Token="yyyyyyyyyyyyyy"
export CF_Account_ID="xxxxxxxxxxxxx"
export CF_Zone_ID="xxxxxxxxxxxxx"
acme.sh --issue --dns dns_cf -d myapp.example.com

运行完成后,需要安装证书

acme.sh --install-cert -d music.senyao.org \
--key-file /mnt/user/appdata/acme/cer/music.senyao.org/private.key \
--fullchain-file /mnt/user/appdata/acme/cer/music.senyao.org/fullchain.cer 

会得到对应的 fullchain.cer 和 private.key,用 Nginx 配置好这两部分即可

ssl_certificate /mnt/user/appdata/acme/cer/music.senyao.org/fullchain.cer;  # 包含中间证书

ssl_certificate_key /mnt/user/appdata/acme/cer/music.senyao.org/private.key;

经过以上配置后重启 Nginx,再用工具检查域名即可看到

说明证书配置完成。


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注