Web 開發學習筆記(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 –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
的文檔 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
的方式訪問我們的網站.
參考鏈接