nodejs Express + 10 分鐘申請 letsencrypt

用戶:「你這網站沒有綠標,我怎麼敢用?」,在現今就算不懂 Https 的人,也知道要看網頁上的安全標誌,現在 Https 已經成為一種網頁的基本門檻,而為了提倡使用 Https,也有許多組織開始大力推廣。

WIKI: 何謂 letsencrypt

今天看了保哥的直播,介紹一個超好用的網站,就想嘗試如何 10 分鐘快速建立起有 https 的網頁伺服器呢?並且搭配 nodejs 的 express,不過保哥講的是 IIS 的,所以就自己做了點嘗試,記錄一下心得,不過其實是大同小異。

首先要先到 sslforfree 這個網站

在中間輸入的地方輸入自己的 domain,記得一定要先申請到 domain 才能使用 SSL

接下來會進入個選擇驗證的方式

選擇中間的手動驗證底下就會在冒出一個說明,這個提示告訴我們一定要使用 80 port 或是 443 port 才可以成功,我自己試過用其他 port 例如,80 轉 8080 是不可行的,一定要 80 port

為了使用 80 port 我就在伺服器上用 root 簡單寫了一個 express server 來接

const fs = require('fs');
const http = require('http');
const https = require('https');
const express = require('express');
const app = express();
app.use(express.static('static'));
app.get('/', (res, req) => {
req.send('Hello SSL');
})
app.listen('80', () => console.log('Server run on port 80'))

很簡單的幾行程式,然後裡面有個

app.use(express.static('static'));

這行很重要,我們要在目錄中建立一個 static 目錄,等等下個步驟會將我們驗證用的檔案丟過來。

接下來回到網頁中點擊 Manually Verify Domain

第一步驟

先將 Download File 全部載下來,都是一個亂碼檔案

第二步驟

第二三步驟中,我們要先在我們剛剛說很重要的那個 static 目錄中,在建立一層 .well-known 跟 acme-challenge,所以會變成 /static/.well-known/acme-challenge,這樣子的層級

第三步驟

建立好伺服器上的目錄後,將下載好後的檔案利用 scp 這個指令將檔案從下載到的本機位置傳到伺服器上,例如我是用 linode

scp ~/Downloads/SASQWQWa9212IIrLWwRELXedITIsk2gfiySPc9rJM hostname@0.0.0.0:~/website/server/static/.well-known/acme-challenge

第四步驟

點擊給予的網址,會打開亂碼檔案並下載,nodejs 沒有這麼嚴格,所以可以直接下載沒有副檔名的檔案,只要點擊後成功下載了,就可以進行下一步

最後一個步驟

確定好已經可以點擊上述步驟下載到檔案後,確定 port 是通過 80 或 443 就可以點擊 Download SSL Certificate 了


點擊完以後(因為我已經申請過了,就略過這步驟),就會轉到一個下載 key 的地方,點擊下載以後解壓縮,然後將 certificate.crt 與 private.key 傳到伺服器上

scp ~/Downloads/openssl/certificate.crt hostname@0.0.0.0:~/website/server/ssl
scp ~/Downloads/openssl/private.key hostname@0.0.0.0:~/website/server/ssl

再將我們的 express server 改寫一下

const fs = require('fs');
const http = require('http');
const https = require('https');
const express = require('express');
const app = express();
var privateKey  = fs.readFileSync(__dirname + '/ssl/private.key');
var certificate = fs.readFileSync(__dirname + '/ssl/certificate.crt');
var credentials = { key: privateKey, cert: certificate };
app.get('/', (res, req) => {
req.send('Hello Linode');
})
var httpsServer = https.createServer(credentials, app)
httpsServer.listen(443);

再打開我們的 domain 打上 https://domain 就成功囉!

這麼一來,使用者就不會在哀嚎片野了,我有 SSL 啦,萬分感謝保哥感激保哥直播!

參考資料

wiki

保哥直播