w3HexSchool
. ssl
certbot 已支援 windows 上設定 ssl 詳情請見 官方網站
最近需要在 windows 上使用 https , 遇到 https 想當然要設定 SSL 憑證啦! 🧐
以前都馬在 Linux 上使用 certbot , 真是非常 happy 😆
今天要在 windows 上安裝 SSL 憑證 ,
結果發現 certbot 不支援 windows 😱 ,
讓我們來看看在 windows 上可以如何來處理這該死的 SSL 憑證吧 !😠
膜拜完 Google 大神後 , 發現有 3 種方式可行
安裝 selfsigned
npm i -s selfsigned
建立 generate.js 檔案 , 執行之
// generate.js
const selfsigned = require('selfsigned');
const domain_names = 'localhost,sit.ttfb.com.tw'; // 不同的 domain_name 用 , 做區隔
const attrs = [{name: 'commonName', value: domain_names}];
const pems = selfsigned.generate(attrs, {days: 365});
console.log(pems);
const fs = require('fs');
// 下方會將檔案存到與 js 同層的位置
fs.writeFileSync('./key.pem', pems.private, 'utf8');
fs.writeFileSync('./cert.pem', pems.cert, 'utf8');
fs.writeFileSync('./.fingerprint', pems.fingerprint, 'utf8');
fs.writeFileSync('./.public.pub', pems.public, 'utf8');
執行後會產生 4 個檔案
讓我們用 https 模組 , 幫我們確認 SSL cert 產生的狀況吧 !
// server.js
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
https.createServer(options, function (req, res) {
res.end('secure!');
}).listen(443);
// Redirect from http port 80 to https
const http = require('http');
http.createServer(function (req, res) {
console.log('req.headers=', req.headers);
res.writeHead(301, {"Location": "https://" + req.headers['host'] + req.url});
res.end();
}).listen(80, () => console.log('http start well'));
然後用瀏覽器訪問 https://localhost 可看到以下畫面
Dashboard -> New Certificates
輸入 Domains -> Next Step
(網頁會自動做 nslookup 的檢查 , 所以要確保 nslookup 在 8.8.8.8 上查的到)
使用 90 天的 SSL 憑證 -> Next Step
自動生成 CSR 檔 -> Next Step
使用免費的 ( Free ) -> Next Step
利用 Http File Upload 作網站所有權驗證
( 我們需要向網站 zerossl 證明 Domain 是我們的 , 它才能派發可信任的 SSL 憑證給我們 < 此機制可防止駭客仿冒憑證 > )
下載 Auth File , 771957028E5EC614768BB40D0AD8C09E.txt
使用 express.js 的 app.get 輸出 Auth File 的 txt 內容
// app.js
const fs = require('fs');
const express = require('express');
const app = express();
const port = 80;
const file_name = '771957028E5EC614768BB40D0AD8C09E.txt';
app.get(`/.well-known/pki-validation/${file_name}`, (req, res) => {
const txt = fs.readFileSync(`./auth/${file_name}`).toString();
res.setHeader('content-type', 'text/plain');
res.send(txt);
});
const server = app.listen(port, () => {
console.log(`express.js start at http://localhost:${server.address().port}`);
});
需要將 771957028E5EC614768BB40D0AD8C09E.txt
放入 auth 資料夾中
// 資料夾結構
-----
|---- app.js
|---- auth
|----- ???.txt
然後用瀏覽器查看 http://stg.thaitown.andrewdeveloper.com/.well-known/pki-validation/771957028E5EC614768BB40D0AD8C09E.txt 確認 txt 內容是否可訪問到 txt 檔的內容
如果可看到 Auth File 的內容 , 按下 Next Step , 接著去 Verify Domain 了!
驗證成功後 , 會出現下方畫面 , 之後就可以下載 SSL cert 檔
選擇 nginx -> Download Certificate , 下載檔案
將下載的檔案 , 解壓縮到 cert 資料夾
建立 server.js 在 ssl 資料夾當作 http 與 https 的伺服器 , 用於驗證下載的 SSL 憑證是正常可用的受信任憑證
// server.js
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('./cert/private.key'),
cert: fs.readFileSync('./cert/certificate.crt')
};
https.createServer(options, function (req, res) {
res.end('secure!');
}).listen(443);
const http = require('http');
http.createServer(function (req, res) {
// Redirect from http to https
res.writeHead(301, {"Location": "https://" + req.headers['host'] + req.url});
res.end();
}).listen(80, () => console.log('http start well'));
然後用瀏覽器訪問 https://stg.thaitown.andrewdeveloper.com/
這樣我們就成功設定 SSL 憑證了 !
( P.S. 這個憑證只 3 個月有效 , 會失效的別忘了更新歐 )
由於需要 public host_name 所以我們使用 aws 上的 windows 伺服器作測試
下載位置 : https://github.com/do-know/Crypt-LE/releases
將下載的 le64.zip 解壓縮到桌面的 ssl 資料夾中 , 可看到檔案 le64.exe , 這就是我們之後要使用的工具
在 ssl 資料夾中 , 建立一個 add-ssl-script.txt 文字檔 , 並輸入下方文字於其中 ( 記得要改 [your_email] . [target_domain_name] 這兩個參數歐 ! )
le64.exe -email "[your_email]" -key account.key -csr domain.csr -csr-key domain.key -crt domain.crt -domains "[target_domain_name]" -generate-missing -live
將 add-ssl-script.txt 的副檔名改成 .bat , 然後執行它
add-ssl-script.bat
執行中 , 如果卡住的話 , 可按 enter 讓其執行下一動作
如果出現 Error requesting certificate 代表此次建立 cert 失敗 !
驗證的其中一個步驟會要求您將指定的 Url 放上 le64 隨機生成的文字
根據上方圖片將 url : http://[your_host]/.well-known/acme-challenge/VCxJsc-la448P9QmVB6TTHFBjwQ0O3NSPE2WNL8tPf4
回應特定文字 VCxJsc-la448P9QmVB6TTHFBjwQ0O3NSPE2WNL8tPf4.I7C2KmyCB_pAhWSyEve1U2ulMwJJ7zIAMDjFSFx34io
驗證成功後 , 可看到 The job is done, enjoy your certificate!
測試 https 是否有效 , 我們請出 node 的 http . https 模組來幫助我們驗證
const https = require('https');
// cert : https://github.com/do-know/Crypt-LE#for-windows
const fs = require('fs');
const options = {
key: fs.readFileSync('./account.key'),
cert: fs.readFileSync('./domain.csr')
};
https.createServer(options, function (req, res) {
res.end('secure!');
}).listen(443);
// Redirect from http port 80 to https
const http = require('http');
http.createServer(function (req, res) {
console.log('req.headers=', req.headers);
res.writeHead(301, {"Location": "https://" + req.headers['host'] + req.url});
res.end();
}).listen(80, () => console.log('http start well'));
// if using ssl cert with Crypt-LE you can use cmd below:
// le64.exe -email "andrew7810262000@yahoo.com.tw" -key account.key -csr domain.csr -csr-key domain.key -crt domain.crt -domains "ec2-13-229-136-81.ap-southeast-1.compute.amazonaws.com" -generate-missing -live