在前面一篇文章中,使用openssl生成了免費證書 後,我們現在使用該證書來實現我們本地node服務的https服務需求。假如我現在node基本架構如下:
|----專案 | |--- static # 存放html檔案 | | |--- index.html # index.html | |--- node_modules # 依賴包 | |--- app.js # node 入口檔案 | |--- package.json | |--- .babelrc # 轉換es6檔案
index.html 檔案程式碼如下:
<!DOCTYPE html> <html> <head> <meta charset=utf-8> <meta name="referrer" content="never"> <title>nginx配置https</title> </head> <body> <div> <h2>歡迎使用https來訪問頁面</h2> </div> </body> </html>
app.js 程式碼如下:
const Koa = require('koa'); const fs = require('fs'); const path = require('path'); const router = require('koa-router')(); const koaBody = require('koa-body'); const static = require('koa-static'); const app = new Koa(); router.get('/', (ctx, next) => { // 設定頭型別, 如果不設定,會直接下載該頁面 ctx.type = 'html'; // 讀取檔案 const pathUrl = path.join(__dirname, '/static/index.html'); ctx.body = fs.createReadStream(pathUrl); next(); }); app.use(static(path.join(__dirname))); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(3001, () => { console.log('server is listen in 3001'); });
package.json 程式碼如下;
{ "name": "uploadandload", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "dev": "nodemon ./app.js" }, "author": "", "license": "ISC", "dependencies": { "fs": "0.0.1-security", "koa": "^2.7.0", "koa-body": "^4.1.0", "koa-router": "^7.4.0", "koa-send": "^5.0.0", "koa-static": "^5.0.0", "nodemon": "^1.19.0", "path": "^0.12.7" } }
然後我在專案的根目錄下執行 npm run dev 後,就可以在瀏覽器下訪問 http://localhost:3001 了,但是為了我想使用域名訪問的話,因此我們可以在 hosts檔案下繫結下域名,比如叫 xxx.abc.com . hosts檔案如下繫結:
127.0.0.1 xxx.abc.com
因此這個時候我們使用 http://xxx.abc.com:3001/ 就可以訪問頁面了,如下所示:
如上所示,我們就可以訪問頁面了,但是我們有沒有發現,在chrome瀏覽器下 顯示http請求是不安全的,因此這個時候我想使用https來訪問就好了,網頁的安全性就得到了保障,但是這個時候如果我什麼都不做,直接使用https去訪問的話是不行的,比如地址:https://xxx.abc.com:3001. 如下圖所示:
我們知道使用https訪問的話,一般是需要安全證書的,因此我們現在的任務是需要使用nginx來配置下安全證書之類的事情,然後使用https能訪問網頁就能達到目標。
如果想要學習nginx基本安裝及基本知識點,請看我之前的這篇文章
nginx配置https服務
1. 首先進入nginx目錄下,使用命令:cd /usr/local/etc/nginx。然後在該目錄下建立 cert資料夾,目的是存放證書檔案。
使用命令:mkdir cert 如下所示:
2. 然後我們需要把證書相關的檔案,比如server.crt 和 server.key 檔案複製到該 cert目錄下。比如如下證書檔案:
至於如上證書是如何生存的,可以請看我上篇文字 使用openssl 生存免費證書
移動命令:mv server.key /usr/local/etc/nginx/cert, 比如把server.key 和 server.crt檔案都移動到 /usr/local/etc/nginx/cert目錄下。如下圖所示:
然後我們再檢視下 /usr/local/etc/nginx/cert 目錄下,有如下檔案,如下所示:
3. nginx的配置
nginx的配置需要加上如下程式碼:
server { listen 443 ssl; server_name xxx.abc.com; ssl on; // 該配置項需要去掉 ssl_certificate cert/server.crt; ssl_certificate_key cert/server.key; /* 設定ssl/tls會話快取的型別和大小。如果設定了這個引數一般是shared,buildin可能會引數記憶體碎片,預設是none,和off差不多,停用快取。如shared:SSL:10m表示我所有的nginx工作程式共享ssl會話快取,官網介紹說1M可以存放約4000個sessions。 */ ssl_session_cache shared:SSL:1m; // 客戶端可以重用會話快取中ssl引數的過期時間,內網系統預設5分鐘太短了,可以設成30m即30分鐘甚至4h。 ssl_session_timeout 5m; /* 選擇加密套件,不同的瀏覽器所支援的套件(和順序)可能會不同。 這裡指定的是OpenSSL庫能夠識別的寫法,你可以通過 openssl -v cipher 'RC4:HIGH:!aNULL:!MD5'(後面是你所指定的套件加密演算法) 來看所支援演算法。 */ ssl_ciphers HIGH:!aNULL:!MD5; // 設定協商加密演算法時,優先使用我們服務端的加密套件,而不是客戶端瀏覽器的加密套件。 ssl_prefer_server_ciphers on; location / { proxy_pass http://localhost:3001; } }
注意:如上 ssl on; 這個配置項需要去掉。假如是如上的配置後,我重新啟動下nginx命令會報錯,如下所示:
SSL: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:0906A065:PEM routines:PEM_do_header:bad decrypt 類似這樣的錯,然後通過百度搜尋這個錯誤,通過如下方法可以解決:
進入到該目錄下:cd /usr/local/etc/nginx/cert 然後執行下面兩句程式碼即可:
cp server.key server.key.org openssl rsa -in server.key.org -out server.key
如下所示:
可以看百度搜尋出來的頁面(http://ju.outofmemory.cn/entry/17732)
然後當我繼續重啟下 nginx, 發現還會報錯,報錯資訊如下:
nginx: [warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
然後繼續把 ssl on; 這句配置項去掉就可以了,可能和nginx的版本有關係,請看這篇文章(https://blog.csdn.net/ootw/article/details/81059677).
現在我繼續重啟下nginx就ok了,如下所示:
但是如上配置後,我們還不能直接 使用 域名 https://xxx.abc.com/ 訪問了,我們還需要在瀏覽器下把自己之前生成的client.crt 證書安裝上去,在mac系統下操作步驟如下:
1. 點選如下啟動臺。如下所示:
2. 搜尋鑰匙串訪問,點選進去,如下所示
3. 進入到證書頁面,把我們之前的client.crt證書拖進到證書裡面去即可,比如我之前生成的 client.crt證書,如下所示:
4. 右鍵點選我的證書,然後點選 "顯示簡介", 進入到證書詳情頁面後。如下圖所示:
5. 進入頁面後,使用證書時,選擇始終信任後,如下圖所示:
6. 然後退出,可能需要輸入電腦開機密碼,輸入完成,會自動儲存。然後我們在瀏覽器訪問該 https://xxx.abc.com/ 頁面後就可以訪問的到了。如下所示:
然後我們點選繼續訪問即可看到頁面了,如下所示:
如上就是使用 nginx + 證書 實現 本地node https服務了。
但是如上https雖然可以訪問,但是https前面還是顯示不安全的文案; 如下圖所示:
可能的原因該證書是自己生成的證書,不是購買第三方的證書導致的吧。具體啥原因,目前我也不知道,至少現在我們可以使用https來訪問我們的專案了。
github上簡單node服務啟動的原始碼