Node.js + Nginx 部署 HTTPS 服務

allenWang發表於2018-06-07

今天,經過無數次折騰,嚮往已久的域名備案終於下來了。於是迫不及待地將個人部落格網站進行 HTTPS 部署遷移,中間遇到一些坑,在此做個記錄。

原因

之所以要將網站從 http 遷移到 https,原因有:

  • https 更安全,相對於 http 可以較為有效防止中間人攻擊,每個專案都希望安全託底。部落格雖然沒有重要資料,但不失為練兵的好地方。
  • 如今 HTTP2 越來越受人關注,它可以提高訪問速度,而 HTTP2 的前提就是 HTTPS

步驟

  1. 安裝證照
  2. nginx 反向代理
  3. 更改前端連線方式

安裝證照

為什麼需要證照?這和 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 來進行自認證。網上有很多類似的教程,但是在瀏覽器中,對於自認證的證照並不認可。所以這種方法可行但不適用於其他使用者訪問,更不能應用於生產環境。這裡推薦幾個工具:

第一個是可以傳送模擬瀏覽器傳送各種請求,對於測試 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 的配置方式比較友好,一看就明白它是什麼意思。所以配置起來也不復雜。

接下去會把這部分在深入一點,寫一個系列吧。

相關文章