为博客配置SSL证书以支持HTTPS访问吧!


博客顺利搭建之后,一个很重要的事情就是配置一个SSL证书,以支持HTTPS访问。这篇博文将首先讲解如何通过腾讯云申请免费SSL证书、并在Nginx服务器上完成SSL证书的安装。

申请免费SSL证书

进入腾讯云控制台,选择SSL证书,然后选择我的证书。可以找到免费证书,并点击申请免费证书

SSL证书90天倡议

需要注意的是,免费SSL证书的有效期只有3个月,且不能直接对证书进行续期。如果证书到期,需要重新申请新的证书。这是有一些背景故事的:“SSL证书90天倡议”主要是指由全球网络安全与浏览器厂商共同推动的一项行业标准变更,核心目标是将所有公开信任的SSL/TLS证书的有效期从传统的1年或更长,逐步缩短至90天,并最终在2029年前降至约47天。

缩短证书有效期主要基于以下安全考量:

  • 减小密钥泄露的影响范围:如果私钥被盗或证书被错误签发,较短的有效期能限制攻击者滥用该证书的时间,从而降低潜在的损失。
  • 推动自动化与敏捷性:促使网站管理员放弃低效的手动证书管理,转向使用自动化工具(如ACME协议)来定期更新证书,从而减少因遗忘续期导致的网站中断事故。

所以,在后期我们也将考虑使用自动化工具来处理证书续期问题。不过,路要一步一步走,我们先来体验一下如何用最传统的方式实现免费SSL证书的配置。

申请免费证书

我们可以在这里申请免费的SSL证书:

手动DNS验证域名

SSL证书提供商需要确保这个域名是你的,是可用的,所以需要进行一些验证。如果选择了手动DNS验证,那么就需要我们登录到DNS控制台中并增加一条TXT类型的记录,并回来进行验证。验证通过后才能签发证书。

我们进入域名控制台,并按照指引添加对应记录:

然后点击验证,查看验证通过:

这样,证书就可以完成签发了。稍后就会收到SSL证书认证通过的通知。

部署SSL证书

下载SSL证书

证书完成了签发,但是目前还没生效,因为没有部署到网络当中去呢。我们需要先下载下来证书:

证书文件的结构如下:

1
2
3
4
5
6
7
8
caiguu@JACKERZHANG-MB0 Downloads % tree caiguu.cn_nginx 
caiguu.cn_nginx
├── caiguu.cn_bundle.crt
├── caiguu.cn_bundle.pem
├── caiguu.cn.csr
└── caiguu.cn.key

1 directory, 4 files

这四个文件的作用分别如下:

文件名 后缀 作用 在Nginx配置中的使用
caiguu.cn_bundle.crt .crt 完整的证书链。包含了你的域名证书和中间证书,是浏览器用来验证你网站身份并建立加密连接的关键文件。 ssl_certificate 指令使用此文件。
caiguu.cn.key .key 私钥文件。与你的公钥证书配对,用于解密客户端发送的数据,必须严格保密,绝对不能泄露。 ssl_certificate_key 指令使用此文件。
caiguu.cn_bundle.pem .pem caiguu.cn_bundle.crt内容相同,只是格式是.pem(一种更通用的文本格式)。为其他软件兼容性而提供。 Nginx不需要,可忽略。
caiguu.cn.csr .csr 证书签名请求文件。申请证书时向CA机构提交的临时文件,证书签发后不再需要 完全不需要,可以安全删除。

所以,接下来我们就可以登录服务器进行对应配置了。

上传证书文件到服务器

我把证书文件存储在了/etc/cert/下。于是我现在要做的就是把caiguu.cn_bundle.crtcaiguu.cn.key这两个文件上传到这个位置。

1
2
3
4
5
6
[root@VM-0-10-opencloudos etc]# tree ./cert
./cert
├── caiguu.cn_bundle.crt
└── caiguu.cn.key

0 directories, 2 files

然后我们修改hexo.conf文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
server {
listen 80; # 监听80端口(HTTP)
listen [::]:80;
server_name caiguu.cn; # 将此处改为你的域名或服务器IP
charset utf-8;

return 301 https://$server_name$request_uri;

}

server {
# 监听 443 端口,并启用 SSL(同时支持IPv4和IPv6)
listen 443 ssl;
listen [::]:443 ssl; # 建议加上 ssl 参数,与上一行保持一致
server_name caiguu.cn;
charset utf-8;

# SSL 证书文件路径
ssl_certificate /etc/cert/caiguu.cn_bundle.crt; # 已添加分号
# SSL 证书私钥文件路径
ssl_certificate_key /etc/cert/caiguu.cn.key;

ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;

# 静态文件目录
root /var/www/hexo;
index index.html;

# 访问和错误日志(目录需要存在且Nginx有写入权限)
access_log /var/log/nginx/hexo.access.log;
error_log /var/log/nginx/hexo.error.log;

location / {
try_files $uri $uri/ =404;
}
}

主要做了两件事:第一是把80访问重定向到443上,强制使用HTTPS。第二是配置了读取SSL证书的路径,并配置了SSL的相关属性。

接下来需要重新加载一下Nginx服务,以使得它生效。

1
sudo nginx -s reload

我们在浏览器中打开,就能看到这个证书的信息了:

至此,我们的博客就支持HTTPS访问了!

凭什么信任我?

我申请了一个SSL证书,并把这个文件放到服务器上,然后又做了点配置,为什么就能得到信任了呢?凭什么呢?

一条完整的信任链

想象一下这个场景:你去派出所办了一张身份证。然后去银行办业务,柜员看了一眼你的身份证,就信你了。为什么?因为他信的不是你这个人,而是你背后的那个体系:身份证上有防伪标识,银行柜员无需见到签发这个证件的过程,凭借对这个体系的信任,他就会信任你。

类比到我们的证书中,也是这个道理,这里存在一条完整的信任链:

  • 我的证书:就像我的身份证,上面有我的名字(caiguu.cn)和我的公钥(相当于我的银行账号)
  • 中间证书:证明我这个身份证是TrustAsia这个”派出所”签发的
  • 根证书:这个最厉害,它被预装在你电脑的操作系统里,就像全世界所有银行都默认信任的”终极权威”

根证书

我们可以在自己的电脑上看到跟证书有哪些:

我们可以在其中看到DigCert Global Root G2:

DigiCert Global Root G2

TrustAsia中间证书

我们可以在自己的caiguu.cn_bundle.crt中看到这些信任链:

这里就能看到我们的证书由TrustAsia签发,同时能够看到公钥和签名。

证书层次结构

我们可以在证书层次结构里看到我们的证书层次结构如下:

1
2
3
4
5
DigiCert Global Root G2 (根证书)
↓ 签名
TrustAsia DV TLS RSA Root CA 2025(中间证书)
↓ 签名
caiguu.cn (你的服务器证书)

签名与验证真伪

接着我们看一下签名。签名不是为了加密什么,而是为了证明这份内容确实是某个持有私钥的人发出的,并且没有被篡改

假设我们是浏览器,有人想访问caiguu.cn,看看会发生什么:

  1. 浏览器通过Nginx获取到.crt文件,得到证书链
  2. 从证书链找到TrustAsia 的中间证书
  3. 从我的证书取出TrustAsia计算出来的签名
  4. 用TrustAsia的公钥解密这个签名,得到一个哈希值,叫H1
  5. 自己用指定的哈希算法(例如SHA-256)计算证书的哈希值,叫H2
  6. 对比H1H2是否相等。如果相等,说明证书真实。否则证书被篡改过!也就是说,H1是解密出来的证书哈希值。是证书最初的样子。 H2是利用当前证书文件计算出来的哈希值。 如果未被篡改,那么H1==H2。如果被改了,那么H1!=H2。至于为什么私钥加密、公钥可以解密,这就是密码学领域的知识了。

接着,类似地,会继续计算TrustAsia的证书是否可信;直到检查根证书是否在操作系统中内置。如果都通过了,那么说明整个信任链上都是安全可信的。

通信内容安全怎么保证?

最后,我还有一个私钥没有出现呢?它干什么用?

答案是保证通信内容的安全。

我的私钥在HTTPS中主要做两件事:

  1. 证明身份:握手阶段,服务器用私钥(也就是我的私钥),生成握手信息的签名。然后浏览器会用我的公钥来解密,查看握手信息是否正确。
  2. 帮助协商密钥(可选方式):浏览器生成一个随机数,用我的公钥加密后发过来,我用私钥解密。这样,我们就能在不安全的网络中安全地商量出一个只有我俩知道的“暗号”,用这个暗号加密后续的所有通信。

至此,我们就对SSL有了直观、生动的认识,相信现在对于HTTPS的理解已经更上层楼了!


文章作者: Jack Zhang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Jack Zhang !
  目录