HTTPS 免费申请和续期

缘由

让个人网站从 HTTP 升级为 HTTPS 是对于众多 web 开发者来说是一件很体现逼格的事情,尤其是能获取免费的 SSL 证书。不花钱一分钱,又能把逼装得漂亮,岂不美哉。

作为一个幼体后端开发工程师, 哥只是个在公司打酱油的角色,平日的工作就是写一些简单的 API 。有一天,需求来了,意思是给刚开发了三期的 API 加上 SSL 认证。天啊,幸福来得太突然了。但心想这样如此简单的 API 还需要 SSL 证书。哥没有立刻答应,而且也作不了主,所以机智地把锅甩给了技术主管,但结局是可想而知的。

Let’s Encrypt

没错!写这篇博文的时候,SSL 证书已经安装成功了,但过程却是相当曲折。为了配置好证书花费了数小时,还把原本的工作给耽误了,这样才有了这篇工作记录。

要开启 HTTPS 认证,就必须要从证书授权机构中获取一个证书,证书有收费的也有免费的。Let’s Encrypt 就是其中一个提供免费证书的机构。

Certbot

Certbot 是 Let’s Encrypt 官方推荐的一套自动化获取证书的工具。「自动化」说得好听,实情并不是下载好,直接运行就能完成配置。单是安装 Certbot 客户端就遇到麻烦了。网上有一堆博文介绍如何安装 Certbot,比如 yum install certbot,又或者直接从 Github 中克隆 repo git clone https://github.com/certbot/certbot,但如果作为开发者的你,平时有使用 Python 的习惯的话,安装这个工具就更为方便了,因为 pip 一早就已经收录了这个包。只需在终端键入如下命令即可完成安装。

1
sudo pip install certbot

解决了安装问题之后,接下就是获取 SSL 证书。网上很多配置教程都会使用 Certbot 的 webroot 模式来生成证书,但对于像 API 这些微型服务,根本就没有根目录,这时使用 webroot 模式就行不通了。最便捷的方式就是使用 Certbot 的 standalone 模式,无需指定网站目录,同时自动启用服务器的 443 服务端口来验证域名的归属。

1
sudo certbot --standalone --email xxx@xxx.com.cn -d example.com -d www.example.com

出现「Congratulations!」说明服务器所需的证书已经生成好了,它们被放置在 /etc/letsencrypt/live 目录下对应域名的文件夹里。

Nginx 启用 HTTPS

因为原来的服务没有配置证书,所以只负责监听 80 端口,接收请求。现在的需求是既要保留 HTTP,又要新增 HTTPS 认证。因此,新增的配置内容只需添加在该服务对应的 Nginx conf 文件的最后即可。配置的内容如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 443 ssl;
server_name example.com;
### 以下是重点 ###
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letscrypt/live/example.com/privkey.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
access_log /var/log/nginx/log/example_access.log main;
error_log /var/log/nginx/log/example_err.log;
location / {
proxy_pass http://127.0.0.1:9876;
proxy_set_header X-Real-IP $ remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
}
}

简单地说明一下上述配置内容的重点部分。ssl_certficatessl_certficate_key 对应路径下的文件就是此前通过 Certbot 客户端生成好的证书与密钥。至于 ssl_dhparam 属于可选项。默认情况下,Nginx 会使用 openssl 提供的 DHE 参数,其中包含一个较弱的 1024 位的交换密钥。为了增强 Nginx 的密钥,我们可以通过下面的命令生成一个 2048 位的密钥。

1
sudo openssl dhparm -out /etc/nginx/ssl/dhparam.pem 2048

然后检查部署的服务器 443 端口是否开启。最后,重载 Nginx 配置文件和重启 Nginx 服务。

1
2
sudo nginx -s reload
sudo service nginx restart

证书监控和更新

Let’s Encrypt 提供的证书只有 90 天的有效期。借助 Let’s Monitor 可以监控所有域名下的 SSL 证书的有效期。当证书快要过期时,Let’s Monitor 会发出邮件提示,提醒你更新证书,非常方便。

至于证书更新,Certbot 客户端提供了一个更新命令:certbot renew。需要注意一点是刚才生成证书时候使用的是 standalone 模式,验证域名需要启用 443 端口,但是此时 Nginx 服务已经占用了该端口,所以更新证书前必须把 Nginx 服务关掉,才可以成功。这可能会对服务器上正在运行的其他服务有微小的影响。

1
sudo certbot renew --pre-hook 'sudo service nginx stop' --post-hook 'sudo service nginx start' --dry-run

dry-run 代表测试模式,用于检验更新过程是否成功,但不会真的去更新证书。出现了「Congratulations」的字样就说明模拟更新成功。

测试工具

Qualys SSL Labs 提供全面的 SSL 安全性测试,填入你的域名,等待数分钟后就给你的 HTTPS 配置一个安全级别分数。

ssl_labs.png

:最后感谢 Let’s Encrypt 组织提供的免费证书,还有技术主管的支持。

文章目录
  1. 1. 缘由
  2. 2. Let’s Encrypt
    1. 2.1. Certbot
  3. 3. Nginx 启用 HTTPS
  4. 4. 证书监控和更新
  5. 5. 测试工具
|