用 Let's Encrypt 给博客加 SSL 证书

Update: 腾讯云推出了免费 SSL 证书服务。期限一年,签发速度快。

趁周末给自己的博客配置了 SSL 证书,配置过程比较顺利。使用的服务与工具有:

  • CentOS 7.1
  • SSL 证书由 Let's Encrypt 生成
  • 通过 Nginx 配置反向代理与 SSL 证书

1. 为什么要添加 SSL 证书

个人博客为什么要添加 SSL 证书呢?有下面几个好处

  • 提升逼格~
  • 练习 Nginx 反向代理的配置与使用
  • 在国内的网络环境下,SSL 可以有效地防止运营商劫持,避免访问博客时出现莫名其妙的广告(update:现在 https 貌似也有可能被劫持了,看看这里的讨论)

另外,在 Chrome 浏览器中,还可以获得小绿锁认证:

2. 两个免费的 SSL 服务

SSL 证书服务大多是收费的,而且价格不菲。目前好用的免费 SSL 服务端是 Let's Encrypt 和 StartSSL 两家。

Let's Encrypt

  • 优点
    • 目前正在 public beta
    • 证书自动签发
    • 支持多域名
    • 不用注册
  • 缺点
    • 证书有效期只有3个月,需要按时续签

StartSSL

  • 优点
    • 老牌服务商,也许更可靠
    • 证书有效期长达一年
  • 缺点:
    • 需要人工审核并且进度较慢,实测网上提交资料后一天之内没有收到任何回复(后来发现正好碰上了官网升级……)

想了解更多 SSL 证书服务商,可以看看知乎上的讨论:SSL 证书服务商,大家用哪家的?

本着快糙猛的互联网精神,我选择了 Let's Encrypt。

Update: 在写完这篇文章一周之后才意识到,或许无意中选择了生成 SSL 证书最便捷的方式。关于 Let's Encrypt 的介绍可以参考开发者头条上的这条推荐,或者直接打开原文

3. Let's Encrypt 证书工具安装与生成

Let's Encrypt 为用户准备了自动安装脚本,可以从 GitHub 获取 使用包管理工具安装:

sudo yum install certbot

执行完毕后,Let's Encrypt 的运行环境就准备好了。

letsencrypt-auto 为常见的 Web 服务器准备了插件,可以一键生成证书并完成配置,但是我们要使用的 Nginx 插件还处于试验阶段,因此目前需要手动生成证书。暂停 80 端口上的进程,然后执行下面的命令进行证书生成:

certbot certonly

选择临时占用80端口,之后按 shell 中的提示进行设置即可。需要注意两个步骤:

  • letsencrypt 支持多域名,在 shell 中设置时,多个域名间用空格或分号隔开即可;
  • 生成证书过程中需要连接80端口进行验证,所以需要先把 Apache 或 Nginx 等占用80端口的服务暂停,等证书生成结束后重启。

生成的证书可以在 /etc/letsencrypt/live/$domain 目录下找到。切换到该目录下,可以查看刚刚生成的一系列证书文件:

其中,fullchain.pemprivkey.pem 就是 Nginx 配置 SSL 需要的证书文件。

其他环境下的安装步骤以及更多细节可以参考 Let's Encrypt 官方文档

4. Nginx 配置反向代理与 SSL 证书

有了证书后,可以通过 Nginx 配置反向代理,并使用证书进行认证,配置文件如下:

server {
    listen 443 ssl;
    server_name blog.qianyanseu.tk;
    ssl_certificate         /etc/letsencrypt/live/qianyanseu.tk/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/qianyanseu.tk/privkey.pem;
    location / {

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass         http://127.0.0.1:2368;
    }
}

配置文件中使用了上一步生成的证书与对应的私钥,并配置了需要进行反向代理的域名。用户访问 blog.qianyanseu.tk 时,Nginx 帮我们反向代理到服务器上的 2368 端口(我的 blog 服务端口)。

到这一步,SSL 证书就配置完成了,重启 Nginx 服务之后就可以使用 https://blog.qianyanseu.tk 访问本博客。

当然,目前还存在一个问题,访问博客时需要输入完整的 URL,不输入 https 中的 s,会无法访问。可以再配置一下针对几种常用 URL 的重定向:

server {
    listen       80;
    server_name  blog.qianyanseu.tk http://blog.qianyanseu.tk;
    return       301 https://blog.qianyanseu.tk$request_uri;
}

保存配置文件,重启 Nginx,现在访问 blog.qianyanseu.tk,就可以自动跳转到 https://blog.qianyanseu.tk 了。

Enjoy!

5. 证书续期

Let's Encrypt 证书的有效期为90天。证书快到期时会收到邮件提醒。给证书续期非常方便,断开80端口上跑的服务,再执行下面的命令即可。

> sudo certbot renew

如果你会写 shell 脚本的话,可以做一个定时任务,每80天跑一次,就不用再操心证书续期了。