引言
时间即将进入2017年,2017年,苹果开始强制要求APP使用https的接口;2017年,各大营销平台对落地页的要求是必须是https页面;2017年,是微信小程序元年,微信小程序要求接口必须是https的。2017年,https已经到来,你和你的网站准备好了么?
怀着这样一个目的,我开始了给自己的网站安装https的历程。首先,介绍一下我的网站,Drupal项目社区,域名是:www.drupalproject.org。主要是为了Drupal在国内的推广以及Drupal新手查阅一些相关资料。这个网站目前基于Drupal7,有多个子域名,是典型的Drupal多站点架构。
在实施的过程中,我最大的体会是大部分查阅的资料很多都没办法用上,因为每个人的网站运行环境是不同的,所以我不打算把这篇文字写的特别细,只概述几个我印象特别深刻的几个地方,希望能给朋友们一些思路和灵感。
谁可以给我证书
第一件事就是到哪里注册证书,查阅了一些资料,大家首推的是Let’s Encrypt,其他的我也就不提及了,只说一下这个CA是免费的,各浏览器都信任,可以自动更新。在选择机构上面,我并没有花太多时间。通过官网的介绍,我知道我需要用一个叫Certbot的东西当客户端。
Docker
本文不会详细介绍Docker,但我的网站目前是基于Docker架构运行的,通过Docker Compose管理,内部基于Nginx和php-fpm,通过几个月的尝试,非常的稳定,而且易于运维,所以非常推荐大家也开始尝试Docker。
Certbot
由于用的是Docker,所以Certbot也要在Docker的架构下,在Docker官方的镜像仓库搜了一下,有很多私有镜像已经帮我做好了,通过尝试,我选择了其中的一个,以下是docker-compose.yml中的相关配置。
version: '2' |
这里不会讲Docker Compose配置文件的语法,大家需要注意到的是,我使用的镜像是quay.io/letsencrypt/letsencrypt,是由CoreOS提供的。启动这个容器之后,我们就能得到证书了,是不是很简单?
证书的地址在容器中的位置是:
/etc/letsencrypt/live/drupalproject.org |
在实际使用时,我是通过Docker容器卷挂载的方式,所以路径会有所不同。
大家可能会注意到,我分别为每个子域名申请了证书,因为Let’s encrypt不发放泛域名证书,这一点大家要注意,另外证书的有效期只有3个月。
那么证书过期了怎么办呢?我们需要在证书过期之前更新证书,这一点Certbot客户端为我们封装了命令,使用起来很简单,借助于Docker这个更新就更方便了,以下是命令,要注意的是启动之前要关闭Nginx,执行后再开启Nginx,我是把这件事情放在服务器的计划任务的,但是也可以手动执行。
docker-compose run --rm --service-ports certbot certbot renew |
使用证书
得到了证书只是第一步,我们还需要把证书配置在Web服务器中,例如Apache或者Nginx,我自己用的是Nginx,所以我以Nginx为例。并且这里要提前跟大家说的是,证书配置到Nginx之后还不行,后面还要做一些其他配置。
以下是我Nginx上证书相关的配置。
|
这里的配置只是和证书相关的一部分,不是我完整虚拟主机的配置。并且也不是每个人都需要和我一样的配置,这个配置只是一个参考。下面我来解释各个部分的含义:
- Part 1 是用于把drupalproject跳转到www.drupalproject.org,不管是不是https。
- Part 2 是把任何非https的二级域名跳转到https的向应二级域名。
- Part 3 是真正的对https的请求,挂载https证书。
我个人认为这样的配置,对我来说是最合理的一种配置。
网站配置
这样配置以后,网站本身已经支持https了,但是由于网站还没有进行配置,所以现在打开的话,网页浏览还是不正常的,地址栏还没有出现绿色的锁头。
下面是网站需要做的相关配置:
settings.php$conf['https'] = TRUE;
开启了这项服务之后,网站是可以在http和https中共享session的,虽然我要的是全站https,但我还是开着,万一以后改成半http半https呢?
https网站如果想要被浏览器信任,需要进一步加载的资源都是https的,这就需要网站在https访问时对网站代码进行一个替换,这种替换有多种方法,比如只修改$base_url就是其中最简单的一种。这里我不是这样做的。我用的完整代码如下,大家可以看到我封装了一个http2https的模块,因为我还不认为这是最佳方式,只是可以工作的一种方式,还有进一步的优化空间:
|
总结
在以上代码和配置的作用下,我的网站终于实现了全站https。虽然本文篇幅不长,但是从我开始决定这么做,到我成功实现实际用了很长时间,踩了无数的坑儿,我的摸索之路也不是按照上面的顺序一帆风顺,而是来回调整的。