如何用只支持http的七牛云CDN免费实现全站https

本篇博客主要讲解了用七牛云CDN实现全站https

事先声明:此方法适用于拥有自己的服务器,能够安装nginx,因为本篇博客nginx起到关键作用

https的意义

HTTPS主要通过在SSL上传输数据来区分HTTP,确保传输的数据在传输过程中被加密,只有相应站点服务器或用户浏览器接收时才能被解密,HTTPS通过这种方式避免了第三方拦截。同时,HTTPS提供可信的服务器认证,这是一套黑客不能随意篡改的认证信息,使相关用户确定他们正与正确的服务器通信。

全站https的初心

一开始博主的博客是搭载在github上的,可是因为github是国外的IP,加载及其的慢,即使用了CDN也无济于事。正好博主在去年学习Linux的时候趁着大四学生最后一年在腾讯云买了一台学生服务器,于是将博客搬到服务器上了。而本人久闻七牛云大名,所以CDN使用得是七牛云的免费10G。因为我的博客也没什么流量,一个月顶破天我自己访问能不能过百兆是个问题,所以肯定够用的(小声比比:希望我的博客以后访客能上来)。搬到服务器上的时候并没有https,但是想着现在证书都是免费颁发,而且https也是安全的象征,现在的网站基本都使用了https。再说,google浏览器会给https一把小锁,看着别人的https上面有把小锁,这感觉都爽歪歪鸭.再看看自己,网页啥都没。得,为了这把锁,我今天也得给他来个全站https了。
https网页上的标志

实操开始

申请ssl证书

既然要全站https那必不可少的是申请证书了,因为博主域名是在腾讯云买的,所以是直接在腾讯云管理平台申请的ssl证书,选择自动验证几分钟就把证书颁发下来了,我们直接点击下载将证书下载过来。解压之后会有四个文件夹,因为我们用的nginx,所以只需要nginx文件夹下面的bundle.crt和.key两个文件,至于外层的csr我们不需要用到。

部署nginx并且开启https监听

因为本人最近在学习docker,并且docker的容器管理实在是方便,所以是用的docker拉取nginx镜像以容器的方式启动nginx。docker入门学习的话可以去菜鸟联盟看一看,我觉得讲解的还是很详细的。以下是我docker启动nginx的shell命令。

1
$ docker run -d -p 80:80 -p 443:443 --name myNginx -v /usr/local/nginx/www:/usr/share/nginx/html -v /usr/local/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /usr/local//nginx/logs:/var/log/nginx nginx

接下来就是配置nginx的conf文件了,首先我们可以开启网页gzip压缩,这样能把我们网页压缩将近一半,提高访问速度。然后就是nginx配置监听443端口进行证书加密的操作了。以下是我的部分配置文件。

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#设定http服务器
http {
#文件扩展名与文件类型映射表
include mime.types;
#默认文件类型
default_type application/octet-stream;
#开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如
果图片显示不正常把这个改 成off。
sendfile on;
#防止网络阻塞
#tcp_nopush on;
#长连接超时时间,单位是秒
keepalive_timeout 65;
#开启gzip压缩输出
gzip on;
#最小压缩文件大小
gzip_min_length 1K;
##压缩缓冲区
gzip_buffers 4 8k;
##压缩类型
gzip_types text/* text/css text/plain application/javascript application/x-javascript application/xml application/json image/jpeg image/png image/gif application/octet-stream;
##压缩级别 1-9 1最快 9最慢
gzip_comp_level 9;
##压缩通过代理的所有文件
gzip_proxied any;
##vary header支持
gzip_vary on;
##压缩版本(默认1.1,前端为squid2.5使用1.0)
gzip_http_version 1.1;

# 监听https请求并配置证书
server {
listen 443 ssl;
server_name ovvow.com; #填写绑定证书的域名
ssl_certificate /var/log/nginx/ssl/1_xxx_bundle.crt; #证书文件名称
ssl_certificate_key /var/log/nginx/ssl/2_xxx.club.key; #私钥文件名称
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #请按照这个协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; #请按照这个套件配置
ssl_prefer_server_ciphers on;
root /usr/share/nginx/html;
index index.html;
error_page 404 /404.html;
location ~ .*\.(gif|css|js|jpg|jpeg|png|ico|webp)$ {
valid_referers none blocked ovvow.com blog.gpdstudy.clu b;
if ($invalid_referer) {
return 404 /404.html;
}
}
}

# 将http请求重定向到https
server {
listen 80;
server_name ovvow.com;
return 301 https://$server_name$request_uri;
}

# 配置CDN支持https访问
server {
listen 443 ssl;
# 我们博客用来配置CDN的网址
server_name qiniuyun.ovvow.com;
ssl_certificate /var/log/nginx/ssl/1_qiniuyun.ovvow.com_bundle.crt;
ssl_certificate_key /var/log/nginx/ssl/2_qiniuyun.ovvow.com.key;
location / {
# 七牛云CDN设置的回源网址
proxy_pass http://回源设置的域名.ovvow.com;
}
}

}

以上部分都有注释,其中第一部分是配置网页压缩,以提高我们博客的访问速度;第二个则是监听我们的https请求,配置证书加密后跳转到我们博客的主页;第三个是将我们的http请求全部重定向到我们的https上。第四个则是重头戏,这个是我们使用https请求CDN的配置。

配置原理

前面的配置不多说相信大家都知道,我就重点说一说第四个吧。我们配置七牛云的CDN时需要绑定一个回源HOST,这个回源HOST需要我们在域名处配置CNAME转到七牛云给我们提供的CDN网址。但是七牛云只支持http请求,如果我们要使用https则需要另行付费。但是我们想一想https的原理就知道,其实这就是经过一层ssl加密数据并进行传输。我们既然无法在七牛云设置https传输数据,那我们自己在请求中间加一层不行吗?于是,我有了这个想法之后参考了第二部分博客实现https的原理。另外申请了一个子域名的ssl,然后通过nginx加密请求之后将反向代理请求到我的CDN域名上获取http资源。结果是令人兴奋的,我的实验成功了。最后说一句,我们这个配置的原理就是利用自己申请的ssl证书来加密我们的请求,再通过nginx反向代理获取我们CDN上的静态资源。这样,我们就能保证我们的资源是经过https加密的。

说说薅羊毛

通过这个示例我发现了一个薅羊毛的方法,我听说国内还有其他的CDN服务商。也就是说,我们可以两边同步我们的资源文件夹,当我们其中一个CDN流量要用完的时候,我们在nginx里面修改配置,将反向代理的网址修改为另一个CDN服务商的回源网址。这样我们无需改变我们博客的任何位置,就能实现将CDN换源,是不是想想就激动呢?不过我就没这个想法了,七牛云10G我相信我能用一年,更不要说每个月都给10G,我就懒得薅这个羊毛了,缺流量的站长可以薅一下。

说说踩过的坑

(1)因为以前一直是监听的80端口,通过不同的域名来跳转我的项目。昨天启动nginx的时候忘了映射443端口,导致后续http重定向到https的时候一直无法访问,查看nginx配置半天也没发现端倪。最后查看防火墙端口的时候发现我的443端口没有被监听,遂恍然想起自己只映射了80端口并未映射443端口。希望大家以我为戒,不要犯这种低级问题,要记住想要监听端口就得把服务器的端口映射给容器。

(2)docker容器内配置文件的地址只能访问到容器内部的地址,并不能访问到服务器地址,开始把秘钥放在了服务器的nginx/conf文件夹下面,结果发现无法访问。后来索性在logs下新建了ssl文件夹存放我的证书,因为我的logs文件夹映射了容器/var/log/nginx/文件夹,所以通过此路径能找到我的ssl证书。

(3)在配置的时候,我并不知道一个域名对应一个证书,当时以为配置了主站所有的子域名都可以使用这个证书,所以在设置”qiniuyun.ovvow.com”域名加密反向代理到七牛云回源网址的时候虽然能够代理成功,但是却被Google拦截了,导致所有的CDN请求直接被阻挡加载不进来。如下图。
错误设置证书
博客无法加载静态资源
最后仔细一看发现颁发的证书与实际访问的网址不一样,百度了一下发现每一个子域名都得设置一个证书。于是又申请了两个证书在nginx配置完成之后成功加载资源。
代理成功返回的图片链接
实际被访问的链接

虽然在配置的过程是痛苦的,但是最后实现了自己的想法,还是蛮开心的。