iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
IT Operation

從前後端踏上 AWS 雲端架構勇者之路系列 第 26 篇

HTTPS:有網址之後,還要替連線加密

  • 分享至 

  • xImage
  •  

上一章節我們用 DNS 和 Nginx,讓別人能透過網址連到我們的 Node.js Container。不過網址前面還是 http://,如果之後要傳登入帳密,總不能就這樣送出去啊

今天會把瀏覽器到 Nginx 這段改成 HTTPS,讓傳輸內容加密,也讓瀏覽器能檢查網站的憑證。憑證有到期日,所以除了申請,還要把自動續期一起處理好

接著我們一起展開這項旅程勒 :D

到底誰來幫我們發憑證?

假設你打開 api.example.com,瀏覽器要確認對方拿出的憑證,能不能代表這個網域名稱

負責簽發憑證的機構叫做 CA(Certificate Authority,憑證機構)。這次會用到三個角色:

  • Let's Encrypt:簽發憑證的 CA
  • Certbot:裝在 EC2 上,幫我們申請、安裝與更新憑證的工具
  • Nginx:拿著憑證,接收瀏覽器的 HTTPS 請求

瀏覽器以 HTTPS 連到 Nginx,Certbot 向 Let's Encrypt 申請與更新網站憑證

圖中左邊走 HTTPS 443,到了 Nginx 才解密,再透過同一台 EC2 的 127.0.0.1:8080 交給 Container。後面這一小段還是 HTTP

今天申請的是網站憑證,跟 Node.js 連到 RDS 的那段 TLS 是分開的,不用拿這張憑證去改資料庫設定哦

要開 HTTPS,為什麼還需要 80?

Let's Encrypt 不會只聽我們說「這個網域是我的」,就直接發憑證。它得先確認我們能控制這個名稱

這次使用 HTTP-01 驗證:Certbot 先替 Nginx 準備一段驗證內容,Let's Encrypt 再從外面連進網域的 80 port,到 /.well-known/acme-challenge/ 底下讀取它。確認內容正確,才會簽發憑證

Certbot 準備驗證內容,Let's Encrypt 經由 DNS 找到主機,再從 80 port 驗證網域控制權

所以 DNS 要指對主機,80 也要能從外部連進來。只有在 EC2 裡測 localhost 成功,還不夠哩(也附上 Let's Encrypt 驗證方式)

這個驗證證明的是網域控制權,不是在替網站內容背書。詐騙網站也可能有 HTTPS XD

先接好 80 和 443 的入口

延續前篇的 Ubuntu 24.04、主機上的 Nginx,以及已經能使用的網域。下面的 api.example.com 都要換成自己的名稱;如果你用的是前篇的 nip.io 名稱,就繼續用那一個

如果前篇結束後把 EC2 停機了,先啟動同一台主機,確認 Nginx 和 Container 已經運作,再從自己電腦、還沒 SSH 的終端機檢查:

dig +short api.example.com A
curl -i http://api.example.com/health

第一行會查到 EC2 的 EIP,第二行會回 200 和 {"status":"ok"}。Windows PowerShell 的第一行改成 Resolve-DnsName api.example.com -Type A,後面的 curl 都使用 curl.exe

如果另外有 AAAA 紀錄,也就是 IPv6 的 DNS 紀錄,它也得指向可用的入口;沒有使用 IPv6,就移除這個名稱底下指錯的 AAAA 紀錄,避免驗證走錯地方

接著回到 AWS 的東京區,進入 EC2 → Instances → 選自己的主機 → Security,點開主機實際掛載的 Web SG,再到 Inbound rules → Edit inbound rules:

Type Port Source
HTTP 80 0.0.0.0/0
HTTPS 443 0.0.0.0/0

80 沿用前篇,新增 443 後儲存。SSH 22 仍只允許自己的 IP,Container 的 8080 繼續留在本機,不用對外開

到 EC2 安裝 Certbot

接下來換到 SSH 登入 EC2 的 ubuntu 視窗。先備份前篇的網站設定,再檢查 Nginx 語法:

sudo cp /etc/nginx/sites-available/demo-api /etc/nginx/sites-available/demo-api.before-https
sudo nginx -t

看到 syntax is ok 與 test is successful 再往下做。備份放在 sites-available 就好,不用連到 sites-enabled

這次依 Certbot 官方流程,使用 snap 安裝。snap 是 Ubuntu 上的套件安裝工具,我們先確認主機有它:

snap --version

如果顯示找不到指令,先執行 sudo apt update,再執行 sudo apt install -y snapd。下面以還沒裝過 Certbot 的主機為例

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
certbot --version

第二行讓我們可以直接輸入 certbot。如果它提示檔案已存在,先用 ls -l /usr/local/bin/certbot 確認

接著申請憑證,記得換掉網域:

sudo certbot --nginx -d api.example.com --redirect

--nginx 讓 Certbot 幫忙設定 Nginx,-d 是憑證使用的網域,--redirect是把原本的 HTTP 轉到 HTTPS。依照畫面填寫自己的 Email

它幫 Nginx 改了什麼?

成功後,在 EC2 看一下同一份設定:

sudo cat /etc/nginx/sites-available/demo-api
sudo nginx -t

相關資訊如下,Certbot 會填入實際的憑證路徑~

設定 用途
listen 443 ssl 接收 HTTPS 請求
ssl_certificate 指向憑證檔案,通常以 fullchain.pem 結尾
ssl_certificate_key 指向私鑰檔案,通常以 privkey.pem 結尾
proxy_pass http://127.0.0.1:8080 沿用前篇,轉給本機的 Container
return 301 ... 請使用者改走 HTTPS

從自己的電腦測 HTTPS

換回自己電腦的終端機:

curl -I http://api.example.com/health
curl -i https://api.example.com/health

第一行應看到 301,以及 Location: https://自己的網域/health。Location 就是它請你改去的新網址,/health 也要保留下來

第二行應回 200 和 {"status":"ok"}。這裡不要加 -k,因為它會跳過我們正要確認的憑證驗證

再用瀏覽器開 https://自己的網域/health,就能直接看到 JSON 沒有憑證警告。也可以從網址列的網站資訊,查看憑證的網域名稱與到期日

如果卡住,可以先這樣查查看:

看到什麼 先查哪裡
HTTP 能連,HTTPS 卻逾時 Web SG 的 443、Nginx 是否監聽 443;有啟用主機防火牆的話,也要放行
憑證名稱不符 開啟的網址是否跟申請的網域相同,有沒有還在用 IP
HTTPS 回 502 Nginx 已接到請求,往下查 Container 和 127.0.0.1:8080

今天能用,之後會自己更新嗎?

先回到 EC2 的 ubuntu 視窗,查看目前憑證:

sudo certbot certificates

Domains 是這張憑證適用的網域,Expiry Date 是到期日。接著試跑一次續期:

sudo certbot renew --dry-run

--dry-run 會使用測試環境,檢查續期流程能不能走完,不會換掉目前正式使用的憑證。輸出應該就會顯示模擬續期成功

手動試跑成功後,還要確認主機之後會自己執行續期。snap 版會建立續期排程,我們用下面兩行看看它有沒有啟用:

systemctl is-active snap.certbot.renew.timer
systemctl list-timers --all snap.certbot.renew.timer

第一行會回 active。第二行看 NEXT,也就是下次預定執行的時間。這個 timer 會定期檢查,憑證需要續期時才更新,並透過 Nginx 外掛重新載入憑證

如果 timer 存在卻是 inactive,執行 sudo snap start --enable certbot.renew,再重跑上面兩行。如果顯示找不到這個 timer,先確認是否真的使用本文的 snap 版本,不要當成已經完成

續期分成三件事:目前 HTTPS 有效、試跑成功,以及自動排程已啟用

之後 DNS 改掉、或是 80 被封,或主機關機,續期還是有可能失敗。所以 80 要保留,同時提供 HTTP 轉址與這次使用的 HTTP-01 驗證

也留意一下,Let's Encrypt 已停止寄送到期提醒,不能等 Email 才想起來查看憑證勒,也附上官方(官方說明)

當你走到這裡,使用者就能經過 HTTPS → Nginx → Node.js Container,有沒有滿滿的成就感呢 XD

希望本篇你會喜歡,我們下篇見勒 :D


上一篇
網域與 Nginx:網址怎麼找到 EC2 裡的 Container?
系列文
從前後端踏上 AWS 雲端架構勇者之路 共 26 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言