localhost HTTPS 環境建置
tags: HTTP
HTTPS
Node.js
Express
category: Front-End
description: 如何在 localhost 上建置 HTTPS 環境
created_at: 2024/11/12 22:00:00
前言
在開發網站時,有時候會需要在 local
建立一個 HTTPS
環境來測試一些功能,這篇文章將會介紹如何在 localhost
上建立一個 HTTPS
環境。
雖然說已經有一些功能可以在不安全的 localhost
上測試,但還是有些時候不得不使用 HTTPS
,這篇應該可以幫助你快速建立一個 HTTPS
環境。
另外這篇會以 Windows
環境為主,如果是 Mac
或 Linux
環境可能要在自己找對應的匯入方式(不確定是否相同),但產生 SSL
憑證的方式應該是一樣的。
然後最後會以簡單的 Node.js
Express
伺服器來做實驗。
前置作業
請準備好 WSL
環境,或者是相關的 Bash
環境,這邊會使用到 OpenSSL
來產生 SSL
憑證。
產生 SSL 憑證
嗯.. 其實我已經寫了一個簡單的腳本,可以直接替換變數來使用。 (當然你也可以改一些參數細節,例如我把 Organization
給留空了)
KEY_FILE=ca.key
PEM_FILE=ca.pem
PFX_FILE=ca.pfx
PFX_PASSWORD=123456
DAYS=365
DOMAIN=local-dev.app
openssl genpkey -algorithm RSA -out $KEY_FILE
openssl req -x509 -new -nodes -key $KEY_FILE -sha256 -days $DAYS -out $PEM_FILE -subj "/C=TW/ST=Taiwan/L=Taipei/O=/CN=$DOMAIN"
openssl genrsa -out $DOMAIN.key 2048
openssl req -new -key $DOMAIN.key -out $DOMAIN.csr -subj "/C=TW/ST=Taiwan/L=Taipei/O=/CN=$DOMAIN"
openssl x509 -req -in $DOMAIN.csr -CA $PEM_FILE -CAkey $KEY_FILE -CAcreateserial -out $DOMAIN.crt -days $DAYS -sha256 -extfile <(echo "subjectAltName=DNS:$DOMAIN")
openssl pkcs12 -export -out $PFX_FILE -inkey $KEY_FILE -in $PEM_FILE -passout pass:$PFX_PASSWORD
這邊會產生以下檔案:
ca.key
:CA 金鑰ca.pem
:CA 憑證ca.pfx
:CA 匯出檔案local-dev.app.key
:網域金鑰local-dev.app.csr
:網域請求憑證local-dev.app.crt
:網域憑證
建立 HTTPS 伺服器
接下來我們要建立一個 Node.js
Express
伺服器,並且使用 HTTPS
來啟動。
const fs = require('fs');
const https = require('https');
const express = require('express');
const app = express();
const options = {
key: fs.readFileSync('local-dev.app.key'),
cert: fs.readFileSync('local-dev.app.crt')
};
https.createServer(options, app).listen(443, () => {
console.log('HTTPS Server running on port 443');
});
嗯.. 非常單純連 ,這邊只是簡單的建立一個 endpoint
都沒有HTTPS
伺服器,並且使用 local-dev.app
這個網域。
記得也要先初始化專案,然後安裝 Express
。
npm init -y
npm install express
接著執行他(假設檔名是 server.js
)。
node server.js
匯入 CA 憑證
- 從瀏覽器匯入 (以下以
Chrome
為例) - 直接從
Windows
匯入 Windows
直接透過ca.pfx
匯入
瀏覽器設定
接下來我們要設定瀏覽器,讓他可以信任我們的 CA
憑證。 (以下以 Chrome
為例)
- 開啟瀏覽器,並且前往
chrome://settings/certificates
。 - 點選
管理從 Windows 匯入的憑證
。 - 點選
受信任的根憑證授權單位
頁籤。 - 點選
匯入
。 - 選擇
local-dev.app.crt
憑證。 - 一路到完成。
這樣瀏覽器就會信任我們的 CA
憑證了。
Windows 設定
Win + R
開啟執行視窗。- 輸入
certmgr.msc
並且按下Enter
。 - 點選
受信任的根憑證授權單位
。 - 點選
動作
->所有工作
->匯入
。 - 選擇
local-dev.app.crt
憑證。 - 一路到完成。
這樣 Windows
就會信任我們的 CA
憑證了。
Windows 直接透過 ca.pfx 匯入
如標題,直接點開 ca.pfx
憑證,然後密碼是你上面設定的 PFX_PASSWORD
,接著選擇 受信任的根憑證授權單位
,然後一路到完成。
設定 hosts
最後一個步驟是設定 hosts
,這樣我們的瀏覽器才能正確的導向到我們的 HTTPS
伺服器。
Windows
的 hosts
位置在 C:\Windows\System32\drivers\etc\hosts
。
127.0.0.1 local-dev.app
這樣我們就可以在瀏覽器上輸入 https://local-dev.app
來存取我們的 HTTPS
伺服器了。
好像漏了什麼?
等等,好像漏了什麼,這樣並不是 https://localhost
啊,也許你想支援多個 domain
或是 ip
,這樣可以多設定一些 Subject Alternative Name
。這樣你愛怎麼設就怎麼設
你必須準備一個檔案,格式如下:
subjectAltName = @alt_names
[alt_names]
DNS.1 = domain 1
DNS.2 = domain 2
IP.1 = ip 1
...
基本上就是 1
、2
、3
... 一路下去,然後 DNS
就是 domain
,IP
就是 ip
,而 ip
是可選(optional
)的。
所以設定可能會像這樣:
subjectAltName = @alt_names
[alt_names]
DNS.1 = local-dev.app
DNS.2 = localhost
也可以把它整合進去我們的腳本:
KEY_FILE=ca.key
PEM_FILE=ca.pem
PFX_FILE=ca.pfx
PFX_PASSWORD=123456
DAYS=365
DOMAIN=local-dev.app5
openssl genpkey -algorithm RSA -out $KEY_FILE
openssl req -x509 -new -nodes -key $KEY_FILE -sha256 -days $DAYS -out $PEM_FILE -subj "/C=TW/ST=Taiwan/L=Taipei/O=/CN=$DOMAIN"
>$DOMAIN.ext cat <<-EOF
subjectAltName = @alt_names
[alt_names]
DNS.1 = $DOMAIN
DNS.2 = localhost
EOF
openssl genrsa -out $DOMAIN.key 2048
openssl req -new -key $DOMAIN.key -out $DOMAIN.csr -subj "/C=TW/ST=Taiwan/L=Taipei/O=/CN=$DOMAIN"
openssl x509 -req -in $DOMAIN.csr -CA $PEM_FILE -CAkey $KEY_FILE -CAcreateserial -out $DOMAIN.crt -days $DAYS -sha256 -extfile $DOMAIN.ext
openssl pkcs12 -export -out $PFX_FILE -inkey $KEY_FILE -in $PEM_FILE -passout pass:$PFX_PASSWORD
主要是多了第 9
行至第 14
行,去產生一個相應的 ext
檔案,之後讓第 17
行去讀取這個檔案。
所以其實你也可以只執行 (環境變數略)
>$DOMAIN.ext cat <<-EOF
subjectAltName = @alt_names
[alt_names]
DNS.1 = $DOMAIN
DNS.2 = localhost
EOF
openssl x509 -req -in $DOMAIN.csr -CA $PEM_FILE -CAkey $KEY_FILE -CAcreateserial -out $DOMAIN.crt -days $DAYS -sha256 -extfile $DOMAIN.ext
或者是你直接去修改 ext
檔案,接著只執行重新產生 crt
檔案。
最後重新啟動你的 HTTPS
伺服器,甚至重新啟動你的瀏覽器,應該就可以正常存取了。
總結
這篇其實算是我自己的筆記,因為未來在辦比賽時可能會需要這樣的環境,讓選手端具有純內網的 HTTPS
環境,來執行一些瀏覽器需要安全的 HTTPS
的功能,這樣就不能單純是 localhost
了。
然後也不想要未來需要每次都重新查一次,乾脆就記錄成一篇文章,幫助未來的自己