Web 開發學習筆記(3) — 申

簡介

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

參考鏈接