Web 開發學習筆記(3) — 申請和部署HTTPS證書

FrozenMap發表於2019-02-16

簡介

  • 現在已經進入 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 的方式訪問我們的網站.

參考連結

相關文章