Web 开发学习笔记(3) — 申
- 2020 年 1 月 3 日
- 笔记
简介
- 现在已经进入
HTTPS
的时代,HTTPS 证书
目前应用广泛, 发展迅速. 相较于明文传输的HTTP
,HTTPS
更加安全. -
HTTPS
即Hypertext Transfer Protocol Secure
, 由于其安全层使用的是TLS/SSL
, 因此HTTPS
也可以称为HTTP over TLS
或HTTP over SSL
. 关于HTTPS
证书的分类, 可以参考这篇博客 -
HTTPS 证书
需要向国际公认的证书证书认证机构 Certificate Authority (CA) 申请. - 接下来, 我们将使用自动化证书管理工具 acme.sh 为我们的域名申请 Let's Encrypt 颁发的
HTTPS
证书, 然后将其部署在我们的网站上. - 本文假设我们的域名为
www.awesome.com
开发环境
- 在前文的基础上, 我们只需增加 acme.sh 这个工具. 它的中文文档在这里. 安装
acme.sh
的过程很简单, 在Terminal
中输入如下命令acme.sh
即可. curl https://get.acme.sh | sh
生成证书
- 我们可以使用
http
方式来验证我们对域名的所有权.- 如果只申请单域名证书 (Single Domain Certificate, 如单域名
www.awesome.com
), 那么在Terminal
中运行如下命令即可 acme.sh –issue -d www.awesome.com –standaloneacme
会在当前目录生成一个验证文件, 然后运行一个监听 80 端口的 server, 如果Let's Encrypt
成功地通过域名下载了这个文件, 就验证了我们对域名的所有权, 就可以签发证书了. 我们也可以运行一个file server
监听80
端口 cd ~/webapp python3 -m http.server 80 然后在另一个Terminal
里输入如下命令 cd ~ acme.sh –issue -d www.awesome.com –webroot ~/webapp
- 如果只申请单域名证书 (Single Domain Certificate, 如单域名
- 我们也可以通过
dns
方式来验证我们对域名的所有权. 如果要申请通配符证书 (Wildcard Certificate, 如*.awesome.com
形式的通用域名), 则需要用dns
方式进行验证.- 首先我们在
Godaddy
上申请开发者API key & secret
, 然后参考acme.sh
的文档 readme 和 dnsapi, 执行如下命令 export GD_Key="xxxxxxxx" export GD_Secret="yyyyy" acme.sh –issue –dns dns_gd -d "*.awesome.com" -d awesome.com 如果一切顺利, 我们会发现 Godaddy 的DNS txt record
中多了一条_acme-challenge
记录. 接下来acme
会先等待120s
以待新的纪录生效, 然后通知Let's Encrypt
验证我们对域名的所有权, 验证通过后,Let's Encrypt
会为我们签发证书.
- 首先我们在
- 下一节, 我们将讲述如何安装和部署证书
安装和部署证书
- 对于单域名证书, 根据 acme 的文档, 我们需要执行以下命令, 将证书和公钥放到
~/ssl/
文件夹中 acme.sh –installcert -d www.awesome.com –key-file ~/ssl/server.key –fullchain-file ~/ssl/server.cer - 对于通配符证书, 操作也是类似的, 把域名换成
"*.awesome.com"
就好了 acme.sh –installcert -d "*.awesome.com" –key-file ~/ssl/server.key –fullchain-file ~/sslwebsite/server.cer - 然后, 在之前编写的 server 中, 我们需要引入证书和公钥, 从而将明文的消息用 ssl/tls 包裹起来. 根据 Stack Overflow, 这篇文章下面的 Comments, 以及 werkzeug docs, 我们需要在
app.run()
中加上ssl_context=('~/ssl/server.cer', '~/ssl/server.key')
参数, 再把监听端口改为443
即可: # class IndexHandler(…): # … if __name__ == '__main__': app.add_url_rule('/', view_func=IndexHandler.as_view('index')) context = ('./server.cer', './server.key') app.run(port=443, host='0.0.0.0', debug=True, threaded=True, ssl_context=context) - 至此, 我们的
HTTPS
证书已经申请和部署完成了. 但是我们的server
目前还存在一个问题, 就是只能访问https://www.awesome.com
, 而原来的http://www.awesome.com
已经无法访问了, 因为我们的server
现在只能监听443
端口而不能监听80
端口. 下一篇文章, 我们将解决这个问题, 方法是另外写一个server
来监听80
端口, 并通过redirect
将http
服务重定向为https
. 同时, 我们还将学习如何使用HSTS
, 使浏览器默认以更安全的https
的方式访问我们的网站.
参考链接
- https://imququ.com/post/letse…
- https://github.com/Neilpang/a…https://github.com/Neilpang/a… https://github.com/Neilpang/a…
- https://letsencrypt.org/
- https://stackoverflow.com/que…http://flask.pocoo.org/docs/1… http://flask.pocoo.org/snippe… http://werkzeug.pocoo.org/doc… http://werkzeug.pocoo.org/doc…
- https://jjayyyyyyy.github.io/…