Django开发个人博客网站——32、启用Let's Encrypt免费的HTTPS证书

我这个博客网站刚搭建起来第二天,在手机端打开的时候就出现了这个抢红包的广告。还以为我的网站刚建成就被攻击了?中毒了?劫持了?……于是赶紧在网上一通搜,最后发现原来是因为网站采用的HTTP协议,传输过程都是明文的,很容易被运营商劫持,我这个广告应该就是运营商给加上去的。

这里写图片描述

解决办法很简单,我们采用将网站的协议改为HTTPS就可以了,HTTPS多了个S,也就是Secure。传输过程是通过密文传输的,是比较安全的。当然,具体是怎么加密的,我们就不深究了。接下来,我们将自己的网站布置成HTTPS协议。

网上有很多证书机构,不过基本上都是收费的,这里我们推荐Let’s Encrypt,这是个成立不久的证书机构,现阶段是完全免费的,并且一个证书可以绑定多个域名。不过每次申请只有90天的有效期,但可以通过脚本定期更新,配置好之后一劳永逸。本教程亲测有效,希望对正在寻找免费HTTPS方案的你有一定的帮助。

本站没有使用 Let’s Encrypt 官方提供的工具来申请证书,而是采用了 acme-tiny 这个小巧易用的开源工具来实现证书申请和安装。

本教程针对的是本网站配置相关:Centos7, Django1.11, Python3.6, Nginx, Uwsgi, 且本网站是搭建在阿里云服务器上的,域名以及解析都是在阿里云上的。

1、创建 Let’s Encrypt 账号

首先需要创建一个用于存放证书申请过程中的临时文件以及证书文件,例如 ssl ,无特别说明,后续操作都是在该目录下进行。进入该目录,创建一个 RSA 私钥用于 Let’s Encrypt 标识你的身份。

openssl genrsa 4096 > account.key

2、创建CSR文件

由于 Let’s Encrypt 使用的 ACME 协议需要 CSR(Certificate Signing Request,证书签名请求)文件。但在生成 CSR 文件之前需要创建域名私钥(这个域名私钥一定不能是第一步创建的账户私钥),下面先创建域名私钥:

openssl genrsa 4096 > domain.key

创建完域名私钥,就可以生成 CSR 文件了,分为两种情况:

1) 单域名

openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr

这里将yoursite.com改成你的域名即可。

2) 多域名

openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/pki/tls/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com,DNS:subdomain.yoursite.com")) > domain.csr

在 CSR 中推荐把不带 www 和带 www 的域名都加进去,其他子域名根据需要进行添加即可。如果提示/etc/pki/tls/openssl.cnf文件无法找到,可以使用命令find / -name openssl.cnf找到openssl.cnf的路径,需要将上述/etc/pki/tls/openssl.cnf更改为该路径。

3、配置验证服务

Let’s Encrypt 会在签发证书时在你的服务器上生成一个随机验证文件,后续的域名所有权验证就是通过这个随机验证文件完成。

首先,需要创建一个用于存放验证文件的目录,且该目录建议一直保留于服务器上,例如:

mkdir /data/challenges/

再配置一个 HTTP 服务,例如 Nginx:

server {
  server_name www.yoursite.com yoursite.com subdomian.yoursite.com;
  location ^~ /.well-known/acme-challenge/ {
    #存放验证文件的目录,需自行更改为对应目录
    alias /data/challenges/;                
    try_files $uri =404;
  }
  location / {
    rewrite ^/(.*)$ https://yoursite.com/$1 permanent;
  }
}

该配置会优先查找/data/challenges/目录下的文件,否则会重定向到 HTTPS 地址,后续站点服务器配置信息中需要保留这些配置信息。

4、签发证书

首先,获取 acme-tiny 脚本并保存于之前的 ssl 目录下:

wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

然后,指定账户私钥、CSR 以及验证目录(需自行更改为对应目录),执行 acme-tiny 脚本:

python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /data/challenges/ > ./signed.crt

这里需要注意的是,各个文件的目录一定要正确,否则会出现找不到文件的错误。

如果一切顺利,那么会在当前目录下生成一个signed.crt文件,这个就是 Let’s Encrypt 签发的证书文件,需要好好保管呦 (^_^)。

但凡事总有不顺,如果出现如下类似错:

ValueError: Wrote file to /data/challenges/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg, but couldn't download http://yoursite.com/.well-known/acme-challenge/oJbvpIhkwkBGBAQUklWJXyC8VbWAdQqlgpwUJkgC1Vg

可能原因有两种:

1)你没有添加不带www的域名解析

先ping下不带 www 的域名,如果不能ping通,则添加主机记录为@的域名解析即可。

2)你的域名在国外无法解析

如果存在域名国外无法解析问题,可以暂时使用外国的 DNS 解析服务商来解决,例如 dns.he.net 。

TIPS:我按照该教程来,在这一步也出现了这个问题,如果你添加了多个域名的话,一定记得在nginx的配置文件中将所有域名添加到server_name下,否则一定会出现这个错误的。并且,经过测试,阿里云的DNS服务器是没有问题的。

5、安装证书

拿到从 Let’s Encrypt 签发的证书后,还需要下载 Let’s Encrypt 的中间证书。配置 HTTPS 证书时既不能漏掉中间证书,也不能直接包含根证书,则需要把中间证书和网站证书进行合并:

openssl dhparam -out dhparams.pem 2048

wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem

cat signed.crt intermediate.pem > chained.pem

最后,在 Nginx 配置中加入证书配置项:

server {
  listen 443;
  server_name yoursite.com, www.yoursite.com;
  ssl on;
  ssl_certificate /data/ssl/chained.pem;          #根据你的路径更改
  ssl_certificate_key /data/ssl/domain.key;       #根据你的路径更改
  ssl_session_timeout 5m;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
  ssl_session_cache shared:SSL:50m;
  ssl_dhparam /data/ssl/server.dhparam;        #根据你的路径更改
  ssl_prefer_server_ciphers on;
  ...the rest of your config
}

6、配置自动更新

由于 Let’s Encrypt 签发的证书只有 90 天有效期,所以证书需要定期的进行更新,推荐使用自动化脚本定期更新。

首先,在 ssl 目录下创建自动更新脚本renew_cert.sh,并赋予执行权限:

touch ./renew_cert.sh
chmod a+x ./renew_cert.sh

然后,往renew_cert.sh添加如下内容(/data/challenges/路径,请对应自行更改):

python /data/ssl/acme_tiny.py --account-key /data/ssl/account.key --csr /data/ssl/domain.csr --acme-dir /data/challenges/ > /data/ssl/signed.crt || exit
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > /data/ssl/intermediate.pem
cat /data/ssl/signed.crt /data/ssl/intermediate.pem > /data/ssl/chained.pem
nginx -s reload

最后,crontab -e增加定时任务:

0 0 1 * * /data/ssl/renew_cert.sh 2>> /data/ssl/acme_tiny.log

就这样完成了 Let’s Encrypt 证书的自动化部署,证书每个月自动更新,无需你的干预。

7、 其它说明

现在我们已经给我们的网站升级成HTTPS安全网站了,但是登陆进去之后发现浏览器中并没有显示安全网站的样式。原来是因为我们的网站中不能有HTTP的超链接,包括链接图片。再将网站中的所有非HTTPS的超链接改成HTTPS或者直接去掉后,再次进入,我们的网站终于变成安全网站了。如下所示:

这里写图片描述

这里写图片描述

并且我们手机端也显示出现了安全的小锁标志。

但是,有一点需要注意的是,我们之前是在CSDN上写好markdown语法的博客,然后直接拷到后台发布,但是由于CSDN并不是HTTP网站,所以插入的图片也是HTTP的。为此,我们需要将图片再次上传到支持HTTPS的网站上在重新插入链接才行。简书上是直接支持HTTPS的图片,所以可以在那里编辑。并且,希望CSDN能尽快改成HTTPS的网站。

本文安装部分参考自:樊浩柏科学院

——————————————————————————————————————————

项目的完整代码:django_blog
觉得有用的欢迎给个star。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值