4

简介

  • 现在已经进入 HTTPS 的时代, HTTPS 证书 目前应用广泛, 发展迅速. 相较于明文传输的 HTTP, HTTPS 更加安全.


  • HTTPSHypertext Transfer Protocol Secure, 由于其安全层使用的是 TLS/SSL, 因此 HTTPS 也可以称为 HTTP over TLSHTTP 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  --standalone

      acme 会在当前目录生成一个验证文件, 然后运行一个监听 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
  • 我们也可以通过 dns 方式来验证我们对域名的所有权. 如果要申请通配符证书 (Wildcard Certificate, 如 *.awesome.com 形式的通用域名), 则需要用 dns 方式进行验证.


    • 首先我们在 Godaddy 上申请开发者 API key & secret, 然后参考 acme.sh 的文档 readmednsapi, 执行如下命令


      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 端口, 并通过 redirecthttp 服务重定向为 https. 同时, 我们还将学习如何使用 HSTS, 使浏览器默认以更安全的 https 的方式访问我们的网站.


参考链接


FrozenMap
64 声望6 粉丝

今天,你快乐吗?