为Ghost配置HTTPS

Ghost Nov 22, 2017

更新:
9/12/2017: 取消注释http端口,http链接自动转跳https

自HTTPS诞生以来,是否采用HTTPS还是停留HTTP的争议就没有中断。网站不采用HTTPS的原因主要分为三点:

  1. HTTPS需要CA(Certificate Authority)签发证书,而各CA签发证书需要的费用不菲。
  2. 一旦采用HTTPS,过去使用HTTP的资源可能无法读取(例如图片)。
  3. HTTPS较HTTP慢。

针对以上几点,现时其实均有很好的解决方案。而且经过数年发展,各大网站也都使用HTTPS,使用HTTPS的好处主要为两点:

  1. 更加安全,HTTPS链接不怕被网络服务商劫持,例如加插弹窗广告。(右下角的广告就是):
    http劫持
  2. SEO优化,搜索引擎会为采用HTTPS的网址额外加分,例如Google

考虑到以上几点,作者建议所有Ghost使用者应在尽早改用HTTPS,免去日后HTTP搬迁HTTPS的麻烦。
Ghost配置HTTPS的流程十分简单,只需要:

  1. 安装certbot
  2. 更改nginx配置
  3. 自动更新CA证书
  4. 更改Ghost的HTTP链接(可选)

1. 安装certbot

以上提及使用HTTPS需要向CA申请SSL证书,SSL证书分为3种等级,等级越高,申请时间和费用越高:

  1. 域名验证(DV)
  2. 组织验证(OV)
  3. 扩展验证(EV)

每个网站应根据自身需求申请证书。如同作者一样,是为Ghost博客申请SSL证书的话,最低级的DV验证即可。
(有关SSL内容,有兴趣请查阅wiki)

为了推广HTTPS,消除申请证书的复杂步骤和金钱,Let’s Encrypt组织于2015年诞生。该组织致力于推广互联网的加密连接,为网站提供免费的SSL证书。该组织的赞助商包括Mozilla, CISCO, Chrome, EFF等互联网和网络安全巨头。

作者正式使用该组织派发的SSL证书实现HTTPS。现时不少CA也提供免费SSL证书服务,读者可自行选择。

而EFF作为Let’s Encrypt的主要赞助,也推出certbot进一步方便网站建立HTTPS链接。过程十分简单:

  1. 登入certbot官网
  2. 选择自身使用的软件和操作系统。(作者使用的是nginx和ubuntu 16.04)
    certbot
  3. 选择后将自动转跳到安装指南。

作者将演示一遍nginx和ubuntu 16.04的安装过程,不同配置过程会有所不同。

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx 

这几步只需要跟着做就可,不会发生问题。(可能有些机器已经安装software-properties-common,照做无妨)

2. 更改nginx配置

理论上跟着官网流程,接下去只需要输入

sudo certbot --nginx

即可完成SSL配置,但是作者发现ubuntu 16.04会普遍发生这种问题

Could not open file: /etc/nginx/sites-enabled/default

经调查,更改nginx的配置文件即可解决问题
在nginx根目录中(作者的nginx根目录为/etc/nginx),将nginx.conf的这行

include /etc/nginx/sites-enabled/*;

改为

include /etc/nginx/sites-enabled/*.*;

然后重新输入

sudo certbot --nginx

完成SSL配置,配置过程中certbot会询问邮箱,使用域名,以及是否强制将HTTP链接转为HTTPS。(邮箱之后会有Email认证,同时建议强制将HTTP转为HTTPS)

之后打开/etc/nginx/sites-enabled/目录下的网址conf文件(xxxx.conf),会多了以下几行:

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.codeproducers.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.codeproducers.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

if ($scheme != "https") {
    return 301 https://$host$request_uri;
} # managed by Certbot

自此HTTPS配置成功。
(作者著:Certbot只是添加了这几行,之前HTTP的接口并没有关闭。如果读者不需要保留HTTPS接口,需要自行注释前面并将代码移位,如图)(由于输入网址后,游览器会默认使用http链接,一旦关闭http接口,很大机会会出现网页不存在的错误,所以不建议关闭http接口,certbot自带的代码会自动将http连接转https。)
将certbot添加的代码略作修改(可选,作者使用了http2,第二行代码是接收ipv6的访问,需要添加‘ipv6only=on default_server’这个后续,否则有些版本的nginx会产生ipv4和ipv6冲突的问题,访问会无限循环。)

listen 443 ssl http2 default_server; 
listen [::]:443 ssl http2 ipv6only=on default_server;

(作者最终版本的nginx配置,根据读者选择,可能和读者的版本有所不同)
nginx2

2.1 使用HTTP2 (可选)

另外,使用HTTPS本身较HTTP慢,建议使用http2取代(原因参考这篇文章)。方法十分简单,只需要添加http2字眼即可:

listen 443 ssl http2; # managed by Certbot
listen [::]:443 ssl http2;

3. 自动更新CA证书

现时网址已经采用HTTPS链接了,但是事情尚未解决,由Let’s Encrypt所发出的证书仅有90日有效期。所以,还需要编写脚本来自动更新证书。
首先可运行这指令测试certbot能否更新证书:

sudo certbot renew --dry-run

出现Congratulations等则证明测试成功,接下来需要编写脚本。两种方法:

  1. 直接修改crontab文件
  2. 建立script然后修改crontab文件

3.1 直接修改crontab文件:

输入command

sudo crontab -e

然后修改crontab文件,加入以下几行:

0 0 * * * certbot renew --force-renewal
5 0 * * * service nginx restart

0 0 * * * 是crontab的时间指令,五位数分别代表分,时,日,月,星期,* 代表每次。
(图片来自 http://www.cnblogs.com/xiaohaillong/p/6102697.html
crontab
0 0 * * * 就是每日0点0分执行指令,5 0 * * * 则是每日0点5分执行指令。(预留5分钟时间更新证书)

保存修改就大功告成。

3.2 建立script然后修改crontab文件

在/root目录建立新文件,命名为letsencrypt.sh,文件内容为:

#!/bin/bash
systemctl reload nginx

# 如果有其他进程也使用该证书:
# systemctl restart mosquitto

保存文件,然后更改该文件的使用权限:

chmod +x /root/letsencrypt.sh

输入指令:

sudo crontab -e

修改crontab文件,加入一行:

20 3 * * * certbot renew --noninteractive --renew-hook /root/letsencrypt.sh

(每日3点20分更新证书,然后执行script文件重启nginx)

保存修改就大功告成。

4. 更改Ghost的HTTP链接(可选)

(可选)自此GHOST已换上HTTPS,但不排除在ghost.conf上使用的还是HTTP的链接。
更改为(作者著:这方法不会更改ghost的@blog.url,url还是原来的HTTP链接。由于ghost内部link都是根据blog.url做扩展,很大几率会从https连去http的链接,所以不建议使用):
ghost-ssl
或者改为(建议):
ghost-ssl-2
之后后请记得更改Design->Navigation的链接。否则所有HTTP链接都不可用,会返回Page Not Found的错误。

参考:

  1. Nginx on Ubuntu 16.04 (xenial)(certbot官方教程)
  2. 如何免费的让网站启用HTTPS
  3. 1125使用的命令行
  4. https是什么?使用https的好处与不足?
  5. How to setup Let's Encrypt for Nginx on Ubuntu 16.04 (including IPv6, HTTP/2 and A+ SLL rating)
  6. Let’s Encrypt