本文由 AI 協助撰寫,內容經作者確認。
我在 VPS 上放了一個只給自己看的交易面板,討論「怎麼保護它」的時候,陸續出現了幾個名詞:Cloudflare Tunnel、2FA、OTP、One-Time PIN。這幾個名詞常常一起出現,但其實分別處理不同的問題:
| 名詞 | 一句話說明 | 解決的問題 |
|---|---|---|
| Cloudflare Tunnel | 由主機主動連出到 Cloudflare 的加密通道 | 主機不用對外開門,別人連找都找不到 |
| 2FA(雙因素驗證) | 登入時要通過兩種「不同類型」的證明 | 密碼外洩時,別人仍然進不來 |
| OTP(一次性密碼) | 只能用一次、很快就失效的密碼 | 常用來當 2FA 的第二道關卡 |
| One-Time PIN | Cloudflare Access 的登入方式:把 OTP 寄到你的信箱 | 不用自己架帳號系統,也能限制只有你能看 |
簡單說:Tunnel 管「路」,2FA 管「身分」,OTP 是 2FA 常用的工具,One-Time PIN 是 Cloudflare 提供的一種 OTP。
graph LR;
U["瀏覽器"] --> A["Cloudflare Access
(One-Time PIN 登入)"];
A --> T["Cloudflare Tunnel
(加密通道)"];
T --> S["VPS 上的網站"];
一、Cloudflare Tunnel:不用開門的連線#
一般架站的做法#
一般架網站,主機要對網路「開門」(開放 80、443 連接埠),讓訪客連進來。就算前面有 Cloudflare 代理,只要有人知道主機的真實 IP,就可以繞過 Cloudflare 直接敲門。
我目前的做法是在主機防火牆(ufw)只允許 Cloudflare 的 IP 範圍 連 80、443,其他來源一律擋掉。這樣也能達到「只能經過 Cloudflare」的效果,但要自己維護 Cloudflare 的 IP 清單。
Tunnel 的做法#
Cloudflare Tunnel 反過來:在主機上安裝一個小程式 cloudflared,由它主動往外連到 Cloudflare,建立一條加密通道。訪客連到 Cloudflare,Cloudflare 再透過這條通道把請求送到主機。
- 主機不需要開放任何對外的連接埠,防火牆可以把進來的連線全部擋掉
- 主機的真實 IP 不會出現在 DNS 上
- 連在家裡、沒有固定 IP 的電腦也能架站(因為是主機往外連)
- 免費方案即可使用
缺點是多了一個常駐程式,而且網站的可用性完全依賴 Cloudflare;Cloudflare 出問題時,網站也會一起連不上。
也能用來保護 SSH#
Tunnel 不只能轉送網頁,也能轉送 SSH。搭配後面提到的 Cloudflare Access,可以做到「SSH 連接埠完全不對外開放,必須先通過 Cloudflare 登入驗證才能連線」。另一個常見的選擇是 Tailscale:把自己的幾台裝置組成一個私人網路,SSH 只在這個私人網路裡開放。
二、2FA:兩種不同的證明#
2FA(Two-Factor Authentication,雙因素驗證) 是指登入時要同時通過兩種「不同類型」的驗證。身分證明大致分成三類:
| 類型 | 例子 |
|---|---|
| 你知道的東西 | 密碼、PIN 碼 |
| 你擁有的東西 | 手機、實體金鑰(YubiKey)、電子信箱 |
| 你本身的特徵 | 指紋、臉部辨識 |
重點是「不同類型」:兩組密碼不算 2FA,因為兩組都是「你知道的東西」,可能一起被偷。密碼加上手機上的驗證碼才算 2FA,因為壞人就算偷到密碼,手上也沒有你的手機。
常見的第二道關卡,由弱到強:
- 簡訊驗證碼:方便,但可能被 SIM 卡挾持(壞人假冒你去電信公司補卡)攔截
- 電子郵件驗證碼:安全程度取決於信箱本身有沒有保護好
- 驗證器 App(Google Authenticator、Microsoft Authenticator 等):驗證碼在手機上離線產生,不經過網路傳送
- 通行金鑰(Passkey)或實體金鑰:可以防止釣魚網站,目前最安全
三、OTP:只能用一次的密碼#
OTP(One-Time Password,一次性密碼) 是用一次就作廢、通常幾十秒到幾分鐘內就過期的密碼。就算被偷看到,也很快就沒用了。
OTP 主要有兩種產生方式:
- 由伺服器產生後寄給你:簡訊、電子郵件。伺服器隨機產生一組數字,記下來,再寄給你輸入
- 由手機自己算出來:驗證器 App 使用的 TOTP(Time-based OTP,以時間為基礎的一次性密碼)
TOTP 的原理#
第一次設定時,網站會顯示一個 QR Code,裡面是一把「共用金鑰」。手機掃描後,手機和伺服器就擁有同一把金鑰。
之後每 30 秒,雙方各自用「共用金鑰 + 目前時間」算出一組 6 位數。因為金鑰和時間都相同,算出來的數字也會相同,伺服器只要比對你輸入的數字就能確認。整個過程不需要網路傳送驗證碼,所以手機沒有訊號也能用。
注意:手機時間如果偏差太多,算出來的數字會對不上。另外,換手機前要先把驗證器移轉過去,或保存網站提供的備用代碼,否則可能會鎖住自己。
四、Cloudflare One-Time PIN:寄到信箱的登入碼#
Cloudflare Access 是 Cloudflare Zero Trust(零信任)服務的一部分,可以在網站前面加一道「門禁」:訪客連進來時,Cloudflare 先要求登入,確認是允許的人之後才放行。免費方案最多 50 位使用者,個人使用綽綽有餘。
Access 支援多種登入方式,例如 Google、GitHub 帳號登入;最簡單的一種就是 One-Time PIN:
- 訪客打開網站,Cloudflare 顯示登入頁,要求輸入電子郵件
- 如果這個信箱在允許名單內,Cloudflare 會寄出一組 6 位數 PIN 碼
- 輸入 PIN 碼後才能看到網站,登入狀態會保留一段時間(可設定)
One-Time PIN 本質上就是「寄到電子郵件的 OTP」。它的好處是完全不用在自己的主機上建立帳號系統,而且驗證發生在 Cloudflare,還沒通過的人連主機都碰不到。
One-Time PIN 算不算 2FA?#
單獨使用時不算。它只驗證了一件事:你能收到這個信箱的信(「你擁有」的東西)。所以它的安全程度等於你的信箱安全程度,信箱本身一定要開 2FA。
如果再加上主機自己的密碼(例如網站本身的帳號密碼),就變成「信箱 PIN(擁有)+ 網站密碼(知道)」兩道不同類型的關卡,才算是 2FA。
名詞對照#
| 縮寫 | 全名 | 中文 |
|---|---|---|
| 2FA / MFA | Two-Factor / Multi-Factor Authentication | 雙因素/多因素驗證 |
| OTP | One-Time Password | 一次性密碼 |
| TOTP | Time-based One-Time Password | 以時間為基礎的一次性密碼 |
| HOTP | HMAC-based One-Time Password | 以計數器為基礎的一次性密碼 |
| PIN | Personal Identification Number | 個人識別碼 |
| Zero Trust | — | 零信任:不因為「在內部網路」就預設信任,每次連線都要驗證 |

