今天,經過無數次折騰,嚮往已久的域名備案終於下來了。於是迫不及待地將個人部落格網站進行 HTTPS 部署遷移,中間遇到一些坑,在此做個記錄。
原因
之所以要將網站從 http 遷移到 https,原因有:
- https 更安全,相對於 http 可以較為有效防止中間人攻擊,每個專案都希望安全託底。部落格雖然沒有重要資料,但不失為練兵的好地方。
- 如今 HTTP2 越來越受人關注,它可以提高訪問速度,而 HTTP2 的前提就是 HTTPS
步驟
- 安裝證照
- nginx 反向代理
- 更改前端連線方式
安裝證照
為什麼需要證照?這和 HTTPS 協議的設計有關。 HTTPS,指的是 Hypertext Transfer Protocol Secure,另外也也可以稱為 HTTP over SSL 或者 HTTP over TLS。通俗一點,HTTPS 通過 Http 協議傳輸資料,SSL/TLS 加密資料。
它是如何實現加密的呢?
首先,瀏覽器廠商預先安裝了各個 證照頒發機構
的證照,用於對訪問網站進行安全驗證
然後,個人向 證照頒發機構
申請個人證照,並將證照應用於伺服器配置中。
之後瀏覽器訪問伺服器,獲取公鑰,將其與已有的證照列表匹配,決定是否繼續。
如果通過,瀏覽器通過公鑰與伺服器通訊,協商兩個非對稱私鑰,用於各自的資料傳輸加密,從而建立的加密通道,防止中間人竊聽。
如何安裝證照? 向證照頒發機構申請證照即可。目前的機構有Symantec、Comodo、GoDaddy 以及 Let's Certbot。這裡我們選擇免費的 Let's Certbot。
在官網上有詳細的說明。我的環境是 Linux 16.04 Nginx
,其他的環境可以參照官網說明:
#####安裝:
$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx
複製程式碼
開始
$ sudo certbot --nginx certonly
複製程式碼
自動續期
可以參考 這裡
根據提示,順利安裝完畢。這裡有個前提,就是伺服器要有域名,而國內的域名都需要按照工信部要求備案,這也是為什麼我需要等待大半個月的原因。
反向代理
證照安裝完畢,如果部署在 nginx 中的是靜態頁面,那麼此刻已經順利部署了 HTTPS 服務。但是更多的應用場景中,我們一方面提供靜態服務,如 img、js、css 等等,另一方面我們也需要 REST 服務。
但是此刻,當我們通過 axios 或者 vue-resource 這樣的 HTTP client 庫來訪問 Node.js 服務 API 來獲取資料,發現瀏覽器禁止了該連線。原因是在部署 HTTPS 服務後,整站都要使用 https 來進行資料傳遞,包括資源的獲取,GET/POST
請求等等。
如何解決?我在這走了一些彎路。當時想,因為是訪問 Node.js 伺服器的 API,我知道 Node.js 是支援 HTTPS 服務的,所以想當然在 Node 中使用 Openssl
來進行自認證。網上有很多類似的教程,但是在瀏覽器中,對於自認證的證照並不認可。所以這種方法可行但不適用於其他使用者訪問,更不能應用於生產環境。這裡推薦幾個工具:
- Postman
- Firefox
第一個是可以傳送模擬瀏覽器傳送各種請求,對於測試 API 來說十分方便 第二個之所以在這裡推薦是因為我一開始使用 Chrome,但給出的錯誤提示很模糊,而 Firefox 在 Network 中對於 Request/Response 錯誤資訊會更直白,在這個問題上幫了我很多忙。
正是 Firefox 給出的提示:xxxx 提供了不支援的自簽名證照..
,我知道自簽名走不通,於是往 Nginx 上考慮了一下,想到 nginx 有反向代理功能,如果說,做一個 api 的反向代理,導航到 node 服務埠,會不會有用呢?於是在網上查詢了 Nginx 反向代理的教程,操作如下:
在 /ete/nginx/site-available/default
中:
location /api {
proxy_pass http://localhost:8089;
proxy_buffering on;
}
複製程式碼
重啟 nginx,重啟 node 服務。
success!
這樣,我們通過反向代理讓 REST 服務無需擔心證照問題,因為 Nginx 已經做了這一部分工作。
更改前端連線方式
這一部分可選,因為我之前使用的是 vue-resource
,連線使用 this.$http
所以無法對 HTTPS 進行連線,解決該問題,可以:
- 使用 axios,簡單優雅處理
最後
整個過程寫的比較亂,原因還是自己對 SSL/TLS 的底層協議不熟悉,而且 Nginx 也是新學,反向代理之前只有所耳聞,並沒有實際操作過。但不得的說,Nginx 的配置方式比較友好,一看就明白它是什麼意思。所以配置起來也不復雜。
接下去會把這部分在深入一點,寫一個系列吧。