在 Express 中設置 Let’s Encrypt
如何使用流行的免費解決方案 Let’s Encrypt 設置 HTTPS
如果你在自己的 VPS 上運行 Node.js 應用程式,你需要一個獲取 SSL 憑證的解決方案。
使用 Let’s Encrypt 和 Certbot 是當今的標準做法,它們是由 EFF(Electronic Frontier Foundation)提供的工具。EFF 是一家致力於保護隱私、自由言論和整個數位世界公民權利的領先非盈利組織。
我們將按照以下步驟進行:
安裝 Certbot
以下指令假設你使用 Ubuntu、Debian 或任何其他使用 apt-get
來管理套件的 Linux 發行版:
1 | sudo add-apt-repository ppa:certbot/certbot |
你也可以在 Mac 上安裝 Certbot 進行測試(需要 Homebrew):
1 | brew install certbot |
然而,你需要將其連接到一個真實的域名,以便它有用。
使用 Certbot 生成 SSL 憑證
現在 Certbot 已安裝完成,你可以使用它來生成憑證。你必須以 root 身份運行此命令:
1 | certbot certonly --manual |
或者你也可以在非 root 使用者環境下使用 sudo:
1 | sudo certbot certonly --manual |
以下是詳細的過程:
安裝程式將要求你提供你的網站域名。
… 然後要求你提供你的電子郵件:
1 | ➜ sudo certbot certonly --manual |
… 並且要求你同意服務條款:
1 | Please read the Terms of Service at |
… 以及是否允許共享你的電子郵件:
1 | Would you be willing to share your email address with the Electronic Frontier |
… 最後,我們可以輸入要使用 SSL 憑證的域名:
1 | Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' |
安裝程式還會詢問是否記錄你的 IP 地址:
1 | Obtaining a new certificate |
… 最後我們需要進行域名驗證!
1 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
現在,讓 Certbot 單獨執行一段時間。
我們需要通過創建一個名為 TS_oZ2-ji23jrio3j2irj3iroj_U51u1o0x7rrDY2E
的文件在 .well-known/acme-challenge/
文件夾中來驗證我們擁有該域名。請注意!我剛剛貼入的奇怪字符串將在每次進行此過程時都改變。
由於預設情況下這些文件夾和文件並不存在,你需要創建它們。
在這個文件中,你需要放入 Certbot 打印的內容:
1 | TS\_oZ2-ji23jrio3j2irj3iroj\_U51u1o0x7rrDY2E.1DzOo\_voCOsrpddP\_2kpoek2opeko2pke-UAPb21sW1c |
至於文件名 - 這個字符串每次運行 Certbot 時都是唯一的。
允許 Express 提供靜態文件
為了從 Express 提供該文件,你需要啟用靜態文件的提供。你可以創建一個 static
文件夾,並在其中添加 .well-known
子文件夾,然後像這樣配置 Express:
1 | const express = require('express') |
dotfiles
選項是必需的,否則以 .
開頭的 .well-known
文件將無法被訪問。這是一項安全措施,因為點文件可以包含敏感信息,默認情況下最好保留它們。
確認域名
現在運行應用程式,並確保該文件可以從公共互聯網訪問。返回正在運行的 Certbot,按 ENTER 鍵繼續執行腳本。
獲取憑證
完成!如果一切順利,Certbot 已經創建了憑證和私鑰,並將它們放在你計算機上的某個文件夾(當然,它也會告訴你該文件夾的位置)。
現在,只需將路徑拷貝/粘貼到應用程式中,以開始使用它們來提供請求:
1 | const fs = require('fs') |
請注意,我讓此服務器在 443 端口上監聽,因此需要使用 root 權限運行。
此外,此服務器僅運行在 HTTPS 上,因為我使用了 https.createServer()
。你也可以同時運行一個 HTTP 服務器,只需運行以下代碼:
1 | http.createServer(app).listen(80, () => { |
設置續訂
SSL 憑證只有效期 90 天,所以你需要設置自動續訂的系統。
如何設置呢?使用定時任務。
定時任務是一種在指定時間間隔運行任務的方式。可以是每周、每分鐘、每月等等。
在我們的例子中,我們將按照 Certbot 的建議,每天運行續訂腳本兩次。
首先,找出你系統上 certbot 的絕對路徑。我使用 macOS 上的 type certbot
命令找到它,而在我這裡它的位置是 /usr/local/bin/certbot
。
以下是我們需要運行的腳本:
certbot renew
這是定時任務的項目:
1 | 0 */12 * * * root /usr/local/bin/certbot renew >/dev/null 2>&1 |
以上代表“每 12 小時運行一次,每天運行兩次:00:00 和 12:00”。
提示:我使用 https://crontab-generator.org/ 生成了這個行。
使用以下命令將新創建的腳本添加到系統的 crontab 中:
1 | env EDITOR=pico crontab -e |
這將打開 pico
編輯器(根據你的喜好,可以替換為其他編輯器)。只需輸入新的腳本,保存,即可安裝 cron 作業。
完成後,你可以使用以下命令查看活動的 cron 作業列表:
1 | crontab -l |
tags: [“node.js”, “Let’s Encrypt”, “Certbot”]